From 096bf5515a34f1158a3bd1c0a259388b337f1f68 Mon Sep 17 00:00:00 2001 From: Nassim Kammah Date: Thu, 8 Feb 2024 08:42:35 +0100 Subject: [PATCH 001/104] Update docs-preview link (#176468) ## Summary Following the migration from Jenkins to Buildkite, docs previews are now available at _bk_. More context in https://github.com/elastic/docs/pull/2898 ### Checklist ### Risk Matrix ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .buildkite/scripts/lifecycle/post_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/scripts/lifecycle/post_build.sh b/.buildkite/scripts/lifecycle/post_build.sh index b5bdfd751a6e3..446ca4b28c559 100755 --- a/.buildkite/scripts/lifecycle/post_build.sh +++ b/.buildkite/scripts/lifecycle/post_build.sh @@ -12,7 +12,7 @@ fi ts-node "$(dirname "${0}")/ci_stats_complete.ts" if [[ "${GITHUB_PR_NUMBER:-}" ]]; then - DOCS_CHANGES_URL="https://kibana_$GITHUB_PR_NUMBER}.docs-preview.app.elstc.co/diff" + DOCS_CHANGES_URL="https://kibana_bk_$GITHUB_PR_NUMBER}.docs-preview.app.elstc.co/diff" DOCS_CHANGES=$(curl --connect-timeout 10 -m 10 -sf "$DOCS_CHANGES_URL" || echo '') if [[ "$DOCS_CHANGES" && "$DOCS_CHANGES" != "There aren't any differences!" ]]; then From e6866fcaf95af3046db55a65f37c4ae7a653cd3d Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Thu, 8 Feb 2024 19:30:50 +1030 Subject: [PATCH 002/104] [main] Sync bundled packages with Package Storage (#176446) Automated by https://buildkite.com/elastic/package-storage-infra-kibana-discover-release-branches/builds/332 --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index 79722187a1b0d..836e65d0e95aa 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -52,7 +52,7 @@ }, { "name": "synthetics", - "version": "1.1.1" + "version": "1.2.1" }, { "name": "security_detection_engine", From 8612ddcf8af9d270bac6c011a46a31910b1f0b8b Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 8 Feb 2024 10:09:19 +0100 Subject: [PATCH 003/104] [Cases] Optional custom fields default values (#176282) ## Summary Optional default values now support default values. - The Case Configuration API does not throw anymore if we try defining a `defaultValue` when `required: false` - The Case Configuration UI allows defining a default value even if `required` is not selected. - The Create Case page populates all custom fields with their default values. **Even if they are optional.** - The Case Detail page suggests the default value for **optional text custom fields** when they are empty. - For optional `toggle` custom fields the default value is not taken into account in the Case Detail page. --- .../components/configure_cases/index.test.tsx | 1 + .../components/custom_fields/flyout.test.tsx | 22 ++++++ .../custom_fields/form_fields.test.tsx | 1 + .../custom_fields/text/configure.test.tsx | 21 ++++++ .../custom_fields/text/configure.tsx | 27 +++---- .../custom_fields/toggle/configure.test.tsx | 7 +- .../custom_fields/toggle/configure.tsx | 28 +++---- .../cases/server/client/cases/utils.test.ts | 6 +- .../cases/server/client/cases/utils.ts | 6 +- .../server/client/configure/client.test.ts | 47 ------------ .../cases/server/client/configure/client.ts | 9 +-- .../client/configure/validators.test.ts | 74 +------------------ .../server/client/configure/validators.ts | 34 --------- .../tests/common/cases/patch_cases.ts | 68 +++++++++++++++++ .../tests/common/cases/post_case.ts | 47 ++++++++++++ .../tests/common/configure/patch_configure.ts | 9 ++- .../tests/common/configure/post_configure.ts | 17 +++-- 17 files changed, 216 insertions(+), 208 deletions(-) diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx index e2db3717c009d..ba3e7850533c9 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx @@ -750,6 +750,7 @@ describe('ConfigureCases', () => { type: customFieldsConfigurationMock[0].type, label: `${customFieldsConfigurationMock[0].label}!!`, required: !customFieldsConfigurationMock[0].required, + defaultValue: customFieldsConfigurationMock[0].defaultValue, }, { ...customFieldsConfigurationMock[1] }, { ...customFieldsConfigurationMock[2] }, diff --git a/x-pack/plugins/cases/public/components/custom_fields/flyout.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/flyout.test.tsx index 3a25009450df7..508f124a7746c 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/flyout.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/flyout.test.tsx @@ -108,6 +108,27 @@ describe('CustomFieldFlyout ', () => { }); }); + it('calls onSaveField with correct params when a custom field is NOT required and has a default value', async () => { + appMockRender.render(); + + userEvent.paste(await screen.findByTestId('custom-field-label-input'), 'Summary'); + userEvent.paste( + await screen.findByTestId('text-custom-field-default-value'), + 'Default value' + ); + userEvent.click(await screen.findByTestId('custom-field-flyout-save')); + + await waitFor(() => { + expect(props.onSaveField).toBeCalledWith({ + key: expect.anything(), + label: 'Summary', + required: false, + type: CustomFieldTypes.TEXT, + defaultValue: 'Default value', + }); + }); + }); + it('calls onSaveField with the correct params when a custom field is required', async () => { appMockRender.render(); @@ -202,6 +223,7 @@ describe('CustomFieldFlyout ', () => { label: 'Summary', required: false, type: CustomFieldTypes.TOGGLE, + defaultValue: false, }); }); }); diff --git a/x-pack/plugins/cases/public/components/custom_fields/form_fields.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/form_fields.test.tsx index 6c392a1ee7d7d..51f5f6dbddea6 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/form_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/form_fields.test.tsx @@ -65,6 +65,7 @@ describe('FormFields ', () => { { label: 'hello', type: CustomFieldTypes.TOGGLE, + defaultValue: false, }, true ); diff --git a/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx index 5d9d7166db270..455163f225a2b 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx @@ -44,6 +44,27 @@ describe('Configure ', () => { }); }); + it('updates field options with default value correctly when not required', async () => { + render( + + + + ); + + userEvent.paste(await screen.findByTestId('text-custom-field-default-value'), 'Default value'); + userEvent.click(await screen.findByTestId('form-test-component-submit-button')); + + await waitFor(() => { + // data, isValid + expect(onSubmit).toBeCalledWith( + { + defaultValue: 'Default value', + }, + true + ); + }); + }); + it('updates field options correctly when required', async () => { render( diff --git a/x-pack/plugins/cases/public/components/custom_fields/text/configure.tsx b/x-pack/plugins/cases/public/components/custom_fields/text/configure.tsx index 1253640d91b79..2ec61a4b80529 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/text/configure.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/text/configure.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { UseField, useFormData } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { UseField } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import { CheckBoxField, TextField } from '@kbn/es-ui-shared-plugin/static/forms/components'; import type { CaseCustomFieldText } from '../../../../common/types/domain'; import type { CustomFieldType } from '../types'; @@ -14,7 +14,6 @@ import { getTextFieldConfig } from './config'; import * as i18n from '../translations'; const ConfigureComponent: CustomFieldType['Configure'] = () => { - const [{ required }] = useFormData<{ required: boolean }>(); const config = getTextFieldConfig({ required: false, label: i18n.DEFAULT_VALUE.toLocaleLowerCase(), @@ -34,19 +33,17 @@ const ConfigureComponent: CustomFieldType['Configure'] = () }, }} /> - {required && ( - - )} + ); }; diff --git a/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.test.tsx index 8153ca64a789c..77f1bde4e7b55 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.test.tsx @@ -41,7 +41,12 @@ describe('Configure ', () => { await waitFor(() => { // data, isValid - expect(onSubmit).toBeCalledWith({}, true); + expect(onSubmit).toBeCalledWith( + { + defaultValue: false, + }, + true + ); }); }); diff --git a/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.tsx b/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.tsx index 83645ae185f1d..7b5980c2276ec 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/toggle/configure.tsx @@ -6,15 +6,13 @@ */ import React from 'react'; -import { UseField, useFormData } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { UseField } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import { CheckBoxField, ToggleField } from '@kbn/es-ui-shared-plugin/static/forms/components'; import type { CaseCustomFieldToggle } from '../../../../common/types/domain'; import type { CustomFieldType } from '../types'; import * as i18n from '../translations'; const ConfigureComponent: CustomFieldType['Configure'] = () => { - const [{ required }] = useFormData<{ required: boolean }>(); - return ( <> ['Configure'] = }, }} /> - {required && ( - - )} + ); }; diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index a1c070eb08d1f..c6c9f1063df60 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -1418,7 +1418,7 @@ describe('utils', () => { ).toEqual(customFields); }); - it('does not use default value for optional custom fields', () => { + it('uses the default value for optional custom fields', () => { expect( fillMissingCustomFields({ customFields: [], @@ -1430,8 +1430,8 @@ describe('utils', () => { ], }) ).toEqual([ - { ...customFields[0], value: null }, - { ...customFields[1], value: null }, + { ...customFields[0], value: 'default value' }, + { ...customFields[1], value: true }, ]); }); diff --git a/x-pack/plugins/cases/server/client/cases/utils.ts b/x-pack/plugins/cases/server/client/cases/utils.ts index b304159b928aa..a7f596a0f9c9e 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.ts @@ -473,11 +473,7 @@ export const fillMissingCustomFields = ({ // only populate with the default value required custom fields missing from the request for (const confCustomField of customFieldsConfiguration) { if (!customFieldsKeys.has(confCustomField.key)) { - if ( - confCustomField.required && - confCustomField?.defaultValue !== null && - confCustomField?.defaultValue !== undefined - ) { + if (confCustomField?.defaultValue !== null && confCustomField?.defaultValue !== undefined) { missingCustomFields.push({ key: confCustomField.key, type: confCustomField.type, diff --git a/x-pack/plugins/cases/server/client/configure/client.test.ts b/x-pack/plugins/cases/server/client/configure/client.test.ts index 2e3c2a6899f91..b5958c44de080 100644 --- a/x-pack/plugins/cases/server/client/configure/client.test.ts +++ b/x-pack/plugins/cases/server/client/configure/client.test.ts @@ -346,30 +346,6 @@ describe('client', () => { 'Failed to get patch configure in route: Error: Invalid custom field types in request for the following labels: "text label"' ); }); - - it('throws when an optional custom field has a default value', async () => { - await expect( - update( - 'test-id', - { - version: 'test-version', - customFields: [ - { - key: 'extra_default', - label: 'text label', - type: CustomFieldTypes.TEXT, - required: false, - defaultValue: 'foobar', - }, - ], - }, - clientArgs, - casesClientInternal - ) - ).rejects.toThrow( - 'Failed to get patch configure in route: Error: The following optional custom fields try to define a default value: "text label"' - ); - }); }); describe('create', () => { @@ -431,28 +407,5 @@ describe('client', () => { 'Failed to create case configuration: Error: Invalid duplicated custom field keys in request: duplicated_key' ); }); - - it('throws when an optional custom field has a default value', async () => { - await expect( - create( - { - ...baseRequest, - customFields: [ - { - key: 'extra_default', - label: 'text label', - type: CustomFieldTypes.TEXT, - required: false, - defaultValue: 'foobar', - }, - ], - }, - clientArgs, - casesClientInternal - ) - ).rejects.toThrow( - 'Failed to create case configuration: Error: The following optional custom fields try to define a default value: "text label"' - ); - }); }); }); diff --git a/x-pack/plugins/cases/server/client/configure/client.ts b/x-pack/plugins/cases/server/client/configure/client.ts index 41a9dd9326c24..1261f1061a371 100644 --- a/x-pack/plugins/cases/server/client/configure/client.ts +++ b/x-pack/plugins/cases/server/client/configure/client.ts @@ -49,10 +49,7 @@ import { updateMappings } from './update_mappings'; import { decodeOrThrow } from '../../../common/api/runtime_types'; import { ConfigurationRt, ConfigurationsRt } from '../../../common/types/domain'; import { validateDuplicatedCustomFieldKeysInRequest } from '../validators'; -import { - validateCustomFieldTypesInRequest, - validateOptionalCustomFieldsInRequest, -} from './validators'; +import { validateCustomFieldTypesInRequest } from './validators'; /** * Defines the internal helper functions. @@ -256,7 +253,6 @@ export async function update( const request = decodeWithExcessOrThrow(ConfigurationPatchRequestRt)(req); validateDuplicatedCustomFieldKeysInRequest({ requestCustomFields: request.customFields }); - validateOptionalCustomFieldsInRequest({ requestCustomFields: request.customFields }); const { version, ...queryWithoutVersion } = request; @@ -372,9 +368,6 @@ export async function create( validateDuplicatedCustomFieldKeysInRequest({ requestCustomFields: validatedConfigurationRequest.customFields, }); - validateOptionalCustomFieldsInRequest({ - requestCustomFields: validatedConfigurationRequest.customFields, - }); let error = null; diff --git a/x-pack/plugins/cases/server/client/configure/validators.test.ts b/x-pack/plugins/cases/server/client/configure/validators.test.ts index d1d41bfe1bb62..0f8e20505fb39 100644 --- a/x-pack/plugins/cases/server/client/configure/validators.test.ts +++ b/x-pack/plugins/cases/server/client/configure/validators.test.ts @@ -6,10 +6,7 @@ */ import { CustomFieldTypes } from '../../../common/types/domain'; -import { - validateCustomFieldTypesInRequest, - validateOptionalCustomFieldsInRequest, -} from './validators'; +import { validateCustomFieldTypesInRequest } from './validators'; describe('validators', () => { describe('validateCustomFieldTypesInRequest', () => { @@ -72,73 +69,4 @@ describe('validators', () => { ).not.toThrow(); }); }); - - describe('validateOptionalCustomFieldsInRequest', () => { - it('does not throw an error for properly constructed optional custom fields', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [ - { key: '1', required: false, label: 'label 1' }, - { key: '2', required: false, label: 'label 2' }, - ], - }) - ).not.toThrow(); - }); - - it('does not throw an error for required custom fields with default values', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [ - { key: '1', required: true, defaultValue: false, label: 'label 1' }, - { key: '2', required: true, defaultValue: 'foobar', label: 'label 2' }, - ], - }) - ).not.toThrow(); - }); - - it('throws an error even if the default value has the correct type', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [ - { key: '1', required: false, defaultValue: false, label: 'label 1' }, - { key: '2', required: false, defaultValue: 'foobar', label: 'label 2' }, - ], - }) - ).toThrowErrorMatchingInlineSnapshot( - `"The following optional custom fields try to define a default value: \\"label 1\\", \\"label 2\\""` - ); - }); - - it('throws an error for other falsy defaultValues (null)', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [ - { key: '1', required: false, defaultValue: null, label: 'label 1' }, - ], - }) - ).toThrowErrorMatchingInlineSnapshot( - `"The following optional custom fields try to define a default value: \\"label 1\\""` - ); - }); - - it('throws an error for other falsy defaultValues (0)', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [{ key: '1', required: false, defaultValue: 0, label: 'label 1' }], - }) - ).toThrowErrorMatchingInlineSnapshot( - `"The following optional custom fields try to define a default value: \\"label 1\\""` - ); - }); - - it('throws an error for other falsy defaultValues (empty string)', () => { - expect(() => - validateOptionalCustomFieldsInRequest({ - requestCustomFields: [{ key: '1', required: false, defaultValue: '', label: 'label 1' }], - }) - ).toThrowErrorMatchingInlineSnapshot( - `"The following optional custom fields try to define a default value: \\"label 1\\""` - ); - }); - }); }); diff --git a/x-pack/plugins/cases/server/client/configure/validators.ts b/x-pack/plugins/cases/server/client/configure/validators.ts index ca3a175e40579..c5929065c631b 100644 --- a/x-pack/plugins/cases/server/client/configure/validators.ts +++ b/x-pack/plugins/cases/server/client/configure/validators.ts @@ -38,37 +38,3 @@ export const validateCustomFieldTypesInRequest = ({ ); } }; - -/** - * Throws an error if any optional custom field defines a default value. - */ -export const validateOptionalCustomFieldsInRequest = ({ - requestCustomFields, -}: { - requestCustomFields?: Array<{ - key: string; - required: boolean; - defaultValue?: unknown; - label: string; - }>; -}) => { - if (!Array.isArray(requestCustomFields)) { - return; - } - - const invalidFields: string[] = []; - - requestCustomFields.forEach((requestField) => { - if (!requestField.required && requestField.defaultValue !== undefined) { - invalidFields.push(`"${requestField.label}"`); - } - }); - - if (invalidFields.length > 0) { - throw Boom.badRequest( - `The following optional custom fields try to define a default value: ${invalidFields.join( - ', ' - )}` - ); - } -}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts index cc49ddf44bdcc..3a965b73004ef 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts @@ -1149,6 +1149,74 @@ export default ({ getService }: FtrProviderContext): void => { ]); }); + it('patches a case with missing optional custom fields to their default values', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'text_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + defaultValue: 'default value', + required: false, + }, + { + key: 'toggle_custom_field', + label: 'toggle', + type: CustomFieldTypes.TOGGLE, + defaultValue: false, + required: false, + }, + ], + }, + }) + ); + + const originalValues = [ + { + key: 'text_custom_field', + type: CustomFieldTypes.TEXT, + value: 'hello', + }, + { + key: 'toggle_custom_field', + type: CustomFieldTypes.TOGGLE, + value: true, + }, + ] as CaseCustomFields; + + const postedCase = await createCase(supertest, { + ...postCaseReq, + customFields: originalValues, + }); + + const patchedCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + customFields: [ + { + key: 'toggle_custom_field', + type: CustomFieldTypes.TOGGLE, + value: false, + }, + ], + }, + ], + }, + }); + + expect(patchedCases[0].customFields).to.eql([ + { ...originalValues[1], value: false }, + { ...originalValues[0], value: 'default value' }, + ]); + }); + it('400s trying to patch a case with missing required custom fields if they dont have default values', async () => { await createConfiguration( supertest, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/post_case.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/post_case.ts index 5049c04b060a8..411932212f242 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/post_case.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/post_case.ts @@ -318,6 +318,53 @@ export default ({ getService }: FtrProviderContext): void => { }, ]); }); + + it('creates a case with missing optional custom fields and default values', async () => { + const customFieldsConfiguration = [ + { + key: 'text_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + defaultValue: 'default value', + }, + { + key: 'toggle_custom_field', + label: 'toggle', + type: CustomFieldTypes.TOGGLE, + defaultValue: false, + required: false, + }, + ]; + + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: customFieldsConfiguration, + }, + }) + ); + const createdCase = await createCase( + supertest, + getPostCaseRequest({ + customFields: [], + }) + ); + + expect(createdCase.customFields).to.eql([ + { + key: customFieldsConfiguration[0].key, + type: customFieldsConfiguration[0].type, + value: 'default value', + }, + { + key: customFieldsConfiguration[1].key, + type: customFieldsConfiguration[1].type, + value: false, + }, + ]); + }); }); describe('unhappy path', () => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/patch_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/patch_configure.ts index d5b6e931ca671..c8e0f092edf3a 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/patch_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/patch_configure.ts @@ -64,7 +64,7 @@ export default ({ getService }: FtrProviderContext): void => { required: true, }, { - key: 'toggle_field', + key: 'toggle_field_1', label: '#2', type: CustomFieldTypes.TOGGLE, required: false, @@ -76,6 +76,13 @@ export default ({ getService }: FtrProviderContext): void => { required: true, defaultValue: 'foobar', }, + { + key: 'toggle_field_2', + label: '#4', + type: CustomFieldTypes.TOGGLE, + required: false, + defaultValue: true, + }, ] as ConfigurationPatchRequest['customFields']; const configuration = await createConfiguration(supertest); const newConfiguration = await updateConfiguration(supertest, configuration.id, { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts index 15efb00444993..a7461d5f1fc18 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/post_configure.ts @@ -63,20 +63,27 @@ export default ({ getService }: FtrProviderContext): void => { it('should create a configuration with customFields', async () => { const customFields = { customFields: [ - { key: 'hello', label: 'text', type: CustomFieldTypes.TEXT, required: false }, + { key: 'text_1', label: 'text 1', type: CustomFieldTypes.TEXT, required: false }, { - key: 'goodbye', - label: 'toggle', + key: 'toggle_1', + label: 'toggle 1', type: CustomFieldTypes.TOGGLE, required: true, defaultValue: false, }, { - key: 'hello_again', - label: 'text', + key: 'text_2', + label: 'text 2', type: CustomFieldTypes.TEXT, required: true, }, + { + key: 'toggle_2', + label: 'toggle 2', + type: CustomFieldTypes.TOGGLE, + required: false, + defaultValue: true, + }, ], }; From 0bca3c0ecfb0da135d1799ed6f956436b9ea27f6 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 8 Feb 2024 09:22:35 +0000 Subject: [PATCH 004/104] [ML] Adds grok highlighting to the file data visualizer (#175913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds grokpattern highlighting to the file data visualizer for semi-structured text files. The first 5 lines of the file are displayed with inline highlighting. Hovering the mouse over displays a tooltip with the field name and type. ![image](https://github.com/elastic/kibana/assets/22172091/7b50aeca-0255-4413-93ef-e44976e798f4) If for whatever reason the highlighting fails, we switch back to the raw text. @szabosteve and @peteharverson I'm not 100% happy with the labels on the tabs, `Highlighted text` and `Raw text`. So suggestions are welcome. Relates to https://github.com/elastic/elasticsearch/pull/104394 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: István Zoltán Szabó --- .../common/types/test_grok_pattern.ts | 13 ++ .../components/file_contents/field_badge.tsx | 62 ++++++++ .../file_contents/file_contents.tsx | 150 +++++++++++++++--- .../file_contents/grok_highlighter.ts | 103 ++++++++++++ .../file_contents/use_text_parser.tsx | 67 ++++++++ .../components/results_view/results_view.tsx | 13 ++ .../plugins/data_visualizer/server/index.ts | 2 +- .../plugins/data_visualizer/server/plugin.ts | 18 ++- .../plugins/data_visualizer/server/routes.ts | 69 ++++++++ x-pack/plugins/data_visualizer/tsconfig.json | 35 ++-- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../data_visualizer/file_data_visualizer.ts | 13 +- .../services/ml/data_visualizer_file_based.ts | 26 +++ 15 files changed, 521 insertions(+), 53 deletions(-) create mode 100644 x-pack/plugins/data_visualizer/common/types/test_grok_pattern.ts create mode 100644 x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/field_badge.tsx create mode 100644 x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/grok_highlighter.ts create mode 100644 x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/use_text_parser.tsx create mode 100644 x-pack/plugins/data_visualizer/server/routes.ts diff --git a/x-pack/plugins/data_visualizer/common/types/test_grok_pattern.ts b/x-pack/plugins/data_visualizer/common/types/test_grok_pattern.ts new file mode 100644 index 0000000000000..65ae4a89988de --- /dev/null +++ b/x-pack/plugins/data_visualizer/common/types/test_grok_pattern.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 interface TestGrokPatternResponse { + matches: Array<{ + matched: boolean; + fields: Record>; + }>; +} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/field_badge.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/field_badge.tsx new file mode 100644 index 0000000000000..981b2195c3065 --- /dev/null +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/field_badge.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { FieldIcon } from '@kbn/react-field'; +import { i18n } from '@kbn/i18n'; +import { getSupportedFieldType } from '../../../common/components/fields_stats_grid/get_field_names'; +import { useCurrentEuiTheme } from '../../../common/hooks/use_current_eui_theme'; + +interface Props { + type: string | undefined; + value: string; + name: string; +} + +export const FieldBadge: FC = ({ type, value, name }) => { + const { euiColorLightestShade, euiColorLightShade } = useCurrentEuiTheme(); + const supportedType = getSupportedFieldType(type ?? 'unknown'); + const tooltip = type + ? i18n.translate('xpack.dataVisualizer.file.fileContents.fieldBadge.tooltip', { + defaultMessage: 'Type: {type}', + values: { type: supportedType }, + }) + : undefined; + return ( + + + + + + + {value} + + + + ); +}; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/file_contents.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/file_contents.tsx index 21c50a7f293b6..789d73888bf35 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/file_contents.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/file_contents.tsx @@ -5,52 +5,150 @@ * 2.0. */ +import React, { FC, useEffect, useState, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import React, { FC } from 'react'; -import { EuiTitle, EuiSpacer } from '@elastic/eui'; +import { + EuiTitle, + EuiSpacer, + EuiHorizontalRule, + EuiFlexGroup, + EuiFlexItem, + EuiSwitch, +} from '@elastic/eui'; -import { JsonEditor, EDITOR_MODE } from '../json_editor'; +import type { FindFileStructureResponse } from '@kbn/file-upload-plugin/common'; +import useMountedState from 'react-use/lib/useMountedState'; +import { i18n } from '@kbn/i18n'; +import { EDITOR_MODE, JsonEditor } from '../json_editor'; +import { useGrokHighlighter } from './use_text_parser'; +import { LINE_LIMIT } from './grok_highlighter'; interface Props { data: string; format: string; numberOfLines: number; + semiStructureTextData: SemiStructureTextData | null; } -export const FileContents: FC = ({ data, format, numberOfLines }) => { +interface SemiStructureTextData { + grokPattern?: string; + multilineStartPattern?: string; + excludeLinesPattern?: string; + sampleStart: string; + mappings: FindFileStructureResponse['mappings']; + ecsCompatibility?: string; +} + +function semiStructureTextDataGuard( + semiStructureTextData: SemiStructureTextData | null +): semiStructureTextData is SemiStructureTextData { + return ( + semiStructureTextData !== null && + semiStructureTextData.grokPattern !== undefined && + semiStructureTextData.multilineStartPattern !== undefined + ); +} + +export const FileContents: FC = ({ data, format, numberOfLines, semiStructureTextData }) => { let mode = EDITOR_MODE.TEXT; if (format === EDITOR_MODE.JSON) { mode = EDITOR_MODE.JSON; } + const isMounted = useMountedState(); + const grokHighlighter = useGrokHighlighter(); + + const [isSemiStructureTextData, setIsSemiStructureTextData] = useState( + semiStructureTextDataGuard(semiStructureTextData) + ); + const formattedData = useMemo( + () => limitByNumberOfLines(data, numberOfLines), + [data, numberOfLines] + ); + + const [highlightedLines, setHighlightedLines] = useState(null); + const [showHighlights, setShowHighlights] = useState(isSemiStructureTextData); + + useEffect(() => { + if (isSemiStructureTextData === false) { + return; + } + const { grokPattern, multilineStartPattern, excludeLinesPattern, mappings, ecsCompatibility } = + semiStructureTextData!; - const formattedData = limitByNumberOfLines(data, numberOfLines); + grokHighlighter( + data, + grokPattern!, + mappings, + ecsCompatibility, + multilineStartPattern!, + excludeLinesPattern + ) + .then((docs) => { + if (isMounted()) { + setHighlightedLines(docs); + } + }) + .catch((e) => { + if (isMounted()) { + setHighlightedLines(null); + setIsSemiStructureTextData(false); + } + }); + }, [data, semiStructureTextData, grokHighlighter, isSemiStructureTextData, isMounted]); return ( - - -

- -

-
- -
- -
+ <> + + + +

+ +

+
+
+ {isSemiStructureTextData ? ( + + setShowHighlights(!showHighlights)} + /> + + ) : null} +
+ + + + - -
+ {highlightedLines === null || showHighlights === false ? ( + + ) : ( + <> + {highlightedLines.map((line, i) => ( + <> + {line} + {i === highlightedLines.length - 1 ? null : } + + ))} + + )} + ); }; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/grok_highlighter.ts b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/grok_highlighter.ts new file mode 100644 index 0000000000000..7be566a5a91b0 --- /dev/null +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/grok_highlighter.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MessageImporter } from '@kbn/file-upload-plugin/public'; +import type { HttpSetup } from '@kbn/core/public'; +import type { ImportFactoryOptions } from '@kbn/file-upload-plugin/public/importer'; +import type { FindFileStructureResponse } from '@kbn/file-upload-plugin/common'; +import type { TestGrokPatternResponse } from '../../../../../common/types/test_grok_pattern'; + +export const LINE_LIMIT = 5; + +type HighlightedLine = Array<{ + word: string; + field?: { + type: string; + name: string; + }; +}>; + +export class GrokHighlighter extends MessageImporter { + constructor(options: ImportFactoryOptions, private http: HttpSetup) { + super(options); + } + + public async createLines( + text: string, + grokPattern: string, + mappings: FindFileStructureResponse['mappings'], + ecsCompatibility: string | undefined + ): Promise { + const docs = this._createDocs(text, false, LINE_LIMIT); + const lines = docs.docs.map((doc) => doc.message); + const matches = await this.testGrokPattern(lines, grokPattern, ecsCompatibility); + + return lines.map((line, index) => { + const { matched, fields } = matches[index]; + if (matched === false) { + return [ + { + word: line, + }, + ]; + } + const sortedFields = Object.entries(fields) + .map(([fieldName, [{ match, offset, length }]]) => { + let type = mappings.properties[fieldName]?.type; + if (type === undefined && fieldName === 'timestamp') { + // it's possible that the timestamp field is not mapped as `timestamp` + // but instead as `@timestamp` + type = mappings.properties['@timestamp']?.type; + } + return { + name: fieldName, + match, + offset, + length, + type, + }; + }) + .sort((a, b) => a.offset - b.offset); + + let offset = 0; + const highlightedLine: HighlightedLine = []; + for (const field of sortedFields) { + highlightedLine.push({ word: line.substring(offset, field.offset) }); + highlightedLine.push({ + word: field.match, + field: { + type: field.type, + name: field.name, + }, + }); + offset = field.offset + field.length; + } + highlightedLine.push({ word: line.substring(offset) }); + return highlightedLine; + }); + } + + private async testGrokPattern( + lines: string[], + grokPattern: string, + ecsCompatibility: string | undefined + ) { + const { matches } = await this.http.fetch( + '/internal/data_visualizer/test_grok_pattern', + { + method: 'POST', + version: '1', + body: JSON.stringify({ + grokPattern, + text: lines, + ecsCompatibility, + }), + } + ); + return matches; + } +} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/use_text_parser.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/use_text_parser.tsx new file mode 100644 index 0000000000000..183f3ca727d3a --- /dev/null +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_contents/use_text_parser.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { EuiText } from '@elastic/eui'; +import type { FindFileStructureResponse } from '@kbn/file-upload-plugin/common'; +import { FieldBadge } from './field_badge'; +import { useDataVisualizerKibana } from '../../../kibana_context'; +import { useCurrentEuiTheme } from '../../../common/hooks/use_current_eui_theme'; +import { GrokHighlighter } from './grok_highlighter'; + +export function useGrokHighlighter() { + const { + services: { http }, + } = useDataVisualizerKibana(); + const { euiSizeL } = useCurrentEuiTheme(); + + const createLines = useMemo( + () => + async ( + text: string, + grokPattern: string, + mappings: FindFileStructureResponse['mappings'], + ecsCompatibility: string | undefined, + multilineStartPattern: string, + excludeLinesPattern: string | undefined + ) => { + const grokHighlighter = new GrokHighlighter( + { multilineStartPattern, excludeLinesPattern }, + http + ); + const lines = await grokHighlighter.createLines( + text, + grokPattern, + mappings, + ecsCompatibility + ); + + return lines.map((line) => { + const formattedWords: JSX.Element[] = []; + for (const { word, field } of line) { + if (field) { + formattedWords.push(); + } else { + formattedWords.push({word}); + } + } + return ( + + {formattedWords} + + ); + }); + }, + [euiSizeL, http] + ); + + return createLines; +} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/results_view/results_view.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/results_view/results_view.tsx index 26a727a7a922e..855df5855536a 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/results_view/results_view.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/results_view/results_view.tsx @@ -20,6 +20,7 @@ import { } from '@elastic/eui'; import { FindFileStructureResponse } from '@kbn/file-upload-plugin/common'; +import { FILE_FORMATS } from '../../../../../common/constants'; import { FileContents } from '../file_contents'; import { AnalysisSummary } from '../analysis_summary'; import { FieldsStatsGrid } from '../../../common/components/fields_stats_grid'; @@ -48,6 +49,17 @@ export const ResultsView: FC = ({ onCancel, disableImport, }) => { + const semiStructureTextData = + results.format === FILE_FORMATS.SEMI_STRUCTURED_TEXT + ? { + grokPattern: results.grok_pattern, + multilineStartPattern: results.multiline_start_pattern, + sampleStart: results.sample_start, + excludeLinesPattern: results.exclude_lines_pattern, + mappings: results.mappings, + ecsCompatibility: results.ecs_compatibility, + } + : null; return ( @@ -77,6 +89,7 @@ export const ResultsView: FC = ({ data={data} format={results.format} numberOfLines={results.num_lines_analyzed} + semiStructureTextData={semiStructureTextData} /> diff --git a/x-pack/plugins/data_visualizer/server/index.ts b/x-pack/plugins/data_visualizer/server/index.ts index 1f15b498f8777..17db3c1abb603 100644 --- a/x-pack/plugins/data_visualizer/server/index.ts +++ b/x-pack/plugins/data_visualizer/server/index.ts @@ -9,5 +9,5 @@ import { PluginInitializerContext } from '@kbn/core/server'; export const plugin = async (initializerContext: PluginInitializerContext) => { const { DataVisualizerPlugin } = await import('./plugin'); - return new DataVisualizerPlugin(); + return new DataVisualizerPlugin(initializerContext); }; diff --git a/x-pack/plugins/data_visualizer/server/plugin.ts b/x-pack/plugins/data_visualizer/server/plugin.ts index 5f16df8b5ffb7..0e70f756f9b21 100644 --- a/x-pack/plugins/data_visualizer/server/plugin.ts +++ b/x-pack/plugins/data_visualizer/server/plugin.ts @@ -5,18 +5,30 @@ * 2.0. */ -import { CoreSetup, CoreStart, Plugin } from '@kbn/core/server'; -import { StartDeps, SetupDeps } from './types'; +import type { + CoreSetup, + CoreStart, + Plugin, + Logger, + PluginInitializerContext, +} from '@kbn/core/server'; +import type { StartDeps, SetupDeps } from './types'; import { registerWithCustomIntegrations } from './register_custom_integration'; +import { routes } from './routes'; export class DataVisualizerPlugin implements Plugin { - constructor() {} + private readonly _logger: Logger; + + constructor(initializerContext: PluginInitializerContext) { + this._logger = initializerContext.logger.get(); + } setup(coreSetup: CoreSetup, plugins: SetupDeps) { // home-plugin required if (plugins.home && plugins.customIntegrations) { registerWithCustomIntegrations(plugins.customIntegrations); } + routes(coreSetup, this._logger); } start(core: CoreStart) {} diff --git a/x-pack/plugins/data_visualizer/server/routes.ts b/x-pack/plugins/data_visualizer/server/routes.ts new file mode 100644 index 0000000000000..c4e286f9671d1 --- /dev/null +++ b/x-pack/plugins/data_visualizer/server/routes.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreSetup, Logger } from '@kbn/core/server'; +import { schema } from '@kbn/config-schema'; +import type { StartDeps } from './types'; +import { wrapError } from './utils/error_wrapper'; +import type { TestGrokPatternResponse } from '../common/types/test_grok_pattern'; + +/** + * @apiGroup DataVisualizer + * + * @api {post} /internal/data_visualizer/test_grok_pattern Tests a grok pattern against a sample of text + * @apiName testGrokPattern + * @apiDescription Tests a grok pattern against a sample of text and return the positions of the fields + */ +export function routes(coreSetup: CoreSetup, logger: Logger) { + const router = coreSetup.http.createRouter(); + + router.versioned + .post({ + path: '/internal/data_visualizer/test_grok_pattern', + access: 'internal', + options: { + tags: ['access:fileUpload:analyzeFile'], + }, + }) + .addVersion( + { + version: '1', + validate: { + request: { + body: schema.object({ + grokPattern: schema.string(), + text: schema.arrayOf(schema.string()), + ecsCompatibility: schema.maybe(schema.string()), + }), + }, + }, + }, + async (context, request, response) => { + try { + const esClient = (await context.core).elasticsearch.client; + const body = await esClient.asInternalUser.transport.request({ + method: 'GET', + path: `/_text_structure/test_grok_pattern`, + body: { + grok_pattern: request.body.grokPattern, + text: request.body.text, + }, + ...(request.body.ecsCompatibility + ? { + querystring: { ecs_compatibility: request.body.ecsCompatibility }, + } + : {}), + }); + + return response.ok({ body }); + } catch (e) { + logger.warn(`Unable to test grok pattern ${e.message}`); + return response.customError(wrapError(e)); + } + } + ); +} diff --git a/x-pack/plugins/data_visualizer/tsconfig.json b/x-pack/plugins/data_visualizer/tsconfig.json index af962ac08b6e8..aad960d856da3 100644 --- a/x-pack/plugins/data_visualizer/tsconfig.json +++ b/x-pack/plugins/data_visualizer/tsconfig.json @@ -17,20 +17,28 @@ "@kbn/aiops-utils", "@kbn/charts-plugin", "@kbn/cloud-plugin", + "@kbn/code-editor", + "@kbn/config-schema", "@kbn/core-execution-context-common", + "@kbn/core-notifications-browser", "@kbn/core", "@kbn/custom-integrations-plugin", "@kbn/data-plugin", + "@kbn/data-service", "@kbn/data-view-field-editor-plugin", "@kbn/data-views-plugin", "@kbn/datemath", "@kbn/discover-plugin", + "@kbn/ebt-tools", "@kbn/embeddable-plugin", "@kbn/embeddable-plugin", "@kbn/es-query", + "@kbn/es-types", "@kbn/es-ui-shared-plugin", + "@kbn/esql-utils", "@kbn/field-formats-plugin", "@kbn/field-types", + "@kbn/field-utils", "@kbn/file-upload-plugin", "@kbn/home-plugin", "@kbn/i18n-react", @@ -41,41 +49,34 @@ "@kbn/maps-plugin", "@kbn/ml-agg-utils", "@kbn/ml-cancellable-search", + "@kbn/ml-chi2test", + "@kbn/ml-data-grid", "@kbn/ml-date-picker", + "@kbn/ml-error-utils", + "@kbn/ml-in-memory-table", "@kbn/ml-is-defined", "@kbn/ml-is-populated-object", + "@kbn/ml-kibana-theme", "@kbn/ml-local-storage", "@kbn/ml-nested-property", "@kbn/ml-number-utils", "@kbn/ml-query-utils", + "@kbn/ml-random-sampler-utils", + "@kbn/ml-string-hash", "@kbn/ml-url-state", - "@kbn/ml-data-grid", - "@kbn/ml-error-utils", - "@kbn/ml-kibana-theme", - "@kbn/ml-in-memory-table", "@kbn/react-field", "@kbn/rison", "@kbn/saved-search-plugin", "@kbn/security-plugin", "@kbn/share-plugin", "@kbn/test-jest-helpers", + "@kbn/text-based-languages", "@kbn/ui-actions-plugin", + "@kbn/ui-theme", "@kbn/unified-search-plugin", "@kbn/usage-collection-plugin", "@kbn/utility-types", - "@kbn/ml-string-hash", - "@kbn/ml-random-sampler-utils", - "@kbn/data-service", - "@kbn/core-notifications-browser", - "@kbn/ebt-tools", - "@kbn/ml-chi2test", - "@kbn/field-utils", - "@kbn/visualization-utils", - "@kbn/text-based-languages", - "@kbn/code-editor", - "@kbn/es-types", - "@kbn/ui-theme", - "@kbn/esql-utils" + "@kbn/visualization-utils" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index c812c47f9aa48..b8d9c9eb44c43 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -12174,7 +12174,6 @@ "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterSValidationErrorMessage": "{length, plural, one { {lg} } many { Le groupe de lettres {lg} } other { Le groupe de lettres {lg} }} en {format} n'est pas compatible, car il n'est pas précédé de ss ni d'un séparateur de {sep}", "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterValidationErrorMessage": "{length, plural, one { {lg} } many { Le groupe de lettres {lg} } other { Le groupe de lettres {lg} }} en {format} n'est pas compatible", "xpack.dataVisualizer.file.editFlyout.overrides.timestampQuestionMarkValidationErrorMessage": "Le format d'horodatage {timestampFormat} n'est pas compatible, car il contient un point d'interrogation ({fieldPlaceholder})", - "xpack.dataVisualizer.file.fileContents.firstLinesDescription": "{numberOfLines, plural, one {# ligne} many {# lignes} other {# lignes}} premier(s)", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeByDiffFormatErrorMessage": "La taille du fichier que vous avez sélectionné pour le chargement dépasse la taille maximale autorisée de {maxFileSizeFormatted} de {diffFormatted}", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeErrorMessage": "La taille du fichier que vous avez sélectionné pour le chargement est de {fileSizeFormatted}, ce qui dépasse la taille maximale autorisée de {maxFileSizeFormatted}", "xpack.dataVisualizer.file.importSummary.documentsCouldNotBeImportedDescription": "Impossible d'importer {importFailuresLength} document(s) sur {docCount}. Cela peut être dû au manque de correspondance entre les lignes et le modèle Grok.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 10bbca87a9cad..cf3ea4c3fe0a9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12187,7 +12187,6 @@ "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterSValidationErrorMessage": "{format}の文字{length, plural, other { グループ{lg} }}は、前にssと{sep}の区切り文字が付いていないため、サポートされません", "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterValidationErrorMessage": "{format}の文字{length, plural, other { グループ{lg} }}はサポートされていません", "xpack.dataVisualizer.file.editFlyout.overrides.timestampQuestionMarkValidationErrorMessage": "タイムスタンプフォーマット {timestampFormat} は、疑問符({fieldPlaceholder})が含まれているためサポートされていません", - "xpack.dataVisualizer.file.fileContents.firstLinesDescription": "最初の{numberOfLines, plural, other {#行}}件", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeByDiffFormatErrorMessage": "アップロードするよう選択されたファイルのサイズが {diffFormatted} に許可された最大サイズの {maxFileSizeFormatted} を超えています", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeErrorMessage": "アップロードするよう選択されたファイルのサイズは {fileSizeFormatted} で、許可された最大サイズの {maxFileSizeFormatted} を超えています", "xpack.dataVisualizer.file.importSummary.documentsCouldNotBeImportedDescription": "{docCount}件中{importFailuresLength}件のドキュメントをインポートできません。行が Grok パターンと一致していないことが原因の可能性があります。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bd37c0d9f3fb6..26029615545f8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12281,7 +12281,6 @@ "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterSValidationErrorMessage": "{format}的字母 {length, plural, other { 组 {lg} }} 不受支持,因为其未前置 ss 和 {sep} 中的分隔符", "xpack.dataVisualizer.file.editFlyout.overrides.timestampLetterValidationErrorMessage": "{format}的字母 {length, plural, other { 组 {lg} }} 不受支持", "xpack.dataVisualizer.file.editFlyout.overrides.timestampQuestionMarkValidationErrorMessage": "时间戳格式 {timestampFormat} 不受支持,因为其包含问号字符 ({fieldPlaceholder})", - "xpack.dataVisualizer.file.fileContents.firstLinesDescription": "前 {numberOfLines, plural, other {# 行}}", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeByDiffFormatErrorMessage": "您选择用于上传的文件大小超过上限值 {maxFileSizeFormatted} 的 {diffFormatted}", "xpack.dataVisualizer.file.fileErrorCallouts.fileSizeExceedsAllowedSizeErrorMessage": "您选择用于上传的文件大小为 {fileSizeFormatted},超过上限值 {maxFileSizeFormatted}", "xpack.dataVisualizer.file.importSummary.documentsCouldNotBeImportedDescription": "无法导入 {importFailuresLength} 个文档(共 {docCount} 个)。这可能是由于行与 Grok 模式不匹配。", diff --git a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts index 24437e02e6907..3a859249fe234 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts @@ -22,7 +22,7 @@ export default function ({ getService }: FtrProviderContext) { expected: { results: { title: 'artificial_server_log', - numberOfFields: 4, + highlightedText: true, }, metricFields: [ { @@ -104,7 +104,7 @@ export default function ({ getService }: FtrProviderContext) { expected: { results: { title: 'geo_file.csv', - numberOfFields: 3, + highlightedText: false, }, metricFields: [], nonMetricFields: [ @@ -146,7 +146,7 @@ export default function ({ getService }: FtrProviderContext) { expected: { results: { title: 'missing_end_of_file_newline.csv', - numberOfFields: 3, + highlightedText: false, }, metricFields: [ { @@ -217,6 +217,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('displays the components of the file details page'); await ml.dataVisualizerFileBased.assertFileTitle(testData.expected.results.title); await ml.dataVisualizerFileBased.assertFileContentPanelExists(); + await ml.dataVisualizerFileBased.assertFileContentHighlightingSwitchExists( + testData.expected.results.highlightedText + ); + await ml.dataVisualizerFileBased.assertFileContentHighlighting( + testData.expected.results.highlightedText, + testData.expected.totalFieldsCount - 1 // -1 for the message field + ); await ml.dataVisualizerFileBased.assertSummaryPanelExists(); await ml.dataVisualizerFileBased.assertFileStatsPanelExists(); diff --git a/x-pack/test/functional/services/ml/data_visualizer_file_based.ts b/x-pack/test/functional/services/ml/data_visualizer_file_based.ts index 0b8effd17cbb0..df95eddd957f8 100644 --- a/x-pack/test/functional/services/ml/data_visualizer_file_based.ts +++ b/x-pack/test/functional/services/ml/data_visualizer_file_based.ts @@ -49,6 +49,32 @@ export function MachineLearningDataVisualizerFileBasedProvider( await testSubjects.existOrFail('dataVisualizerFileFileContentPanel'); }, + async assertFileContentHighlightingSwitchExists(exist: boolean) { + const tabs = await testSubjects.findAll('dataVisualizerFileContentsHighlightingSwitch'); + expect(tabs.length).to.eql( + exist ? 1 : 0, + `Expected file content highlighting switch to ${exist ? 'exist' : 'not exist'}, but found ${ + tabs.length + }` + ); + }, + + async assertFileContentHighlighting(highlighted: boolean, numberOfFields: number) { + const lines = await testSubjects.findAll('dataVisualizerHighlightedLine', 1000); + const linesExist = lines.length > 0; + expect(linesExist).to.eql( + highlighted, + `Expected file content highlighting to be '${highlighted ? 'enabled' : 'disabled'}'` + ); + const expectedNumberOfFields = highlighted ? numberOfFields : 0; + const foundFields = (await lines[0]?.findAllByTestSubject('dataVisualizerFieldBadge')) ?? []; + + expect(foundFields.length).to.eql( + expectedNumberOfFields, + `Expected ${expectedNumberOfFields} fields to be highlighted, but found ${foundFields.length}` + ); + }, + async assertSummaryPanelExists() { await testSubjects.existOrFail('dataVisualizerFileSummaryPanel'); }, From d492fb7300cfe86ee79e0ccee8743f4b57dcc351 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 8 Feb 2024 11:44:25 +0200 Subject: [PATCH 005/104] [ES|QL] Clicking the editor closes the documentation popover (#176394) ## Summary Part of https://github.com/elastic/kibana/issues/166907 Fixes the problem with the eui popovers and the monaco editor. I am not sure why it is happening. I think it is due to the third party library that eui uses to detects the outside clicks. What I did to fix it: - Wrap the documentation popover in an EuiOutsideClickDetector - I force monaco editor to focus onMoyseDown ![meow](https://github.com/elastic/kibana/assets/17003240/f432608d-0801-4a68-b327-da1e8dec9f9a) This solves the problem on the documentation popover but not on the SuperDatePicker because I don't have a way to force it to close. I will ping the EUI team --- .../src/components/documentation_popover.tsx | 70 +++++++++++-------- .../src/text_based_languages_editor.tsx | 11 +++ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/packages/kbn-language-documentation-popover/src/components/documentation_popover.tsx b/packages/kbn-language-documentation-popover/src/components/documentation_popover.tsx index db66d69d7173f..735c567dbb4d5 100644 --- a/packages/kbn-language-documentation-popover/src/components/documentation_popover.tsx +++ b/packages/kbn-language-documentation-popover/src/components/documentation_popover.tsx @@ -7,7 +7,13 @@ */ import React, { useCallback, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiPopover, EuiToolTip, EuiButtonIcon, EuiButtonIconProps } from '@elastic/eui'; +import { + EuiPopover, + EuiToolTip, + EuiButtonIcon, + EuiButtonIconProps, + EuiOutsideClickDetector, +} from '@elastic/eui'; import { type LanguageDocumentationSections, LanguageDocumentationPopoverContent, @@ -33,35 +39,41 @@ function DocumentationPopover({ }, [isHelpOpen]); return ( - setIsHelpOpen(false)} - button={ - - - - } + { + setIsHelpOpen(false); + }} > - - + setIsHelpOpen(false)} + button={ + + + + } + > + + + ); } diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 146e020d4fe82..15adf2f293bb8 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -815,6 +815,17 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ } }); + // this is fixing a bug between the EUIPopover and the monaco editor + // when the user clicks the editor, we force it to focus and the onDidFocusEditorText + // to fire, the timeout is needed because otherwise it refocuses on the popover icon + // and the user needs to click again the editor. + // IMPORTANT: The popover needs to be wrapped with the EuiOutsideClickDetector component. + editor.onMouseDown(() => { + setTimeout(() => { + editor.focus(); + }, 100); + }); + editor.onDidFocusEditorText(() => { onEditorFocus(); }); From 6bb2bd3d5cc45bf1cb5e486c5e0f68c9aa0fe4c5 Mon Sep 17 00:00:00 2001 From: Navarone Feekery <13634519+navarone-feekery@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:57:19 +0100 Subject: [PATCH 006/104] [Search] Remove API keys when deleting connectors (#176407) When deleting connectors or indices in Search: - Invalidate the API key if a connector has an `api_key_id` value - Delete the connector secret if a connector has an `api_key_secret_id` value --- .../lib/delete_connector_secret.test.ts | 39 +++++++++++++++++++ .../lib/delete_connector_secret.ts | 17 ++++++++ packages/kbn-search-connectors/lib/index.ts | 1 + .../routes/enterprise_search/connectors.ts | 18 ++++++--- .../routes/enterprise_search/indices.ts | 8 +++- 5 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 packages/kbn-search-connectors/lib/delete_connector_secret.test.ts create mode 100644 packages/kbn-search-connectors/lib/delete_connector_secret.ts diff --git a/packages/kbn-search-connectors/lib/delete_connector_secret.test.ts b/packages/kbn-search-connectors/lib/delete_connector_secret.test.ts new file mode 100644 index 0000000000000..164a37f3ccb57 --- /dev/null +++ b/packages/kbn-search-connectors/lib/delete_connector_secret.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; + +import { deleteConnectorSecret } from './delete_connector_secret'; + +describe('deleteConnectorSecret lib function', () => { + const mockClient = { + transport: { + request: jest.fn(), + }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + jest.useFakeTimers(); + }); + + it('should delete a connector secret', async () => { + mockClient.transport.request.mockImplementation(() => ({ + result: 'deleted', + })); + + await expect( + deleteConnectorSecret(mockClient as unknown as ElasticsearchClient, 'secret-id') + ).resolves.toEqual({ result: 'deleted' }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/_connector/_secret/secret-id', + }); + jest.useRealTimers(); + }); +}); diff --git a/packages/kbn-search-connectors/lib/delete_connector_secret.ts b/packages/kbn-search-connectors/lib/delete_connector_secret.ts new file mode 100644 index 0000000000000..d3ecbe8da73f5 --- /dev/null +++ b/packages/kbn-search-connectors/lib/delete_connector_secret.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { ConnectorsAPIUpdateResponse } from '../types/connectors_api'; + +export const deleteConnectorSecret = async (client: ElasticsearchClient, id: string) => { + return await client.transport.request({ + method: 'DELETE', + path: `/_connector/_secret/${id}`, + }); +}; diff --git a/packages/kbn-search-connectors/lib/index.ts b/packages/kbn-search-connectors/lib/index.ts index 3e929d5bc6834..e0a1caea66422 100644 --- a/packages/kbn-search-connectors/lib/index.ts +++ b/packages/kbn-search-connectors/lib/index.ts @@ -11,6 +11,7 @@ export * from './create_connector'; export * from './create_connector_document'; export * from './create_connector_secret'; export * from './delete_connector'; +export * from './delete_connector_secret'; export * from './fetch_connectors'; export * from './fetch_sync_jobs'; export * from './update_filtering'; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts index 39657c97c6202..4226e4326ce0a 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { deleteConnectorById, + deleteConnectorSecret, fetchConnectorById, fetchConnectors, fetchSyncJobs, @@ -589,18 +590,25 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { const { shouldDeleteIndex } = request.query; let connectorResponse; - let indexNameToDelete; try { - if (shouldDeleteIndex) { - const connector = await fetchConnectorById(client.asCurrentUser, connectorId); - indexNameToDelete = connector?.value.index_name; - } + const connector = await fetchConnectorById(client.asCurrentUser, connectorId); + const indexNameToDelete = shouldDeleteIndex ? connector?.value.index_name : null; + const apiKeyId = connector?.value.api_key_id; + const secretId = connector?.value.api_key_secret_id; + connectorResponse = await deleteConnectorById(client.asCurrentUser, connectorId); + if (indexNameToDelete) { await deleteIndexPipelines(client, indexNameToDelete); await deleteAccessControlIndex(client, indexNameToDelete); await client.asCurrentUser.indices.delete({ index: indexNameToDelete }); } + if (apiKeyId) { + await client.asCurrentUser.security.invalidateApiKey({ ids: [apiKeyId] }); + } + if (secretId) { + await deleteConnectorSecret(client.asCurrentUser, secretId); + } } catch (error) { if (isResourceNotFoundException(error)) { return createError({ diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index d96130fb02472..fdbeca1e82ff9 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -14,7 +14,7 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; -import { deleteConnectorById } from '@kbn/search-connectors'; +import { deleteConnectorById, deleteConnectorSecret } from '@kbn/search-connectors'; import { fetchConnectorByIndexName, fetchConnectors, @@ -204,6 +204,12 @@ export function registerIndexRoutes({ if (connector) { await deleteConnectorById(client.asCurrentUser, connector.id); + if (connector.api_key_id) { + await client.asCurrentUser.security.invalidateApiKey({ ids: [connector.api_key_id] }); + } + if (connector.api_key_secret_id) { + await deleteConnectorSecret(client.asCurrentUser, connector.api_key_secret_id); + } } await deleteIndexPipelines(client, indexName); From b1b36bdd23324bd12b74267287cbe368c1504eaa Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Thu, 8 Feb 2024 10:58:43 +0100 Subject: [PATCH 007/104] [Custom threshold] Add threshold to the custom threshold alert document (#176043) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of #175136 ## Summary This PR persists the threshold value in the AAD document. Now, when creating a custom threshold rule, you should be able to see the value in the alert table: ![image](https://github.com/elastic/kibana/assets/12370520/a5b3ddaf-f218-48c0-b73c-d4c7cc72506e) ## 🧪 How to test - Create a custom threshold rule with one or multiple conditions - When the related alert fires, you should be able to see the threshold value (unformatted) in the alert table --- .../alerts_table/common/render_cell_value.tsx | 5 +- .../custom_threshold_executor.test.ts | 3 ++ .../custom_threshold_executor.ts | 20 +++---- .../custom_threshold/lib/get_values.test.ts | 28 ++++++++++ .../rules/custom_threshold/lib/get_values.ts | 29 ++++++++++ .../mocks/custom_threshold_alert_result.ts | 54 +++++++++++++++++++ .../mocks/custom_threshold_metric_params.ts | 51 ++++++++++++++++++ .../lib/rules/custom_threshold/types.ts | 16 +++++- .../custom_threshold_rule/avg_pct_fired.ts | 2 +- .../custom_threshold_rule/avg_us_fired.ts | 4 +- .../custom_eq_avg_bytes_fired.ts | 2 +- .../documents_count_fired.ts | 2 +- .../custom_threshold_rule/group_by_fired.ts | 2 +- .../custom_threshold_rule/avg_pct_fired.ts | 2 +- .../custom_eq_avg_bytes_fired.ts | 2 +- .../documents_count_fired.ts | 2 +- .../custom_threshold_rule/group_by_fired.ts | 2 +- 17 files changed, 203 insertions(+), 23 deletions(-) create mode 100644 x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.test.ts create mode 100644 x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.ts create mode 100644 x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_alert_result.ts create mode 100644 x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_metric_params.ts diff --git a/x-pack/plugins/observability/public/components/alerts_table/common/render_cell_value.tsx b/x-pack/plugins/observability/public/components/alerts_table/common/render_cell_value.tsx index 3bde70900d334..d68b11115396e 100644 --- a/x-pack/plugins/observability/public/components/alerts_table/common/render_cell_value.tsx +++ b/x-pack/plugins/observability/public/components/alerts_table/common/render_cell_value.tsx @@ -100,11 +100,12 @@ export const getRenderCellValue = ({ case ALERT_SEVERITY: return ; case ALERT_EVALUATION_VALUE: - const values = getMappedNonEcsValue({ + const valuesField = getMappedNonEcsValue({ data, fieldName: ALERT_EVALUATION_VALUES, }); - return values ? values : value; + const values = getRenderValue(valuesField); + return valuesField ? values : value; case ALERT_REASON: const dataFieldEs = data.reduce((acc, d) => ({ ...acc, [d.field]: d.value }), {}); const alert = parseAlert(observabilityRuleTypeRegistry)(dataFieldEs); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts index 9e3eab1e8a054..51fc7e7227cdf 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts @@ -75,11 +75,13 @@ const mockOptions = { previousStartedAt: null, params: { searchConfiguration: { + index: {}, query: { query: mockQuery, language: 'kuery', }, }, + alertOnNoData: true, }, state: { wrapped: initialRuleState, @@ -573,6 +575,7 @@ describe('The custom threshold alert type', () => { }, ], searchConfiguration: { + index: {}, query: { query: filterQuery, language: 'kuery', diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts index 39dbade62ce62..b59c3f532daea 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts @@ -10,6 +10,7 @@ import { LogsExplorerLocatorParams } from '@kbn/deeplinks-observability'; import { ALERT_ACTION_GROUP, ALERT_EVALUATION_VALUES, + ALERT_EVALUATION_THRESHOLD, ALERT_REASON, ALERT_GROUP, } from '@kbn/rule-data-utils'; @@ -17,13 +18,14 @@ import { LocatorPublic } from '@kbn/share-plugin/common'; import { RecoveredActionGroup } from '@kbn/alerting-plugin/common'; import { IBasePath, Logger } from '@kbn/core/server'; import { LifecycleRuleExecutor } from '@kbn/rule-registry-plugin/server'; +import { getEvaluationValues, getThreshold } from './lib/get_values'; import { AlertsLocatorParams, getAlertUrl } from '../../../../common'; import { getViewInAppUrl } from '../../../../common/custom_threshold_rule/get_view_in_app_url'; import { ObservabilityConfig } from '../../..'; import { FIRED_ACTIONS_ID, NO_DATA_ACTIONS_ID, UNGROUPED_FACTORY_KEY } from './constants'; import { AlertStates, - CustomThresholdRuleParams, + CustomThresholdRuleTypeParams, CustomThresholdRuleTypeState, CustomThresholdAlertState, CustomThresholdAlertContext, @@ -66,7 +68,7 @@ export const createCustomThresholdExecutor = ({ config: ObservabilityConfig; locators: CustomThresholdLocators; }): LifecycleRuleExecutor< - CustomThresholdRuleParams, + CustomThresholdRuleTypeParams, CustomThresholdRuleTypeState, CustomThresholdAlertState, CustomThresholdAlertContext, @@ -108,6 +110,7 @@ export const createCustomThresholdExecutor = ({ actionGroup, additionalContext, evaluationValues, + threshold, group ) => alertWithLifecycle({ @@ -116,6 +119,7 @@ export const createCustomThresholdExecutor = ({ [ALERT_REASON]: reason, [ALERT_ACTION_GROUP]: actionGroup, [ALERT_EVALUATION_VALUES]: evaluationValues, + [ALERT_EVALUATION_THRESHOLD]: threshold, [ALERT_GROUP]: group, ...flattenAdditionalContext(additionalContext), }, @@ -139,7 +143,7 @@ export const createCustomThresholdExecutor = ({ ? state.missingGroups : []; - const initialSearchSource = await searchSourceClient.create(params.searchConfiguration!); + const initialSearchSource = await searchSourceClient.create(params.searchConfiguration); const dataView = initialSearchSource.getField('index')!; const { id: dataViewId, timeFieldName } = dataView; const dataViewIndexPattern = dataView.getIndexPattern(); @@ -241,6 +245,8 @@ export const createCustomThresholdExecutor = ({ if (reason) { const timestamp = startedAt.toISOString(); + const threshold = getThreshold(criteria); + const evaluationValues = getEvaluationValues(alertResults, group); const actionGroupId: CustomThresholdActionGroup = nextState === AlertStates.OK ? RecoveredActionGroup.id @@ -258,19 +264,13 @@ export const createCustomThresholdExecutor = ({ new Set([...(additionalContext.tags ?? []), ...options.rule.tags]) ); - const evaluationValues = alertResults.reduce((acc: Array, result) => { - if (result[group]) { - acc.push(result[group].currentValue); - } - return acc; - }, []); - const alert = alertFactory( `${group}`, reason, actionGroupId, additionalContext, evaluationValues, + threshold, groupByKeysObjectMapping[group] ); const alertUuid = getAlertUuid(group); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.test.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.test.ts new file mode 100644 index 0000000000000..ddf2b7b1b1a45 --- /dev/null +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.test.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { alertResultsMultipleConditions } from '../mocks/custom_threshold_alert_result'; +import { criteriaMultipleConditions } from '../mocks/custom_threshold_metric_params'; +import { getEvaluationValues, getThreshold } from './get_values'; + +describe('getValue helpers', () => { + describe('getThreshold', () => { + test('should return threshold for one condition', () => { + expect(getThreshold([criteriaMultipleConditions[1]])).toEqual([4, 5]); + }); + + test('should return threshold for multiple conditions', () => { + expect(getThreshold(criteriaMultipleConditions)).toEqual([1, 2, 4, 5]); + }); + }); + + describe('getEvaluationValues', () => { + test('should return evaluation values ', () => { + expect(getEvaluationValues(alertResultsMultipleConditions, '*')).toEqual([1.0, 3.0]); + }); + }); +}); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.ts new file mode 100644 index 0000000000000..13c0cabb9b590 --- /dev/null +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/get_values.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CustomMetricExpressionParams } from '../../../../../common/custom_threshold_rule/types'; +import { Evaluation } from './evaluate_rule'; + +export const getEvaluationValues = ( + alertResults: Array>, + group: string +): Array => { + return alertResults.reduce((acc: Array, result) => { + if (result[group]) { + acc.push(result[group].currentValue); + } + return acc; + }, []); +}; + +export const getThreshold = (criteria: CustomMetricExpressionParams[]): number[] => { + const threshold = criteria.map((c) => c.threshold); + + return threshold.reduce((acc: number[], t) => { + return acc.concat(...t); + }, []); +}; diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_alert_result.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_alert_result.ts new file mode 100644 index 0000000000000..b8ab169b7a90d --- /dev/null +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_alert_result.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + Aggregators, + Comparator, + CustomMetricExpressionParams, +} from '../../../../../common/custom_threshold_rule/types'; +import { Evaluation } from '../lib/evaluate_rule'; + +const customThresholdNonCountCriterion: CustomMetricExpressionParams = { + comparator: Comparator.GT, + metrics: [ + { + aggType: Aggregators.AVERAGE, + name: 'A', + field: 'test.metric.1', + }, + ], + timeSize: 1, + timeUnit: 'm', + threshold: [0], +}; + +export const alertResultsMultipleConditions: Array> = [ + { + '*': { + ...customThresholdNonCountCriterion, + comparator: Comparator.GT, + threshold: [0.75], + currentValue: 1.0, + timestamp: new Date().toISOString(), + shouldFire: true, + isNoData: false, + bucketKey: { groupBy0: '*' }, + }, + }, + { + '*': { + ...customThresholdNonCountCriterion, + comparator: Comparator.GT, + threshold: [0.75], + currentValue: 3.0, + timestamp: new Date().toISOString(), + shouldFire: true, + isNoData: false, + bucketKey: { groupBy0: '*' }, + }, + }, +]; diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_metric_params.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_metric_params.ts new file mode 100644 index 0000000000000..9d09c90859659 --- /dev/null +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/mocks/custom_threshold_metric_params.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + Aggregators, + Comparator, + CustomMetricExpressionParams, +} from '../../../../../common/custom_threshold_rule/types'; + +export const criteriaMultipleConditions: CustomMetricExpressionParams[] = [ + { + metrics: [ + { + name: 'A', + aggType: Aggregators.AVERAGE, + field: 'system.is.a.good.puppy.dog', + }, + { + name: 'B', + aggType: Aggregators.AVERAGE, + field: 'system.is.a.bad.kitty', + }, + ], + timeUnit: 'm', + timeSize: 1, + threshold: [1, 2], + comparator: Comparator.GT, + }, + { + metrics: [ + { + name: 'A', + aggType: Aggregators.AVERAGE, + field: 'system.is.a.good.puppy.dog', + }, + { + name: 'B', + aggType: Aggregators.AVERAGE, + field: 'system.is.a.bad.kitty', + }, + ], + timeUnit: 'm', + timeSize: 1, + threshold: [4, 5], + comparator: Comparator.GT, + }, +]; diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/types.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/types.ts index 97881f55d8d32..f688088d6b816 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/types.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/types.ts @@ -14,6 +14,8 @@ import { } from '@kbn/alerting-plugin/common'; import { Alert } from '@kbn/alerting-plugin/server'; import { TypeOf } from '@kbn/config-schema'; +import { DataViewSpec } from '@kbn/data-views-plugin/common'; +import { CustomMetricExpressionParams } from '../../../../common/custom_threshold_rule/types'; import { FIRED_ACTIONS_ID, NO_DATA_ACTIONS_ID, FIRED_ACTION, NO_DATA_ACTION } from './constants'; import { MissingGroupsRecord } from './lib/check_missing_group'; import { AdditionalContext } from './utils'; @@ -28,13 +30,22 @@ export enum AlertStates { // Executor types export type SearchConfigurationType = TypeOf; +export type RuleTypeParams = Record; + +export interface CustomThresholdRuleTypeParams extends RuleTypeParams { + criteria: CustomMetricExpressionParams[]; + // Index will be a data view spec after extracting references + searchConfiguration: Omit & { index: DataViewSpec }; + groupBy?: string | string[]; + alertOnNoData: boolean; + alertOnGroupDisappear?: boolean; +} -export type CustomThresholdRuleParams = Record; export type CustomThresholdRuleTypeState = RuleTypeState & { lastRunTimestamp?: number; missingGroups?: Array; groupBy?: string | string[]; - searchConfiguration?: SearchConfigurationType; + searchConfiguration?: Omit & { index: DataViewSpec }; }; export type CustomThresholdAlertState = AlertState; // no specific instance state used export type CustomThresholdAlertContext = AlertContext & { @@ -64,6 +75,7 @@ export type CustomThresholdAlertFactory = ( actionGroup: CustomThresholdActionGroup, additionalContext?: AdditionalContext | null, evaluationValues?: Array, + threshold?: Array, group?: Group ) => CustomThresholdAlert; diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts index 9c41ca3d150b3..929913f15f39f 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts @@ -209,7 +209,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.5]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts index 7d9c7bf7e657e..1a32a0af3612e 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts @@ -187,7 +187,9 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source) + .property('kibana.alert.evaluation.threshold') + .eql([7500000]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts index 06eaea7f21c9c..d1c8a2927837c 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts @@ -206,7 +206,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.9]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts index 0185d7b8ea05e..43029573defd8 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts @@ -208,7 +208,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('event.action', 'open'); expect(resp.hits.hits[0]._source).not.have.property('kibana.alert.group'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([1, 2]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts index ca73e43114441..55f2d61be2b0e 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts @@ -230,7 +230,7 @@ export default function ({ getService }: FtrProviderContext) { value: 'container-0', }, ]); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.2]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts index 32dd3e263998b..47ed06c1ad440 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts @@ -191,7 +191,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.5]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts index 95d9608d0a841..8b6d76a380748 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts @@ -200,7 +200,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.9]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts index 519c0329e6390..15c34602e0a78 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts @@ -191,7 +191,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open'); expect(resp.hits.hits[0]._source).property('event.kind', 'signal'); expect(resp.hits.hits[0]._source).property('event.action', 'open'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([1, 2]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts index ccd2aa6edaeaa..264057cacff1c 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts @@ -217,7 +217,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source).property('container.id', 'container-0'); expect(resp.hits.hits[0]._source).property('container.name', 'container-name'); expect(resp.hits.hits[0]._source).not.property('container.cpu'); - + expect(resp.hits.hits[0]._source).property('kibana.alert.evaluation.threshold').eql([0.2]); expect(resp.hits.hits[0]._source) .property('kibana.alert.rule.parameters') .eql({ From 52f35fca662bffe99ee3ba431f7d1e94a50ac903 Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Thu, 8 Feb 2024 11:30:01 +0100 Subject: [PATCH 008/104] [Observability AI Assistant] Chat tweaks + keyboard shortcut (#176350) --- .../action_menu_item/action_menu_item.tsx | 16 +- .../components/chat/chat_actions_menu.tsx | 28 ++-- .../public/components/chat/chat_body.tsx | 23 ++- .../public/components/chat/chat_flyout.tsx | 138 +++++++++++++----- .../public/components/chat/chat_header.tsx | 128 +++++++++++++--- .../use_observability_ai_assistant_router.ts | 37 ++++- 6 files changed, 293 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx b/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx index f11f2c8b56bc6..c357d9d22e8f6 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiHeaderLink, EuiLoadingSpinner } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ObservabilityAIAssistantChatServiceProvider } from '../../context/observability_ai_assistant_chat_service_provider'; @@ -30,6 +30,20 @@ export function ObservabilityAIAssistantActionMenuItem() { const initialMessages = useMemo(() => [], []); + useEffect(() => { + const keyboardListener = (event: KeyboardEvent) => { + if (event.ctrlKey && event.code === 'Semicolon') { + setIsOpen(true); + } + }; + + window.addEventListener('keypress', keyboardListener); + + return () => { + window.removeEventListener('keypress', keyboardListener); + }; + }, []); + if (!service.isEnabled()) { return null; } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx index 4186f2c70c04d..f9635f5808072 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx @@ -7,7 +7,7 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonIcon, EuiContextMenu, EuiPanel, EuiPopover } from '@elastic/eui'; +import { EuiButtonIcon, EuiContextMenu, EuiPanel, EuiPopover, EuiToolTip } from '@elastic/eui'; import { useKibana } from '../../hooks/use_kibana'; import { useObservabilityAIAssistantRouter } from '../../hooks/use_observability_ai_assistant_router'; import { getSettingsHref } from '../../utils/get_settings_href'; @@ -52,16 +52,24 @@ export function ChatActionsMenu({ + display="block" + > + + } panelPaddingSize="none" closePopover={toggleActionsMenu} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx index 373e35641ff8f..8ed26d71acc58 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx @@ -43,6 +43,7 @@ import { import { ASSISTANT_SETUP_TITLE, EMPTY_CONVERSATION_TITLE, UPGRADE_LICENSE_TITLE } from '../../i18n'; import type { StartedFrom } from '../../utils/get_timeline_items_from_conversation'; import { TELEMETRY, sendEvent } from '../../analytics'; +import { FlyoutWidthMode } from './chat_flyout'; const fullHeightClassName = css` height: 100%; @@ -93,27 +94,31 @@ const animClassName = css` const PADDING_AND_BORDER = 32; export function ChatBody({ - initialTitle, - initialMessages, - initialConversationId, + chatFlyoutSecondSlotHandler, connectors, - knowledgeBase, currentUser, + flyoutWidthMode, + initialConversationId, + initialMessages, + initialTitle, + knowledgeBase, showLinkToConversationsApp, startedFrom, - chatFlyoutSecondSlotHandler, onConversationUpdate, + onToggleFlyoutWidthMode, }: { + chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; + connectors: UseGenAIConnectorsResult; + currentUser?: Pick; + flyoutWidthMode?: FlyoutWidthMode; initialTitle?: string; initialMessages?: Message[]; initialConversationId?: string; - connectors: UseGenAIConnectorsResult; knowledgeBase: UseKnowledgeBaseResult; - currentUser?: Pick; showLinkToConversationsApp: boolean; startedFrom?: StartedFrom; - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; onConversationUpdate: (conversation: { conversation: Conversation['conversation'] }) => void; + onToggleFlyoutWidthMode?: (flyoutWidthMode: FlyoutWidthMode) => void; }) { const license = useLicense(); const hasCorrectLicense = license?.hasAtLeast('enterprise'); @@ -455,6 +460,7 @@ export function ChatBody({ ? conversation.value.conversation.id : undefined } + flyoutWidthMode={flyoutWidthMode} licenseInvalid={!hasCorrectLicense && !initialConversationId} loading={isLoading} showLinkToConversationsApp={showLinkToConversationsApp} @@ -463,6 +469,7 @@ export function ChatBody({ onSaveTitle={(newTitle) => { saveTitle(newTitle); }} + onToggleFlyoutWidthMode={onToggleFlyoutWidthMode} /> diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx index 83c1496befa4f..6823153397ca4 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx @@ -9,7 +9,15 @@ import ReactDOM from 'react-dom'; import { i18n } from '@kbn/i18n'; import { v4 } from 'uuid'; import { css } from '@emotion/css'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiFlyout, useEuiTheme } from '@elastic/eui'; +import { + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiPopover, + EuiToolTip, + useEuiTheme, +} from '@elastic/eui'; import { useForceUpdate } from '../../hooks/use_force_update'; import { useCurrentUser } from '../../hooks/use_current_user'; import { useGenAIConnectors } from '../../hooks/use_genai_connectors'; @@ -25,6 +33,8 @@ const CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED = 34; const SIDEBAR_WIDTH = 400; +export type FlyoutWidthMode = 'side' | 'full'; + export function ChatFlyout({ initialTitle, initialMessages, @@ -48,26 +58,36 @@ export function ChatFlyout({ const [conversationId, setConversationId] = useState(undefined); - const [expanded, setExpanded] = useState(false); + const [flyoutWidthMode, setFlyoutWidthMode] = useState('side'); + + const [conversationsExpanded, setConversationsExpanded] = useState(false); + const [secondSlotContainer, setSecondSlotContainer] = useState(null); const [isSecondSlotVisible, setIsSecondSlotVisible] = useState(false); const sidebarClass = css` - max-width: ${expanded ? CONVERSATIONS_SIDEBAR_WIDTH : CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED}px; - min-width: ${expanded ? CONVERSATIONS_SIDEBAR_WIDTH : CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED}px; + max-width: ${conversationsExpanded + ? CONVERSATIONS_SIDEBAR_WIDTH + : CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED}px; + min-width: ${conversationsExpanded + ? CONVERSATIONS_SIDEBAR_WIDTH + : CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED}px; border-right: solid 1px ${euiTheme.border.color}; `; - const expandButtonClassName = css` + const expandButtonContainerClassName = css` position: absolute; margin-top: 16px; - margin-left: ${expanded + margin-left: ${conversationsExpanded ? CONVERSATIONS_SIDEBAR_WIDTH - CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED : 5}px; - padding: ${euiTheme.size.s}; z-index: 1; `; + const expandButtonClassName = css` + color: ${euiTheme.colors.primary}; + `; + const containerClassName = css` height: 100%; `; @@ -79,10 +99,9 @@ export function ChatFlyout({ const newChatButtonClassName = css` position: absolute; bottom: 31px; - margin-left: ${expanded + margin-left: ${conversationsExpanded ? CONVERSATIONS_SIDEBAR_WIDTH - CONVERSATIONS_SIDEBAR_WIDTH_COLLAPSED : 5}px; - padding: ${euiTheme.size.s}; z-index: 1; `; @@ -110,12 +129,20 @@ export function ChatFlyout({ } }; + const handleToggleFlyoutWidthMode = (newFlyoutWidthMode: FlyoutWidthMode) => { + setFlyoutWidthMode(newFlyoutWidthMode); + }; + return isOpen ? ( { onClose(); @@ -127,19 +154,40 @@ export function ChatFlyout({ > - setExpanded(!expanded)} + + setConversationsExpanded(!conversationsExpanded)} + /> + + } /> - {expanded ? ( + {conversationsExpanded ? ( ) : ( - + + + } className={newChatButtonClassName} - data-test-subj="observabilityAiAssistantNewChatFlyoutButton" - iconType="plusInCircle" - onClick={handleClickNewChat} /> )} @@ -163,21 +224,23 @@ export function ChatFlyout({ { setConversationId(conversation.conversation.id); }} - chatFlyoutSecondSlotHandler={{ - container: secondSlotContainer, - setVisibility: setIsSecondSlotVisible, - }} - showLinkToConversationsApp + onToggleFlyoutWidthMode={handleToggleFlyoutWidthMode} /> @@ -204,10 +267,15 @@ export function ChatFlyout({ const getFlyoutWidth = ({ expanded, isSecondSlotVisible, + flyoutWidthMode, }: { expanded: boolean; isSecondSlotVisible: boolean; + flyoutWidthMode?: FlyoutWidthMode; }) => { + if (flyoutWidthMode === 'full') { + return '100%'; + } if (!expanded && !isSecondSlotVisible) { return '40vw'; } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx index cd4dc0d824590..de8a80928207b 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx @@ -6,11 +6,14 @@ */ import React, { useEffect, useState } from 'react'; import { + EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiInlineEditTitle, EuiLoadingSpinner, EuiPanel, + EuiPopover, + EuiToolTip, useEuiTheme, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -18,6 +21,8 @@ import { css } from '@emotion/css'; import { AssistantAvatar } from '../assistant_avatar'; import { ChatActionsMenu } from './chat_actions_menu'; import type { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors'; +import type { FlyoutWidthMode } from './chat_flyout'; +import { useObservabilityAIAssistantRouter } from '../../hooks/use_observability_ai_assistant_router'; // needed to prevent InlineTextEdit component from expanding container const minWidthClassName = css` @@ -30,36 +35,54 @@ const chatHeaderClassName = css` `; export function ChatHeader({ - title, - loading, - licenseInvalid, connectors, conversationId, + flyoutWidthMode, + licenseInvalid, + loading, showLinkToConversationsApp, + title, onCopyConversation, onSaveTitle, + onToggleFlyoutWidthMode, }: { - title: string; - loading: boolean; - licenseInvalid: boolean; connectors: UseGenAIConnectorsResult; conversationId?: string; + flyoutWidthMode?: FlyoutWidthMode; + licenseInvalid: boolean; + loading: boolean; showLinkToConversationsApp: boolean; + title: string; onCopyConversation: () => void; onSaveTitle: (title: string) => void; + onToggleFlyoutWidthMode?: (newFlyoutWidthMode: FlyoutWidthMode) => void; }) { const theme = useEuiTheme(); + const router = useObservabilityAIAssistantRouter(); + const [newTitle, setNewTitle] = useState(title); useEffect(() => { setNewTitle(title); }, [title]); - const chatActionsMenuWrapper = css` - position: absolute; - right: 46px; - `; + const handleToggleFlyoutWidthMode = () => { + onToggleFlyoutWidthMode?.(flyoutWidthMode === 'side' ? 'full' : 'side'); + }; + + const handleNavigateToConversations = () => { + if (conversationId) { + router.navigateToConversationsApp('/conversations/{conversationId}', { + path: { + conversationId, + }, + query: {}, + }); + } else { + router.navigateToConversationsApp('/conversations/new', { path: {}, query: {} }); + } + }; return ( - - + + + + {flyoutWidthMode && onToggleFlyoutWidthMode ? ( + <> + + + + + } + /> + + + + + + + } + /> + + + ) : null} + + + + + diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts index 160a4835d0ffb..afdae21c91a8d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts @@ -21,13 +21,20 @@ interface StatefulObservabilityAIAssistantRouter extends ObservabilityAIAssistan path: T, ...params: TypeAsArgs> ): void; + navigateToConversationsApp>( + path: T, + ...params: TypeAsArgs> + ): void; } export function useObservabilityAIAssistantRouter(): StatefulObservabilityAIAssistantRouter { const history = useHistory(); const { - services: { http }, + services: { + http, + application: { navigateToApp }, + }, } = useKibana(); const link = (...args: any[]) => { @@ -43,6 +50,32 @@ export function useObservabilityAIAssistantRouter(): StatefulObservabilityAIAssi history.push(next); }, + navigateToConversationsApp: (path, ...args) => { + const [_, route, routeParam] = path.split('/'); + + const sanitized = routeParam.replace('{', '').replace('}', ''); + + const pathKey = args[0]?.path; + + if (typeof pathKey !== 'object') { + return; + } + + if (Object.keys(pathKey).length === 0) { + navigateToApp('observabilityAIAssistant', { + path: route, + }); + return; + } + + if (Object.keys(pathKey).length === 1) { + navigateToApp('observabilityAIAssistant', { + // @ts-expect-error + path: `${route}/${pathKey[sanitized]}`, + }); + return; + } + }, replace: (path, ...args) => { const next = link(path, ...args); history.replace(next); @@ -51,6 +84,6 @@ export function useObservabilityAIAssistantRouter(): StatefulObservabilityAIAssi return http.basePath.prepend('/app/observabilityAIAssistant' + link(path, ...args)); }, }), - [http, history] + [history, navigateToApp, http.basePath] ); } From 6076d1b39588867f33cd258375120f0b813447ce Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 8 Feb 2024 12:56:55 +0200 Subject: [PATCH 009/104] [ES|QL] Adds link on the documentation popover to navigate users to our external docs (#176377) ## Summary Part of https://github.com/elastic/kibana/issues/173495 Adds a link to the external documents in the popover used for ES|QL reference. The request is here https://github.com/elastic/kibana/issues/173495#issuecomment-1916896737 image --- .../src/components/documentation_content.tsx | 37 ++++++++++++++++--- .../src/components/documentation_popover.tsx | 3 ++ .../src/text_based_languages_editor.tsx | 9 ++++- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/packages/kbn-language-documentation-popover/src/components/documentation_content.tsx b/packages/kbn-language-documentation-popover/src/components/documentation_content.tsx index 0f24e233a4f28..daf52aba46727 100644 --- a/packages/kbn-language-documentation-popover/src/components/documentation_content.tsx +++ b/packages/kbn-language-documentation-popover/src/components/documentation_content.tsx @@ -10,7 +10,6 @@ import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem, - EuiLink, EuiPopoverTitle, EuiText, EuiListGroupItem, @@ -19,6 +18,7 @@ import { EuiFieldSearch, EuiHighlight, EuiSpacer, + EuiLink, } from '@elastic/eui'; import { elementToString } from '../utils/element_to_string'; @@ -38,9 +38,16 @@ interface DocumentationProps { sections?: LanguageDocumentationSections; // if sets to true, allows searching in the markdown description searchInDescription?: boolean; + // if set, a link will appear on the top right corner + linkToDocumentation?: string; } -function DocumentationContent({ language, sections, searchInDescription }: DocumentationProps) { +function DocumentationContent({ + language, + sections, + searchInDescription, + linkToDocumentation, +}: DocumentationProps) { const [selectedSection, setSelectedSection] = useState(); const scrollTargets = useRef>({}); @@ -83,10 +90,28 @@ function DocumentationContent({ language, sections, searchInDescription }: Docum paddingSize="m" data-test-subj="language-documentation-title" > - {i18n.translate('languageDocumentationPopover.header', { - defaultMessage: '{language} reference', - values: { language }, - })} + + + {i18n.translate('languageDocumentationPopover.header', { + defaultMessage: '{language} reference', + values: { language }, + })} + + {linkToDocumentation && ( + + + {i18n.translate('languageDocumentationPopover.documentationLinkLabel', { + defaultMessage: 'View full documentation', + })} + + + )} + ; searchInDescription?: boolean; + linkToDocumentation?: string; } function DocumentationPopover({ @@ -31,6 +32,7 @@ function DocumentationPopover({ sections, buttonProps, searchInDescription, + linkToDocumentation, }: DocumentationPopoverProps) { const [isHelpOpen, setIsHelpOpen] = useState(false); @@ -71,6 +73,7 @@ function DocumentationPopover({ language={language} sections={sections} searchInDescription={searchInDescription} + linkToDocumentation={linkToDocumentation} /> diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 15adf2f293bb8..7bdfce427bc21 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -163,7 +163,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const language = getAggregateQueryMode(query); const queryString: string = query[language] ?? ''; const kibana = useKibana(); - const { dataViews, expressions, indexManagementApiService, application } = kibana.services; + const { dataViews, expressions, indexManagementApiService, application, docLinks } = + kibana.services; const [code, setCode] = useState(queryString ?? ''); const [codeOneLiner, setCodeOneLiner] = useState(''); // To make server side errors less "sticky", register the state of the code when submitting @@ -680,6 +681,9 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ language={getLanguageDisplayName(String(language))} sections={documentationSections} searchInDescription + linkToDocumentation={ + language === 'esql' ? docLinks?.links?.query?.queryESQL : '' + } buttonProps={{ color: 'text', size: 's', @@ -914,6 +918,9 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ language={ String(language) === 'esql' ? 'ES|QL' : String(language).toUpperCase() } + linkToDocumentation={ + language === 'esql' ? docLinks?.links?.query?.queryESQL : '' + } searchInDescription sections={documentationSections} buttonProps={{ From cf1ae59ec044c9b80df18c5467a855bc557236cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Thu, 8 Feb 2024 12:14:46 +0100 Subject: [PATCH 010/104] [Obs AI Assistant] Improved logging (#176289) Tiny PR to improve debug logs --- .../server/functions/recall.ts | 20 ++++++++++++------- .../server/service/client/index.ts | 6 ++++++ .../service/knowledge_base_service/index.ts | 8 ++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts index 7e966fa0e5508..ee0fae1f91ed1 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts @@ -15,6 +15,7 @@ import { FunctionRegistrationParameters } from '.'; import { MessageRole, type Message } from '../../common/types'; import { concatenateChatCompletionChunks } from '../../common/utils/concatenate_chat_completion_chunks'; import type { ObservabilityAIAssistantClient } from '../service/client'; +import { RespondFunctionResources } from '../service/types'; export function registerRecallFunction({ client, @@ -95,10 +96,6 @@ export function registerRecallFunction({ queries, }); - resources.logger.debug(`Received ${suggestions.length} suggestions`); - - resources.logger.debug(JSON.stringify(suggestions, null, 2)); - if (suggestions.length === 0) { return { content: [] as unknown as Serializable, @@ -113,11 +110,9 @@ export function registerRecallFunction({ client, connectorId, signal, + resources, }); - resources.logger.debug(`Received ${relevantDocuments.length} relevant documents`); - resources.logger.debug(JSON.stringify(relevantDocuments, null, 2)); - return { content: relevantDocuments as unknown as Serializable, }; @@ -177,6 +172,7 @@ async function scoreSuggestions({ client, connectorId, signal, + resources, }: { suggestions: Awaited>; systemMessage: Message; @@ -185,7 +181,10 @@ async function scoreSuggestions({ client: ObservabilityAIAssistantClient; connectorId: string; signal: AbortSignal; + resources: RespondFunctionResources; }) { + resources.logger.debug(`Suggestions: ${JSON.stringify(suggestions, null, 2)}`); + const systemMessageExtension = dedent(`You have the function called score available to help you inform the user about how relevant you think a given document is to the conversation. Please give a score between 1 and 7, fractions are allowed. @@ -262,6 +261,8 @@ async function scoreSuggestions({ scoreFunctionRequest.message.function_call.arguments ); + resources.logger.debug(`Scores: ${JSON.stringify(scores, null, 2)}`); + if (scores.length === 0) { return []; } @@ -279,5 +280,10 @@ async function scoreSuggestions({ relevantDocumentIds.includes(suggestion.id) ); + resources.logger.debug( + `Found ${relevantDocumentIds.length} relevant suggestions from the knowledge base. ${scores.length} suggestions were considered in total.` + ); + resources.logger.debug(`Relevant documents: ${JSON.stringify(relevantDocuments, null, 2)}`); + return relevantDocuments; } diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index 76749e75daed1..f3ab3e917979b 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -320,6 +320,10 @@ export class ObservabilityAIAssistantClient { }, }; + this.dependencies.logger.debug( + `Function response: ${JSON.stringify(functionResponseMessage, null, 2)}` + ); + nextMessages = nextMessages.concat(functionResponseMessage); subscriber.next({ @@ -357,6 +361,8 @@ export class ObservabilityAIAssistantClient { return await next(nextMessages); } + this.dependencies.logger.debug(`Conversation: ${JSON.stringify(nextMessages, null, 2)}`); + if (!persist) { subscriber.complete(); return; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts index 9442985602e98..6783f972f6b4c 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts @@ -436,6 +436,7 @@ export class KnowledgeBaseService { }): Promise<{ entries: RecalledEntry[]; }> => { + this.dependencies.logger.debug(`Recalling entries from KB for queries: "${queries}"`); const modelId = await this.dependencies.getModelId(); const [documentsFromKb, documentsFromConnectors] = await Promise.all([ @@ -482,10 +483,9 @@ export class KnowledgeBaseService { } } - if (returnedEntries.length <= sortedEntries.length) { - this.dependencies.logger.debug( - `Dropped ${sortedEntries.length - returnedEntries.length} entries because of token limit` - ); + const droppedEntries = sortedEntries.length - returnedEntries.length; + if (droppedEntries > 0) { + this.dependencies.logger.info(`Dropped ${droppedEntries} entries because of token limit`); } return { From 0f3a72d700d13ff95e33e7f2a862cff411ec8b8c Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:56:34 +0100 Subject: [PATCH 011/104] [Lens] replace deprecated createReducer object notation with builder notation (#176404) We get this message in the console and in our tests: Screenshot 2024-02-07 at 14 12 34 I updated the syntax to the builder notation. --------- Co-authored-by: Marco Liberati --- .../public/state_management/lens_slice.ts | 1597 ++++++++--------- 1 file changed, 712 insertions(+), 885 deletions(-) diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.ts b/x-pack/plugins/lens/public/state_management/lens_slice.ts index 309efeb8ea827..b7b02bdbc934b 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createAction, createReducer, current, PayloadAction } from '@reduxjs/toolkit'; +import { createAction, createReducer, current } from '@reduxjs/toolkit'; import { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import { mapValues, uniq } from 'lodash'; import { Filter, Query } from '@kbn/es-query'; @@ -320,986 +320,813 @@ export const lensActions = { export const makeLensReducer = (storeDeps: LensStoreDeps) => { const { datasourceMap, visualizationMap } = storeDeps; - return createReducer(initialState, { - [setState.type]: (state, { payload }: PayloadAction>) => { - return { - ...state, - ...payload, - }; - }, - [setExecutionContext.type]: (state, { payload }: PayloadAction) => { - return { - ...state, - ...payload, - }; - }, - [initExisting.type]: (state, { payload }: PayloadAction>) => { - return { - ...state, - ...payload, - }; - }, - [onActiveDataChange.type]: ( - state, - { payload: { activeData } }: PayloadAction<{ activeData: TableInspectorAdapter }> - ) => { - return { - ...state, - activeData, - }; - }, - [setSaveable.type]: (state, { payload }: PayloadAction) => { - return { - ...state, - isSaveable: payload, - }; - }, - [enableAutoApply.type]: (state) => { - state.autoApplyDisabled = false; - }, - [disableAutoApply.type]: (state) => { - state.autoApplyDisabled = true; - state.changesApplied = true; - }, - [applyChanges.type]: (state) => { - if (typeof state.applyChangesCounter === 'undefined') { - state.applyChangesCounter = 0; - } - state.applyChangesCounter!++; - }, - [setChangesApplied.type]: (state, { payload: applied }) => { - state.changesApplied = applied; - }, - [cloneLayer.type]: ( - state, - { - payload: { layerId, newLayerId }, - }: { - payload: { - layerId: string; - newLayerId: string; + return createReducer(initialState, (builder) => { + builder + .addCase(setState, (state, { payload }) => { + return { + ...state, + ...payload, }; - } - ) => { - const clonedIDsMap = new Map(); - - const getNewId = (prevId: string) => { - const inMapValue = clonedIDsMap.get(prevId); - if (!inMapValue) { - const newId = generateId(); - clonedIDsMap.set(prevId, newId); - return newId; + }) + .addCase(setExecutionContext, (state, { payload }) => { + return { + ...state, + ...payload, + }; + }) + .addCase(initExisting, (state, { payload }) => { + return { + ...state, + ...payload, + }; + }) + .addCase(onActiveDataChange, (state, { payload: { activeData } }) => { + return { + ...state, + activeData, + }; + }) + .addCase(setSaveable, (state, { payload }) => { + return { + ...state, + isSaveable: payload, + }; + }) + .addCase(enableAutoApply, (state) => { + state.autoApplyDisabled = false; + }) + .addCase(disableAutoApply, (state) => { + state.autoApplyDisabled = true; + state.changesApplied = true; + }) + .addCase(applyChanges, (state) => { + if (typeof state.applyChangesCounter === 'undefined') { + state.applyChangesCounter = 0; } - return inMapValue; - }; + state.applyChangesCounter++; + }) + .addCase(setChangesApplied, (state, { payload: applied }) => { + state.changesApplied = applied; + }) + .addCase(cloneLayer, (state, { payload: { layerId, newLayerId } }) => { + const clonedIDsMap = new Map(); + + const getNewId = (prevId: string) => { + const inMapValue = clonedIDsMap.get(prevId); + if (!inMapValue) { + const newId = generateId(); + clonedIDsMap.set(prevId, newId); + return newId; + } + return inMapValue; + }; - if (!state.activeDatasourceId || !state.visualization.activeId) { - return state; - } + if (!state.activeDatasourceId || !state.visualization.activeId) { + return state; + } - state.datasourceStates = mapValues(state.datasourceStates, (datasourceState, datasourceId) => - datasourceId - ? { - ...datasourceState, - state: datasourceMap[datasourceId].cloneLayer( - datasourceState.state, - layerId, - newLayerId, - getNewId - ), - } - : datasourceState - ); - state.visualization.state = visualizationMap[state.visualization.activeId].cloneLayer!( - state.visualization.state, - layerId, - newLayerId, - clonedIDsMap - ); - }, - [removeOrClearLayer.type]: ( - state, - { - payload: { visualizationId, layerId, layerIds }, - }: { - payload: { - visualizationId: string; - layerId: string; - layerIds: string[]; - }; - } - ) => { - const activeVisualization = visualizationMap[visualizationId]; - const activeDataSource = datasourceMap[state.activeDatasourceId!]; - const isOnlyLayer = - getRemoveOperation( - activeVisualization, + state.datasourceStates = mapValues( + state.datasourceStates, + (datasourceState, datasourceId) => + datasourceId + ? { + ...datasourceState, + state: datasourceMap[datasourceId].cloneLayer( + datasourceState.state, + layerId, + newLayerId, + getNewId + ), + } + : datasourceState + ); + state.visualization.state = visualizationMap[state.visualization.activeId].cloneLayer!( state.visualization.state, layerId, - layerIds.length - ) === 'clear'; + newLayerId, + clonedIDsMap + ); + }) + .addCase(removeOrClearLayer, (state, { payload: { visualizationId, layerId, layerIds } }) => { + const activeVisualization = visualizationMap[visualizationId]; + const activeDataSource = datasourceMap[state.activeDatasourceId!]; + const isOnlyLayer = + getRemoveOperation( + activeVisualization, + state.visualization.state, + layerId, + layerIds.length + ) === 'clear'; - let removedLayerIds: string[] = []; + let removedLayerIds: string[] = []; - state.datasourceStates = mapValues( - state.datasourceStates, - (datasourceState, datasourceId) => { - const datasource = datasourceMap[datasourceId!]; + state.datasourceStates = mapValues( + state.datasourceStates, + (datasourceState, datasourceId) => { + const datasource = datasourceMap[datasourceId!]; - const { newState, removedLayerIds: removedLayerIdsForThisDatasource } = isOnlyLayer - ? datasource.clearLayer(datasourceState.state, layerId) - : datasource.removeLayer(datasourceState.state, layerId); + const { newState, removedLayerIds: removedLayerIdsForThisDatasource } = isOnlyLayer + ? datasource.clearLayer(datasourceState.state, layerId) + : datasource.removeLayer(datasourceState.state, layerId); - removedLayerIds = [...removedLayerIds, ...removedLayerIdsForThisDatasource]; + removedLayerIds = [...removedLayerIds, ...removedLayerIdsForThisDatasource]; - return { - ...datasourceState, - ...(datasourceId === state.activeDatasourceId && { - state: newState, - }), - }; - } - ); - state.stagedPreview = undefined; - // reuse the activeDatasource current dataView id for the moment - const currentDataViewsId = activeDataSource.getUsedDataView( - state.datasourceStates[state.activeDatasourceId!].state - ); - - if (isOnlyLayer || !activeVisualization.removeLayer) { - state.visualization.state = activeVisualization.clearLayer( - state.visualization.state, - layerId, - currentDataViewsId + return { + ...datasourceState, + ...(datasourceId === state.activeDatasourceId && { + state: newState, + }), + }; + } + ); + state.stagedPreview = undefined; + // reuse the activeDatasource current dataView id for the moment + const currentDataViewsId = activeDataSource.getUsedDataView( + state.datasourceStates[state.activeDatasourceId!].state ); - } - uniq(removedLayerIds).forEach( - (removedId) => - (state.visualization.state = activeVisualization.removeLayer?.( + if (isOnlyLayer || !activeVisualization.removeLayer) { + state.visualization.state = activeVisualization.clearLayer( state.visualization.state, - removedId - )) - ); - }, - [changeIndexPattern.type]: ( - state, - { - payload, - }: { - payload: { - visualizationIds?: string; - datasourceIds?: string; - layerId?: string; - indexPatternId: string; - dataViews: Pick; - }; - } - ) => { - const { visualizationIds, datasourceIds, layerId, indexPatternId, dataViews } = payload; - const newIndexPatternRefs = [...state.dataViews.indexPatternRefs]; - const availableRefs = new Set(newIndexPatternRefs.map((ref) => ref.id)); - // check for missing refs - Object.values(dataViews.indexPatterns || {}).forEach((indexPattern) => { - if (!availableRefs.has(indexPattern.id)) { - newIndexPatternRefs.push({ - id: indexPattern.id!, - name: indexPattern.name, - title: indexPattern.title, - }); - } - }); - const newState: Partial = { - dataViews: { - ...state.dataViews, - indexPatterns: dataViews.indexPatterns, - indexPatternRefs: newIndexPatternRefs, - }, - }; - if (visualizationIds?.length) { - for (const visualizationId of visualizationIds) { - const activeVisualization = - visualizationId && - state.visualization.activeId === visualizationId && - visualizationMap[visualizationId]; - if (activeVisualization && layerId && activeVisualization?.onIndexPatternChange) { - newState.visualization = { - ...state.visualization, - state: activeVisualization.onIndexPatternChange( - state.visualization.state, - indexPatternId, - layerId - ), - }; - } + layerId, + currentDataViewsId + ); } - } - if (datasourceIds?.length) { - newState.datasourceStates = { ...state.datasourceStates }; - const frame = selectFramePublicAPI( - { lens: { ...current(state), dataViews: newState.dataViews! } }, - datasourceMap - ); - const datasourceLayers = frame.datasourceLayers; - for (const datasourceId of datasourceIds) { - const activeDatasource = datasourceId && datasourceMap[datasourceId]; - if (activeDatasource && activeDatasource?.onIndexPatternChange) { - newState.datasourceStates = { - ...newState.datasourceStates, - [datasourceId]: { - isLoading: false, - state: activeDatasource.onIndexPatternChange( - newState.datasourceStates[datasourceId].state, - dataViews.indexPatterns, + uniq(removedLayerIds).forEach( + (removedId) => + (state.visualization.state = activeVisualization.removeLayer?.( + state.visualization.state, + removedId + )) + ); + }) + .addCase(changeIndexPattern, (state, { payload }) => { + const { visualizationIds, datasourceIds, layerId, indexPatternId, dataViews } = payload; + if (!dataViews.indexPatterns) { + throw new Error('Invariant: indexPatterns should be defined'); + } + const newIndexPatternRefs = [...state.dataViews.indexPatternRefs]; + const availableRefs = new Set(newIndexPatternRefs.map((ref) => ref.id)); + // check for missing refs + Object.values(dataViews.indexPatterns || {}).forEach((indexPattern) => { + if (!availableRefs.has(indexPattern.id)) { + newIndexPatternRefs.push({ + id: indexPattern.id!, + name: indexPattern.name, + title: indexPattern.title, + }); + } + }); + const newState: Partial = { + dataViews: { + ...state.dataViews, + indexPatterns: dataViews.indexPatterns, + indexPatternRefs: newIndexPatternRefs, + }, + }; + if (visualizationIds?.length) { + for (const visualizationId of visualizationIds) { + const activeVisualization = + visualizationId && + state.visualization.activeId === visualizationId && + visualizationMap[visualizationId]; + if (activeVisualization && layerId && activeVisualization?.onIndexPatternChange) { + newState.visualization = { + ...state.visualization, + state: activeVisualization.onIndexPatternChange( + state.visualization.state, indexPatternId, layerId ), - }, - }; - // Update the visualization columns - if (layerId && state.visualization.activeId) { - const nextPublicAPI = activeDatasource.getPublicAPI({ - state: newState.datasourceStates[datasourceId].state, - layerId, - indexPatterns: dataViews.indexPatterns, - }); - const nextTable = new Set( - nextPublicAPI.getTableSpec().map(({ columnId }) => columnId) - ); - const datasourcePublicAPI = datasourceLayers[layerId]; - if (datasourcePublicAPI) { - const removed = datasourcePublicAPI - .getTableSpec() - .map(({ columnId }) => columnId) - .filter((columnId) => !nextTable.has(columnId)); - const activeVisualization = visualizationMap[state.visualization.activeId]; - let nextVisState = (newState.visualization || state.visualization).state; - removed.forEach((columnId) => { - nextVisState = activeVisualization.removeDimension({ - layerId, - columnId, - prevState: nextVisState, - frame, - }); + }; + } + } + } + if (datasourceIds?.length) { + newState.datasourceStates = { ...state.datasourceStates }; + const frame = selectFramePublicAPI( + { lens: { ...current(state), dataViews: newState.dataViews! } }, + datasourceMap + ); + const datasourceLayers = frame.datasourceLayers; + + for (const datasourceId of datasourceIds) { + const activeDatasource = datasourceId && datasourceMap[datasourceId]; + if (activeDatasource && activeDatasource?.onIndexPatternChange) { + newState.datasourceStates = { + ...newState.datasourceStates, + [datasourceId]: { + isLoading: false, + state: activeDatasource.onIndexPatternChange( + newState.datasourceStates[datasourceId].state, + dataViews.indexPatterns, + indexPatternId, + layerId + ), + }, + }; + // Update the visualization columns + if (layerId && state.visualization.activeId) { + const nextPublicAPI = activeDatasource.getPublicAPI({ + state: newState.datasourceStates[datasourceId].state, + layerId, + indexPatterns: dataViews.indexPatterns, }); - newState.visualization = { - ...state.visualization, - state: nextVisState, - }; + const nextTable = new Set( + nextPublicAPI.getTableSpec().map(({ columnId }) => columnId) + ); + const datasourcePublicAPI = datasourceLayers[layerId]; + if (datasourcePublicAPI) { + const removed = datasourcePublicAPI + .getTableSpec() + .map(({ columnId }) => columnId) + .filter((columnId) => !nextTable.has(columnId)); + const activeVisualization = visualizationMap[state.visualization.activeId]; + let nextVisState = (newState.visualization || state.visualization).state; + removed.forEach((columnId) => { + nextVisState = activeVisualization.removeDimension({ + layerId, + columnId, + prevState: nextVisState, + frame, + }); + }); + newState.visualization = { + ...state.visualization, + state: nextVisState, + }; + } } } } } - } - return { ...state, ...newState }; - }, - [updateIndexPatterns.type]: (state, { payload }: { payload: Partial }) => { - return { - ...state, - dataViews: { ...state.dataViews, ...payload }, - }; - }, - [replaceIndexpattern.type]: ( - state, - { payload }: { payload: { newIndexPattern: IndexPattern; oldId: string } } - ) => { - state.dataViews.indexPatterns[payload.newIndexPattern.id] = payload.newIndexPattern; - delete state.dataViews.indexPatterns[payload.oldId]; - state.dataViews.indexPatternRefs = state.dataViews.indexPatternRefs.filter( - (r) => r.id !== payload.oldId - ); - state.dataViews.indexPatternRefs.push({ - id: payload.newIndexPattern.id, - title: payload.newIndexPattern.title, - name: payload.newIndexPattern.name, - }); - const visualization = visualizationMap[state.visualization.activeId!]; - state.visualization.state = - visualization.onIndexPatternRename?.( - state.visualization.state, - payload.oldId, - payload.newIndexPattern.id - ) ?? state.visualization.state; - - Object.entries(state.datasourceStates).forEach(([datasourceId, datasourceState]) => { - const datasource = datasourceMap[datasourceId]; - state.datasourceStates[datasourceId].state = - datasource?.onIndexPatternRename?.( - datasourceState.state, - payload.oldId, - payload.newIndexPattern.id! - ) ?? datasourceState.state; - }); - }, - [updateDatasourceState.type]: ( - state, - { - payload, - }: { - payload: { - newDatasourceState: unknown; - datasourceId: string; - clearStagedPreview?: boolean; - dontSyncLinkedDimensions: boolean; + return { ...state, ...newState }; + }) + .addCase(updateIndexPatterns, (state, { payload }) => { + return { + ...state, + dataViews: { ...state.dataViews, ...payload }, }; - } - ) => { - if (payload.clearStagedPreview) { - state.stagedPreview = undefined; - } + }) + .addCase(replaceIndexpattern, (state, { payload }) => { + state.dataViews.indexPatterns[payload.newIndexPattern.id] = payload.newIndexPattern; + delete state.dataViews.indexPatterns[payload.oldId]; + state.dataViews.indexPatternRefs = state.dataViews.indexPatternRefs.filter( + (r) => r.id !== payload.oldId + ); + state.dataViews.indexPatternRefs.push({ + id: payload.newIndexPattern.id, + title: payload.newIndexPattern.title, + name: payload.newIndexPattern.name, + }); + const visualization = visualizationMap[state.visualization.activeId!]; + state.visualization.state = + visualization.onIndexPatternRename?.( + state.visualization.state, + payload.oldId, + payload.newIndexPattern.id + ) ?? state.visualization.state; + + Object.entries(state.datasourceStates).forEach(([datasourceId, datasourceState]) => { + const datasource = datasourceMap[datasourceId]; + state.datasourceStates[datasourceId].state = + datasource?.onIndexPatternRename?.( + datasourceState.state, + payload.oldId, + payload.newIndexPattern.id! + ) ?? datasourceState.state; + }); + }) + .addCase(updateDatasourceState, (state, { payload }) => { + if (payload.clearStagedPreview) { + state.stagedPreview = undefined; + } - state.datasourceStates[payload.datasourceId] = { - state: payload.newDatasourceState, - isLoading: false, - }; + state.datasourceStates[payload.datasourceId] = { + state: payload.newDatasourceState, + isLoading: false, + }; - if (payload.dontSyncLinkedDimensions) { - return; - } + if (payload.dontSyncLinkedDimensions) { + return; + } - const currentState = current(state); + const currentState = current(state); - const { - datasourceState: syncedDatasourceState, - visualizationState: syncedVisualizationState, - } = syncLinkedDimensions(currentState, visualizationMap, datasourceMap, payload.datasourceId); + const { + datasourceState: syncedDatasourceState, + visualizationState: syncedVisualizationState, + } = syncLinkedDimensions( + currentState, + visualizationMap, + datasourceMap, + payload.datasourceId + ); - state.visualization.state = syncedVisualizationState; - state.datasourceStates[payload.datasourceId].state = syncedDatasourceState; - }, - [updateVisualizationState.type]: ( - state, - { - payload, - }: { - payload: { - visualizationId: string; - newState: unknown; - dontSyncLinkedDimensions?: boolean; - }; - } - ) => { - if (!state.visualization.activeId) { - throw new Error('Invariant: visualization state got updated without active visualization'); - } - // This is a safeguard that prevents us from accidentally updating the - // wrong visualization. This occurs in some cases due to the uncoordinated - // way we manage state across plugins. - if (state.visualization.activeId !== payload.visualizationId) { - return state; - } + state.visualization.state = syncedVisualizationState; + state.datasourceStates[payload.datasourceId].state = syncedDatasourceState; + }) + .addCase(updateVisualizationState, (state, { payload }) => { + if (!state.visualization.activeId) { + throw new Error( + 'Invariant: visualization state got updated without active visualization' + ); + } + // This is a safeguard that prevents us from accidentally updating the + // wrong visualization. This occurs in some cases due to the uncoordinated + // way we manage state across plugins. + if (state.visualization.activeId !== payload.visualizationId) { + return state; + } - state.visualization.state = payload.newState; + state.visualization.state = payload.newState; - if (!state.activeDatasourceId) { - return; - } + if (!state.activeDatasourceId) { + return; + } - if (payload.dontSyncLinkedDimensions) { - return; - } + if (payload.dontSyncLinkedDimensions) { + return; + } - // TODO - consolidate into applySyncLinkedDimensions - const { - datasourceState: syncedDatasourceState, - visualizationState: syncedVisualizationState, - } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); + // TODO - consolidate into applySyncLinkedDimensions + const { + datasourceState: syncedDatasourceState, + visualizationState: syncedVisualizationState, + } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); - state.datasourceStates[state.activeDatasourceId].state = syncedDatasourceState; - state.visualization.state = syncedVisualizationState; - }, + state.datasourceStates[state.activeDatasourceId].state = syncedDatasourceState; + state.visualization.state = syncedVisualizationState; + }) - [switchVisualization.type]: ( - state, - { - payload, - }: { - payload: { - suggestion: { - newVisualizationId: string; - visualizationState: unknown; - datasourceState?: unknown; - datasourceId?: string; - }; - clearStagedPreview?: boolean; - }; - } - ) => { - const { newVisualizationId, visualizationState, datasourceState, datasourceId } = - payload.suggestion; - return { - ...state, - datasourceStates: datasourceId - ? { - ...state.datasourceStates, - [datasourceId]: { - ...state.datasourceStates[datasourceId], - state: datasourceState, + .addCase(switchVisualization, (state, { payload }) => { + const { newVisualizationId, visualizationState, datasourceState, datasourceId } = + payload.suggestion; + return { + ...state, + datasourceStates: datasourceId + ? { + ...state.datasourceStates, + [datasourceId]: { + ...state.datasourceStates[datasourceId], + state: datasourceState, + }, + } + : state.datasourceStates, + visualization: { + ...state.visualization, + activeId: newVisualizationId, + state: visualizationState, + }, + stagedPreview: payload.clearStagedPreview + ? undefined + : state.stagedPreview || { + datasourceStates: state.datasourceStates, + visualization: state.visualization, + activeData: state.activeData, }, - } - : state.datasourceStates, - visualization: { - ...state.visualization, - activeId: newVisualizationId, - state: visualizationState, - }, - stagedPreview: payload.clearStagedPreview - ? undefined - : state.stagedPreview || { - datasourceStates: state.datasourceStates, - visualization: state.visualization, - activeData: state.activeData, - }, - }; - }, - [rollbackSuggestion.type]: (state) => { - return { - ...state, - ...(state.stagedPreview || {}), - stagedPreview: undefined, - }; - }, - [setToggleFullscreen.type]: (state) => { - return { ...state, isFullscreenDatasource: !state.isFullscreenDatasource }; - }, - [submitSuggestion.type]: (state) => { - return { - ...state, - stagedPreview: undefined, - }; - }, - [switchDatasource.type]: ( - state, - { - payload, - }: { - payload: { - newDatasourceId: string; }; - } - ) => { - return { - ...state, - datasourceStates: { - ...state.datasourceStates, - [payload.newDatasourceId]: state.datasourceStates[payload.newDatasourceId] || { - state: null, - isLoading: true, + }) + .addCase(rollbackSuggestion, (state) => { + return { + ...state, + ...(state.stagedPreview || {}), + stagedPreview: undefined, + }; + }) + .addCase(setToggleFullscreen, (state) => { + return { ...state, isFullscreenDatasource: !state.isFullscreenDatasource }; + }) + .addCase(submitSuggestion, (state) => { + return { + ...state, + stagedPreview: undefined, + }; + }) + .addCase(switchDatasource, (state, { payload }) => { + return { + ...state, + datasourceStates: { + ...state.datasourceStates, + [payload.newDatasourceId]: state.datasourceStates[payload.newDatasourceId] || { + state: null, + isLoading: true, + }, }, - }, - activeDatasourceId: payload.newDatasourceId, - }; - }, - [switchAndCleanDatasource.type]: ( - state, - { - payload, - }: { - payload: { - newDatasourceId: string; - visualizationId?: string; - currentIndexPatternId?: string; + activeDatasourceId: payload.newDatasourceId, }; - } - ) => { - const activeVisualization = - payload.visualizationId && visualizationMap[payload.visualizationId]; - const visualization = state.visualization; - let newVizState = visualization.state; - const ids: string[] = []; - if (activeVisualization && activeVisualization.getLayerIds) { - const layerIds = activeVisualization.getLayerIds(visualization.state); - ids.push(...Object.values(layerIds)); - newVizState = activeVisualization.initialize(() => ids[0]); - } - const currentVizId = ids[0]; + }) + .addCase(switchAndCleanDatasource, (state, { payload }) => { + const activeVisualization = + payload.visualizationId && visualizationMap[payload.visualizationId]; + const visualization = state.visualization; + let newVizState = visualization.state; + const ids: string[] = []; + if (activeVisualization && activeVisualization.getLayerIds) { + const layerIds = activeVisualization.getLayerIds(visualization.state); + ids.push(...Object.values(layerIds)); + newVizState = activeVisualization.initialize(() => ids[0]); + } + const currentVizId = ids[0]; - const datasourceState = current(state).datasourceStates[payload.newDatasourceId] - ? current(state).datasourceStates[payload.newDatasourceId]?.state - : datasourceMap[payload.newDatasourceId].createEmptyLayer( - payload.currentIndexPatternId ?? '' - ); - const updatedState = datasourceMap[payload.newDatasourceId].insertLayer( - datasourceState, - currentVizId - ); + const datasourceState = current(state).datasourceStates[payload.newDatasourceId] + ? current(state).datasourceStates[payload.newDatasourceId]?.state + : datasourceMap[payload.newDatasourceId].createEmptyLayer( + payload.currentIndexPatternId ?? '' + ); + const updatedState = datasourceMap[payload.newDatasourceId].insertLayer( + datasourceState, + currentVizId + ); - return { - ...state, - datasourceStates: { - [payload.newDatasourceId]: { - state: updatedState, - isLoading: false, - }, - }, - activeDatasourceId: payload.newDatasourceId, - visualization: { - ...visualization, - state: newVizState, - }, - }; - }, - [navigateAway.type]: (state) => state, - [loadInitial.type]: ( - state, - payload: PayloadAction<{ - initialInput?: LensEmbeddableInput; - redirectCallback?: (savedObjectId?: string) => void; - history?: History; - inlineEditing?: boolean; - }> - ) => state, - [initEmpty.type]: ( - state, - { - payload, - }: { - payload: { - newState: Partial; - initialContext: VisualizeFieldContext | VisualizeEditorContext | undefined; - layerId: string; - }; - } - ) => { - const newState = { - ...state, - ...payload.newState, - }; - const suggestion: Suggestion | undefined = getVisualizeFieldSuggestions({ - datasourceMap, - datasourceStates: newState.datasourceStates, - visualizationMap, - visualizeTriggerFieldContext: payload.initialContext, - dataViews: newState.dataViews, - }); - if (suggestion) { return { - ...newState, + ...state, datasourceStates: { - ...newState.datasourceStates, - [suggestion.datasourceId!]: { - ...newState.datasourceStates[suggestion.datasourceId!], - state: suggestion.datasourceState, + [payload.newDatasourceId]: { + state: updatedState, + isLoading: false, }, }, + activeDatasourceId: payload.newDatasourceId, visualization: { - ...newState.visualization, - activeId: suggestion.visualizationId, - state: suggestion.visualizationState, + ...visualization, + state: newVizState, }, - stagedPreview: undefined, }; - } + }) + .addCase(navigateAway, (state) => state) + .addCase(loadInitial, (state, payload) => state) + .addCase(initEmpty, (state, { payload }) => { + const newState = { + ...state, + ...payload.newState, + }; + const suggestion: Suggestion | undefined = getVisualizeFieldSuggestions({ + datasourceMap, + datasourceStates: newState.datasourceStates, + visualizationMap, + visualizeTriggerFieldContext: payload.initialContext, + dataViews: newState.dataViews, + }); + if (suggestion) { + return { + ...newState, + datasourceStates: { + ...newState.datasourceStates, + [suggestion.datasourceId!]: { + ...newState.datasourceStates[suggestion.datasourceId!], + state: suggestion.datasourceState, + }, + }, + visualization: { + ...newState.visualization, + activeId: suggestion.visualizationId, + state: suggestion.visualizationState, + }, + stagedPreview: undefined, + }; + } - const visualization = newState.visualization; + const visualization = newState.visualization; - if (!visualization.activeId) { - throw new Error('Invariant: visualization state got updated without active visualization'); - } + if (!visualization.activeId) { + throw new Error( + 'Invariant: visualization state got updated without active visualization' + ); + } - const activeVisualization = visualizationMap[visualization.activeId]; - if (visualization.state === null && activeVisualization) { - const activeDatasourceId = getInitialDatasourceId(datasourceMap)!; - const newVisState = activeVisualization.initialize(() => payload.layerId); - const activeDatasource = datasourceMap[activeDatasourceId]; + const activeVisualization = visualizationMap[visualization.activeId]; + if (visualization.state === null && activeVisualization) { + const activeDatasourceId = getInitialDatasourceId(datasourceMap)!; + const newVisState = activeVisualization.initialize(() => payload.layerId); + const activeDatasource = datasourceMap[activeDatasourceId]; + return { + ...newState, + activeDatasourceId, + datasourceStates: { + ...newState.datasourceStates, + [activeDatasourceId]: { + ...newState.datasourceStates[activeDatasourceId], + state: activeDatasource.insertLayer( + newState.datasourceStates[activeDatasourceId]?.state, + payload.layerId + ), + }, + }, + visualization: { + ...visualization, + state: newVisState, + }, + }; + } + return newState; + }) + .addCase(editVisualizationAction, (state, { payload }) => { + if (!state.visualization.activeId) { + throw new Error( + 'Invariant: visualization state got updated without active visualization' + ); + } + // This is a safeguard that prevents us from accidentally updating the + // wrong visualization. This occurs in some cases due to the uncoordinated + // way we manage state across plugins. + if (state.visualization.activeId !== payload.visualizationId) { + return state; + } + const activeVisualization = visualizationMap[payload.visualizationId]; + if (activeVisualization?.onEditAction) { + state.visualization.state = activeVisualization.onEditAction( + state.visualization.state, + payload.event + ); + } + }) + .addCase(insertLayer, (state, { payload }) => { + const updater = datasourceMap[payload.datasourceId].insertLayer; return { - ...newState, - activeDatasourceId, + ...state, datasourceStates: { - ...newState.datasourceStates, - [activeDatasourceId]: { - ...newState.datasourceStates[activeDatasourceId], - state: activeDatasource.insertLayer( - newState.datasourceStates[activeDatasourceId]?.state, + ...state.datasourceStates, + [payload.datasourceId]: { + ...state.datasourceStates[payload.datasourceId], + state: updater( + current(state).datasourceStates[payload.datasourceId].state, payload.layerId ), }, }, - visualization: { - ...visualization, - state: newVisState, - }, - }; - } - return newState; - }, - [editVisualizationAction.type]: ( - state, - { - payload, - }: { - payload: { - visualizationId: string; - event: LensEditEvent; }; - } - ) => { - if (!state.visualization.activeId) { - throw new Error('Invariant: visualization state got updated without active visualization'); - } - // This is a safeguard that prevents us from accidentally updating the - // wrong visualization. This occurs in some cases due to the uncoordinated - // way we manage state across plugins. - if (state.visualization.activeId !== payload.visualizationId) { - return state; - } - const activeVisualization = visualizationMap[payload.visualizationId]; - if (activeVisualization?.onEditAction) { - state.visualization.state = activeVisualization.onEditAction( - state.visualization.state, - payload.event - ); - } - }, - [insertLayer.type]: ( - state, - { - payload, - }: { - payload: { - layerId: string; - datasourceId: string; - }; - } - ) => { - const updater = datasourceMap[payload.datasourceId].insertLayer; - return { - ...state, - datasourceStates: { - ...state.datasourceStates, - [payload.datasourceId]: { - ...state.datasourceStates[payload.datasourceId], - state: updater( - current(state).datasourceStates[payload.datasourceId].state, - payload.layerId - ), - }, - }, - }; - }, - [removeLayers.type]: ( - state, - { - payload: { visualizationId, layerIds }, - }: { - payload: { - visualizationId: VisualizationState['activeId']; - layerIds: string[]; - }; - } - ) => { - if (!state.visualization.activeId) { - throw new Error('Invariant: visualization state got updated without active visualization'); - } - - const activeVisualization = visualizationId && visualizationMap[visualizationId]; - - // This is a safeguard that prevents us from accidentally updating the - // wrong visualization. This occurs in some cases due to the uncoordinated - // way we manage state across plugins. - if ( - state.visualization.activeId === visualizationId && - activeVisualization && - activeVisualization.removeLayer && - state.visualization.state - ) { - const updater = layerIds.reduce( - (acc, layerId) => - activeVisualization.removeLayer ? activeVisualization.removeLayer(acc, layerId) : acc, - state.visualization.state - ); + }) + .addCase(removeLayers, (state, { payload: { visualizationId, layerIds } }) => { + if (!state.visualization.activeId) { + throw new Error( + 'Invariant: visualization state got updated without active visualization' + ); + } - state.visualization.state = - typeof updater === 'function' ? updater(current(state.visualization.state)) : updater; - } + const activeVisualization = visualizationId && visualizationMap[visualizationId]; - layerIds.forEach((layerId) => { - const [layerDatasourceId] = - Object.entries(datasourceMap).find(([datasourceId, datasource]) => { - return ( - state.datasourceStates[datasourceId] && - datasource.getLayers(state.datasourceStates[datasourceId].state).includes(layerId) - ); - }) ?? []; - if (layerDatasourceId) { - const { newState } = datasourceMap[layerDatasourceId].removeLayer( - current(state).datasourceStates[layerDatasourceId].state, - layerId + // This is a safeguard that prevents us from accidentally updating the + // wrong visualization. This occurs in some cases due to the uncoordinated + // way we manage state across plugins. + if ( + state.visualization.activeId === visualizationId && + activeVisualization && + activeVisualization.removeLayer && + state.visualization.state + ) { + const updater = layerIds.reduce( + (acc, layerId) => + activeVisualization.removeLayer ? activeVisualization.removeLayer(acc, layerId) : acc, + state.visualization.state ); - state.datasourceStates[layerDatasourceId].state = newState; - // TODO - call removeLayer for any extra (linked) layers removed by the datasource - } - }); - }, - [addLayer.type]: ( - state, - { - payload: { layerId, layerType, extraArg, ignoreInitialValues }, - }: { - payload: { - layerId: string; - layerType: LayerType; - extraArg: unknown; - ignoreInitialValues: boolean; - }; - } - ) => { - if (!state.activeDatasourceId || !state.visualization.activeId) { - return state; - } + state.visualization.state = + typeof updater === 'function' ? updater(current(state.visualization.state)) : updater; + } - const activeVisualization = visualizationMap[state.visualization.activeId]; - const activeDatasource = datasourceMap[state.activeDatasourceId]; - // reuse the active datasource dataView id for the new layer - const currentDataViewsId = activeDatasource.getUsedDataView( - state.datasourceStates[state.activeDatasourceId!].state - ); - const visualizationState = activeVisualization.appendLayer!( - state.visualization.state, - layerId, - layerType, - currentDataViewsId, - extraArg - ); + layerIds.forEach((layerId) => { + const [layerDatasourceId] = + Object.entries(datasourceMap).find(([datasourceId, datasource]) => { + return ( + state.datasourceStates[datasourceId] && + datasource.getLayers(state.datasourceStates[datasourceId].state).includes(layerId) + ); + }) ?? []; + if (layerDatasourceId) { + const { newState } = datasourceMap[layerDatasourceId].removeLayer( + current(state).datasourceStates[layerDatasourceId].state, + layerId + ); + state.datasourceStates[layerDatasourceId].state = newState; + // TODO - call removeLayer for any extra (linked) layers removed by the datasource + } + }); + }) - const framePublicAPI = selectFramePublicAPI({ lens: current(state) }, datasourceMap); + .addCase( + addLayer, + (state, { payload: { layerId, layerType, extraArg, ignoreInitialValues } }) => { + if (!state.activeDatasourceId || !state.visualization.activeId) { + return state; + } - const { noDatasource } = - activeVisualization - .getSupportedLayers(visualizationState, framePublicAPI) - .find(({ type }) => type === layerType) || {}; - - const layersToLinkTo = - activeVisualization.getLayersToLinkTo?.(visualizationState, layerId) ?? []; - - const datasourceState = - !noDatasource && activeDatasource - ? activeDatasource.insertLayer( - state.datasourceStates[state.activeDatasourceId].state, - layerId, - layersToLinkTo - ) - : state.datasourceStates[state.activeDatasourceId].state; - - const { activeDatasourceState, activeVisualizationState } = ignoreInitialValues - ? { activeDatasourceState: datasourceState, activeVisualizationState: visualizationState } - : addInitialValueIfAvailable({ - datasourceState, - visualizationState, - framePublicAPI, - activeVisualization, - activeDatasource, + const activeVisualization = visualizationMap[state.visualization.activeId]; + const activeDatasource = datasourceMap[state.activeDatasourceId]; + // reuse the active datasource dataView id for the new layer + const currentDataViewsId = activeDatasource.getUsedDataView( + state.datasourceStates[state.activeDatasourceId!].state + ); + const visualizationState = activeVisualization.appendLayer!( + state.visualization.state, layerId, layerType, - }); + currentDataViewsId, + extraArg + ); - state.visualization.state = activeVisualizationState; - state.datasourceStates[state.activeDatasourceId].state = activeDatasourceState; - state.stagedPreview = undefined; + const framePublicAPI = selectFramePublicAPI({ lens: current(state) }, datasourceMap); + + const { noDatasource } = + activeVisualization + .getSupportedLayers(visualizationState, framePublicAPI) + .find(({ type }) => type === layerType) || {}; + + const layersToLinkTo = + activeVisualization.getLayersToLinkTo?.(visualizationState, layerId) ?? []; + + const datasourceState = + !noDatasource && activeDatasource + ? activeDatasource.insertLayer( + state.datasourceStates[state.activeDatasourceId].state, + layerId, + layersToLinkTo + ) + : state.datasourceStates[state.activeDatasourceId].state; + + const { activeDatasourceState, activeVisualizationState } = ignoreInitialValues + ? { + activeDatasourceState: datasourceState, + activeVisualizationState: visualizationState, + } + : addInitialValueIfAvailable({ + datasourceState, + visualizationState, + framePublicAPI, + activeVisualization, + activeDatasource, + layerId, + layerType, + }); - const { - datasourceState: syncedDatasourceState, - visualizationState: syncedVisualizationState, - } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); + state.visualization.state = activeVisualizationState; + state.datasourceStates[state.activeDatasourceId].state = activeDatasourceState; + state.stagedPreview = undefined; - state.datasourceStates[state.activeDatasourceId].state = syncedDatasourceState; - state.visualization.state = syncedVisualizationState; - }, - [onDropToDimension.type]: ( - state, - { - payload: { source, target, dropType }, - }: { - payload: { - source: DragDropIdentifier; - target: DragDropOperation; - dropType: DropType; - }; - } - ) => { - if (!state.visualization.activeId) { - return state; - } + const { + datasourceState: syncedDatasourceState, + visualizationState: syncedVisualizationState, + } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); - const activeVisualization = visualizationMap[state.visualization.activeId]; - const framePublicAPI = selectFramePublicAPI({ lens: current(state) }, datasourceMap); + state.datasourceStates[state.activeDatasourceId].state = syncedDatasourceState; + state.visualization.state = syncedVisualizationState; + } + ) + .addCase(onDropToDimension, (state, { payload: { source, target, dropType } }) => { + if (!state.visualization.activeId) { + return state; + } - const { groups } = activeVisualization.getConfiguration({ - layerId: target.layerId, - frame: framePublicAPI, - state: state.visualization.state, - }); + const activeVisualization = visualizationMap[state.visualization.activeId]; + const framePublicAPI = selectFramePublicAPI({ lens: current(state) }, datasourceMap); - const [layerDatasourceId, layerDatasource] = - Object.entries(datasourceMap).find( - ([datasourceId, datasource]) => - state.datasourceStates[datasourceId] && - datasource - .getLayers(state.datasourceStates[datasourceId].state) - .includes(target.layerId) - ) || []; - - let newDatasourceState; - - if (layerDatasource && layerDatasourceId) { - newDatasourceState = layerDatasource?.onDrop({ - state: state.datasourceStates[layerDatasourceId].state, - source, - target: { - ...(target as unknown as DragDropOperation), - filterOperations: - groups.find(({ groupId: gId }) => gId === target.groupId)?.filterOperations || - Boolean, - }, - targetLayerDimensionGroups: groups, - dropType, - indexPatterns: framePublicAPI.dataViews.indexPatterns, + const { groups } = activeVisualization.getConfiguration({ + layerId: target.layerId, + frame: framePublicAPI, + state: state.visualization.state, }); - if (!newDatasourceState) { - return; + + const [layerDatasourceId, layerDatasource] = + Object.entries(datasourceMap).find( + ([datasourceId, datasource]) => + state.datasourceStates[datasourceId] && + datasource + .getLayers(state.datasourceStates[datasourceId].state) + .includes(target.layerId) + ) || []; + + let newDatasourceState; + + if (layerDatasource && layerDatasourceId) { + newDatasourceState = layerDatasource?.onDrop({ + state: state.datasourceStates[layerDatasourceId].state, + source, + target: { + ...(target as unknown as DragDropOperation), + filterOperations: + groups.find(({ groupId: gId }) => gId === target.groupId)?.filterOperations || + Boolean, + }, + targetLayerDimensionGroups: groups, + dropType, + indexPatterns: framePublicAPI.dataViews.indexPatterns, + }); + if (!newDatasourceState) { + return; + } + state.datasourceStates[layerDatasourceId].state = newDatasourceState; } - state.datasourceStates[layerDatasourceId].state = newDatasourceState; - } - activeVisualization.onDrop = activeVisualization.onDrop?.bind(activeVisualization); - const newVisualizationState = (activeVisualization.onDrop || onDropForVisualization)?.( - { - prevState: state.visualization.state, - frame: framePublicAPI, - target, - source, - dropType, - group: groups.find(({ groupId: gId }) => gId === target.groupId), - }, - activeVisualization - ); - state.visualization.state = newVisualizationState; + activeVisualization.onDrop = activeVisualization.onDrop?.bind(activeVisualization); + const newVisualizationState = (activeVisualization.onDrop || onDropForVisualization)?.( + { + prevState: state.visualization.state, + frame: framePublicAPI, + target, + source, + dropType, + group: groups.find(({ groupId: gId }) => gId === target.groupId), + }, + activeVisualization + ); + state.visualization.state = newVisualizationState; - if (layerDatasourceId) { - const { - datasourceState: syncedDatasourceState, - visualizationState: syncedVisualizationState, - } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); + if (layerDatasourceId) { + const { + datasourceState: syncedDatasourceState, + visualizationState: syncedVisualizationState, + } = syncLinkedDimensions(current(state), visualizationMap, datasourceMap); - state.datasourceStates[layerDatasourceId].state = syncedDatasourceState; - state.visualization.state = syncedVisualizationState; - } - state.stagedPreview = undefined; - }, - [setLayerDefaultDimension.type]: ( - state, - { - payload: { layerId, columnId, groupId }, - }: { - payload: { - layerId: string; - columnId: string; - groupId: string; - }; - } - ) => { - if (!state.activeDatasourceId || !state.visualization.activeId) { - return state; - } + state.datasourceStates[layerDatasourceId].state = syncedDatasourceState; + state.visualization.state = syncedVisualizationState; + } + state.stagedPreview = undefined; + }) + .addCase(setLayerDefaultDimension, (state, { payload: { layerId, columnId, groupId } }) => { + if (!state.activeDatasourceId || !state.visualization.activeId) { + return state; + } - const activeDatasource = datasourceMap[state.activeDatasourceId]; - const activeVisualization = visualizationMap[state.visualization.activeId]; - const layerType = - activeVisualization.getLayerType(layerId, state.visualization.state) || LayerTypes.DATA; - const { activeDatasourceState, activeVisualizationState } = addInitialValueIfAvailable({ - datasourceState: state.datasourceStates[state.activeDatasourceId].state, - visualizationState: state.visualization.state, - framePublicAPI: selectFramePublicAPI({ lens: current(state) }, datasourceMap), - activeVisualization, - activeDatasource, - layerId, - layerType, - columnId, - groupId, - }); + const activeDatasource = datasourceMap[state.activeDatasourceId]; + const activeVisualization = visualizationMap[state.visualization.activeId]; + const layerType = + activeVisualization.getLayerType(layerId, state.visualization.state) || LayerTypes.DATA; + const { activeDatasourceState, activeVisualizationState } = addInitialValueIfAvailable({ + datasourceState: state.datasourceStates[state.activeDatasourceId].state, + visualizationState: state.visualization.state, + framePublicAPI: selectFramePublicAPI({ lens: current(state) }, datasourceMap), + activeVisualization, + activeDatasource, + layerId, + layerType, + columnId, + groupId, + }); - state.visualization.state = activeVisualizationState; - state.datasourceStates[state.activeDatasourceId].state = activeDatasourceState; - }, - [removeDimension.type]: ( - state, - { - payload: { layerId, columnId, datasourceId }, - }: { - payload: { - layerId: string; - columnId: string; - datasourceId?: string; - }; - } - ) => { - if (!state.visualization.activeId) { - return state; - } + state.visualization.state = activeVisualizationState; + state.datasourceStates[state.activeDatasourceId].state = activeDatasourceState; + }) + .addCase(removeDimension, (state, { payload: { layerId, columnId, datasourceId } }) => { + if (!state.visualization.activeId) { + return state; + } - const activeVisualization = visualizationMap[state.visualization.activeId]; + const activeVisualization = visualizationMap[state.visualization.activeId]; - const links = activeVisualization.getLinkedDimensions?.(state.visualization.state); + const links = activeVisualization.getLinkedDimensions?.(state.visualization.state); - const linkedDimensions = links - ?.filter(({ from: { columnId: fromId } }) => columnId === fromId) - ?.map(({ to }) => to); + const linkedDimensions = links + ?.filter(({ from: { columnId: fromId } }) => columnId === fromId) + ?.map(({ to }) => to); - const datasource = datasourceId ? datasourceMap[datasourceId] : undefined; + const datasource = datasourceId ? datasourceMap[datasourceId] : undefined; - const frame = selectFramePublicAPI({ lens: current(state) }, datasourceMap); + const frame = selectFramePublicAPI({ lens: current(state) }, datasourceMap); - const remove = (dimensionProps: { layerId: string; columnId: string }) => { - if (datasource && datasourceId) { - let datasourceState; + const remove = (dimensionProps: { layerId: string; columnId: string }) => { + if (datasource && datasourceId) { + let datasourceState; + try { + datasourceState = current(state.datasourceStates[datasourceId].state); + } catch { + datasourceState = state.datasourceStates[datasourceId].state; + } + state.datasourceStates[datasourceId].state = datasource?.removeColumn({ + layerId: dimensionProps.layerId, + columnId: dimensionProps.columnId, + prevState: datasourceState, + indexPatterns: frame.dataViews.indexPatterns, + }); + } + + let visualizationState; try { - datasourceState = current(state.datasourceStates[datasourceId].state); + visualizationState = current(state.visualization.state); } catch { - datasourceState = state.datasourceStates[datasourceId].state; + visualizationState = state.visualization.state; } - state.datasourceStates[datasourceId].state = datasource?.removeColumn({ + state.visualization.state = activeVisualization.removeDimension({ layerId: dimensionProps.layerId, columnId: dimensionProps.columnId, - prevState: datasourceState, - indexPatterns: frame.dataViews.indexPatterns, + prevState: visualizationState, + frame, }); - } - - let visualizationState; - try { - visualizationState = current(state.visualization.state); - } catch { - visualizationState = state.visualization.state; - } - state.visualization.state = activeVisualization.removeDimension({ - layerId: dimensionProps.layerId, - columnId: dimensionProps.columnId, - prevState: visualizationState, - frame, - }); - }; + }; - remove({ layerId, columnId }); + remove({ layerId, columnId }); - linkedDimensions?.forEach( - (linkedDimension) => - linkedDimension.columnId && // if there's no columnId, there's no dimension to remove - remove({ columnId: linkedDimension.columnId, layerId: linkedDimension.layerId }) - ); - }, - [registerLibraryAnnotationGroup.type]: ( - state, - { - payload: { group, id }, - }: { - payload: { group: EventAnnotationGroupConfig; id: string }; - } - ) => { - state.annotationGroups[id] = group; - }, + linkedDimensions?.forEach( + (linkedDimension) => + linkedDimension.columnId && // if there's no columnId, there's no dimension to remove + remove({ columnId: linkedDimension.columnId, layerId: linkedDimension.layerId }) + ); + }) + .addCase(registerLibraryAnnotationGroup, (state, { payload: { group, id } }) => { + state.annotationGroups[id] = group; + }) + .addDefaultCase((state) => state); }); }; From baa80de3d8ec4996d25e57096401e11899e2e428 Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:56:43 +0100 Subject: [PATCH 012/104] [Lens] Fixes dimension button on configuration panel palette is not cleaned up on changing to unsupported operation type (#175912) Fixes https://github.com/elastic/kibana/issues/174747 This is one of the type of bugs we get quite often and I think we reached a moment we should holistically rethink how we could validate the state of the visualization when we update datasource state. I'll be taking a look at that, but here's some adhoc fix! --- .../datatable/visualization.test.tsx | 71 ++++++++++++++++++- .../datatable/visualization.tsx | 9 ++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx index dda07ef2c41c8..963e471e912f7 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx @@ -7,7 +7,13 @@ import { Ast } from '@kbn/interpreter'; import { buildExpression } from '@kbn/expressions-plugin/public'; -import { createMockDatasource, createMockFramePublicAPI, DatasourceMock } from '../../mocks'; +import { + createMockDatasource, + createMockFramePublicAPI, + DatasourceMock, + generateActiveData, +} from '../../mocks'; +import faker from 'faker'; import { DatatableVisualizationState, getDatatableVisualization } from './visualization'; import { Operation, @@ -15,6 +21,7 @@ import { FramePublicAPI, TableSuggestionColumn, VisualizationDimensionGroupConfig, + VisualizationConfigProps, } from '../../types'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; @@ -408,6 +415,68 @@ describe('Datatable Visualization', () => { ).toEqual([{ columnId: 'c' }, { columnId: 'b' }]); }); + describe('with palette', () => { + let params: VisualizationConfigProps; + beforeEach(() => { + const datasource = createMockDatasource('test'); + datasource.publicAPIMock.getTableSpec.mockReturnValue([{ columnId: 'b', fields: [] }]); + params = { + layerId: 'a', + state: { + layerId: 'a', + layerType: LayerTypes.DATA, + columns: [ + { + columnId: 'b', + palette: { + type: 'palette' as const, + name: '', + params: { stops: [{ color: 'blue', stop: 0 }] }, + }, + }, + ], + }, + frame: { + ...mockFrame(), + activeData: generateActiveData([ + { + id: 'a', + rows: Array(3).fill({ + b: faker.random.number(), + }), + }, + ]), + datasourceLayers: { a: datasource.publicAPIMock }, + }, + }; + }); + + it('does include palette for accessor config if the values are numeric and palette exists', () => { + expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([ + { columnId: 'b', palette: ['blue'], triggerIconType: 'colorBy' }, + ]); + }); + it('does not include palette for accessor config if the values are not numeric and palette exists', () => { + params.frame.activeData = generateActiveData([ + { + id: 'a', + rows: Array(3).fill({ + b: faker.random.word(), + }), + }, + ]); + expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([ + { columnId: 'b' }, + ]); + }); + it('does not include palette for accessor config if the values are numeric but palette exists', () => { + params.state.columns[0].palette = undefined; + expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([ + { columnId: 'b' }, + ]); + }); + }); + it('should compute the groups correctly for text based languages', () => { const datasource = createMockDatasource('textBased', { isTextBasedLanguage: jest.fn(() => true), diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index fe3e331d03714..05e05279567e5 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -14,6 +14,7 @@ import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartDatatable } from '@kbn/chart-icons'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/common'; +import { isNumericFieldForDatatable } from '../../../common/expressions/datatable/utils'; import type { FormBasedPersistedState } from '../../datasources/form_based/types'; import type { SuggestionRequest, @@ -315,16 +316,20 @@ export const getDatatableVisualization = ({ .map((accessor) => { const columnConfig = columnMap[accessor]; const stops = columnConfig?.palette?.params?.stops; + const isNumeric = Boolean( + accessor && isNumericFieldForDatatable(frame.activeData?.[state.layerId], accessor) + ); const hasColoring = Boolean(columnConfig?.colorMode !== 'none' && stops); return { columnId: accessor, triggerIconType: columnConfig?.hidden ? 'invisible' - : hasColoring + : hasColoring && isNumeric ? 'colorBy' : undefined, - palette: hasColoring && stops ? stops.map(({ color }) => color) : undefined, + palette: + hasColoring && isNumeric && stops ? stops.map(({ color }) => color) : undefined, }; }), supportsMoreColumns: true, From 59b986fbaa84723ceb48896c1c4ff8dc6a79ba1d Mon Sep 17 00:00:00 2001 From: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:21:30 +0000 Subject: [PATCH 013/104] [Security Solution][Detection Engine] sets Indicator match rule sort order of search to asc (#176321) ## Summary Sets search of documents for IM rule type from `desc` to `asc` when suppression is enabled. Also would allow to fix corner cases around [alert suppression](https://github.com/elastic/kibana/pull/174241). Alert suppression in IM rule relies on correct suppression time boundaries to correctly deduplicate earlier suppressed alerts. I.e, if document start suppression time(document timestamp) falls within suppression boundaries, it means, alert was already suppressed. So, we can exclude it from suppression as already suppressed and not to count it twice. But because documents for IM rule are searched in reverse order, it is possible, while processing a second page of results, to falsely count alert as already suppressed and discard it from suppressed count. That's because its timestamp is older than document's timestamp from the first page. Newly added test failed only for code execution path, when number of events is greater than number of threats. It is because, events are split in chunks by 9,000 first. So if reverse order in that case would cause alert from next batches to be dropped as already suppressed Setting `asc` can potentially affect IM rule performance, when events need to be searched first and rule is configured with the large look-back time. That's why new order is set to tech preview alert suppression feature only --------- Co-authored-by: Ryland Herrick --- .../threat_mapping/create_event_signal.ts | 20 +-- .../threat_mapping/create_threat_signal.ts | 20 +-- .../threat_mapping/create_threat_signals.ts | 25 +++- .../threat_mapping/get_event_count.ts | 3 +- .../indicator_match/threat_mapping/types.ts | 7 +- .../threat_match_alert_suppression.ts | 128 ++++++++++++++++++ 6 files changed, 166 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts index 211466e17c8f7..acf506b0304c9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { firstValueFrom } from 'rxjs'; - import { buildThreatMappingFilter } from './build_threat_mapping_filter'; import { getFilter } from '../../utils/get_filter'; import { searchAfterAndBulkCreate } from '../../utils/search_after_bulk_create'; @@ -56,7 +54,8 @@ export const createEventSignal = async ({ inputIndexFields, threatIndexFields, completeRule, - licensing, + sortOrder = 'desc', + isAlertSuppressionActive, }: CreateEventSignalOptions): Promise => { const threatFiltersFromEvents = buildThreatMappingFilter({ threatMapping, @@ -65,9 +64,6 @@ export const createEventSignal = async ({ allowedFieldsForTermsQuery, }); - const license = await firstValueFrom(licensing.license$); - const hasPlatinumLicense = license.hasAtLeast('platinum'); - if (!threatFiltersFromEvents.query || threatFiltersFromEvents.query?.bool.should.length === 0) { // empty event list and we do not want to return everything as being // a hit so opt to return the existing result. @@ -134,10 +130,6 @@ export const createEventSignal = async ({ threatSearchParams, }); - const isAlertSuppressionEnabled = Boolean( - completeRule.ruleParams.alertSuppression?.groupBy?.length - ); - let createResult: SearchAfterAndBulkCreateReturnType; const searchAfterBulkCreateParams = { buildReasonMessage: buildReasonMessageForThreatMatchAlert, @@ -151,7 +143,7 @@ export const createEventSignal = async ({ pageSize: searchAfterSize, ruleExecutionLogger, services, - sortOrder: 'desc' as const, + sortOrder, trackTotalHits: false, tuple, wrapHits, @@ -160,11 +152,7 @@ export const createEventSignal = async ({ secondaryTimestamp, }; - if ( - isAlertSuppressionEnabled && - runOpts.experimentalFeatures?.alertSuppressionForIndicatorMatchRuleEnabled && - hasPlatinumLicense - ) { + if (isAlertSuppressionActive) { createResult = await searchAfterAndBulkCreateSuppressedAlerts({ ...searchAfterBulkCreateParams, wrapSuppressedHits, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts index c5071605841f5..7740bed7777bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { firstValueFrom } from 'rxjs'; - import { buildThreatMappingFilter } from './build_threat_mapping_filter'; import { getFilter } from '../../utils/get_filter'; import { searchAfterAndBulkCreate } from '../../utils/search_after_bulk_create'; @@ -54,7 +52,8 @@ export const createThreatSignal = async ({ allowedFieldsForTermsQuery, inputIndexFields, threatIndexFields, - licensing, + sortOrder = 'desc', + isAlertSuppressionActive, }: CreateThreatSignalOptions): Promise => { const threatFilter = buildThreatMappingFilter({ threatMapping, @@ -63,9 +62,6 @@ export const createThreatSignal = async ({ allowedFieldsForTermsQuery, }); - const license = await firstValueFrom(licensing.license$); - const hasPlatinumLicense = license.hasAtLeast('platinum'); - if (!threatFilter.query || threatFilter.query?.bool.should.length === 0) { // empty threat list and we do not want to return everything as being // a hit so opt to return the existing result. @@ -107,10 +103,6 @@ export const createThreatSignal = async ({ threatIndexFields, }); - const isAlertSuppressionEnabled = Boolean( - completeRule.ruleParams.alertSuppression?.groupBy?.length - ); - let result: SearchAfterAndBulkCreateReturnType; const searchAfterBulkCreateParams = { buildReasonMessage: buildReasonMessageForThreatMatchAlert, @@ -124,7 +116,7 @@ export const createThreatSignal = async ({ pageSize: searchAfterSize, ruleExecutionLogger, services, - sortOrder: 'desc' as const, + sortOrder, trackTotalHits: false, tuple, wrapHits, @@ -133,11 +125,7 @@ export const createThreatSignal = async ({ secondaryTimestamp, }; - if ( - isAlertSuppressionEnabled && - runOpts.experimentalFeatures?.alertSuppressionForIndicatorMatchRuleEnabled && - hasPlatinumLicense - ) { + if (isAlertSuppressionActive) { result = await searchAfterAndBulkCreateSuppressedAlerts({ ...searchAfterBulkCreateParams, wrapSuppressedHits, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts index 5cb9dddc9b42e..aa108e5ea9bea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { firstValueFrom } from 'rxjs'; + import type { OpenPointInTimeResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { uniq, chunk } from 'lodash/fp'; @@ -216,6 +218,22 @@ export const createThreatSignals = async ({ } }; + const license = await firstValueFrom(licensing.license$); + const hasPlatinumLicense = license.hasAtLeast('platinum'); + const isAlertSuppressionConfigured = Boolean( + completeRule.ruleParams.alertSuppression?.groupBy?.length + ); + + const isAlertSuppressionActive = + isAlertSuppressionConfigured && + Boolean(runOpts.experimentalFeatures?.alertSuppressionForIndicatorMatchRuleEnabled) && + hasPlatinumLicense; + + // alert suppression needs to be performed on results searched in ascending order, so alert's suppression boundaries would be set correctly + // at the same time, there are concerns on performance of IM rule when sorting is set to asc, as it may lead to longer rule runs, since it will + // first go through alerts that might ve been processed in earlier executions, when look back interval set to large values (it can't be larger than 24h) + const sortOrder = isAlertSuppressionConfigured ? 'asc' : 'desc'; + if (eventCount < threatListCount) { await createSignals({ totalDocumentCount: eventCount, @@ -236,6 +254,7 @@ export const createThreatSignals = async ({ exceptionFilter, eventListConfig, indexFields: inputIndexFields, + sortOrder, }), createSignal: (slicedChunk) => @@ -278,7 +297,8 @@ export const createThreatSignals = async ({ inputIndexFields, threatIndexFields, runOpts, - licensing, + sortOrder, + isAlertSuppressionActive, }), }); } else { @@ -342,7 +362,8 @@ export const createThreatSignals = async ({ inputIndexFields, threatIndexFields, runOpts, - licensing, + sortOrder, + isAlertSuppressionActive, }), }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/get_event_count.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/get_event_count.ts index 214c7d3f13075..c74424f65d514 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/get_event_count.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/get_event_count.ts @@ -29,6 +29,7 @@ export const getEventList = async ({ exceptionFilter, eventListConfig, indexFields, + sortOrder = 'desc', }: EventsOptions): Promise> => { const calculatedPerPage = perPage ?? MAX_PER_PAGE; if (calculatedPerPage > 10000) { @@ -59,7 +60,7 @@ export const getEventList = async ({ filter: queryFilter, primaryTimestamp, secondaryTimestamp, - sortOrder: 'desc', + sortOrder, trackTotalHits: false, runtimeMappings, overrideBody: eventListConfig, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/types.ts index ae9548090ea64..d8a6a97bbc644 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/types.ts @@ -120,7 +120,8 @@ export interface CreateThreatSignalOptions { inputIndexFields: DataViewFieldBase[]; threatIndexFields: DataViewFieldBase[]; runOpts: RunOpts; - licensing: LicensingPluginSetup; + sortOrder?: SortOrderOrUndefined; + isAlertSuppressionActive: boolean; } export interface CreateEventSignalOptions { @@ -163,7 +164,8 @@ export interface CreateEventSignalOptions { inputIndexFields: DataViewFieldBase[]; threatIndexFields: DataViewFieldBase[]; runOpts: RunOpts; - licensing: LicensingPluginSetup; + sortOrder?: SortOrderOrUndefined; + isAlertSuppressionActive: boolean; } type EntryKey = 'field' | 'value'; @@ -312,6 +314,7 @@ export interface EventsOptions { exceptionFilter: Filter | undefined; eventListConfig?: OverrideBodyQuery; indexFields: DataViewFieldBase[]; + sortOrder?: SortOrderOrUndefined; } export interface EventDoc { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/threat_match_alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/threat_match_alert_suppression.ts index 9d66f49c8558b..3f53e6d8a7100 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/threat_match_alert_suppression.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/threat_match_alert_suppression.ts @@ -1126,6 +1126,133 @@ export default ({ getService }: FtrProviderContext) => { }); }); + // large number of documents gets processed in batches of 9,000 + // rule should correctly go through them and suppress + // that can be an issue when search results returning in desc order + // this test is added to verify suppression works fine for this cases + it('should suppress alerts on large number of documents, more than 9,000', async () => { + const id = uuidv4(); + const firstTimestamp = '2020-10-28T05:45:00.000Z'; + const secondTimestamp = '2020-10-28T06:10:00.000Z'; + + await eventsFiller({ + id, + count: 10000 * eventsCount, + timestamp: [firstTimestamp, secondTimestamp], + }); + await threatsFiller({ id, count: 10000 * threatsCount, timestamp: firstTimestamp }); + + await indexGeneratedSourceDocuments({ + docsCount: 60000, + interval: [firstTimestamp, '2020-10-28T05:35:50.000Z'], + seed: (index, _, timestamp) => ({ + id, + '@timestamp': timestamp, + host: { + name: `host-${index}`, + }, + agent: { name: 'agent-a' }, + }), + }); + + await indexGeneratedSourceDocuments({ + docsCount: 60000, + interval: [secondTimestamp, '2020-10-28T06:20:50.000Z'], + seed: (index, _, timestamp) => ({ + id, + '@timestamp': timestamp, + host: { + name: `host-${index}`, + }, + agent: { name: 'agent-a' }, + }), + }); + + await addThreatDocuments({ + id, + timestamp: firstTimestamp, + fields: { + host: { + name: 'host-80', + }, + }, + count: 1, + }); + + await addThreatDocuments({ + id, + timestamp: firstTimestamp, + fields: { + host: { + name: 'host-14000', + }, + }, + count: 1, + }); + + await addThreatDocuments({ + id, + timestamp: firstTimestamp, + fields: { + host: { + name: 'host-36000', + }, + }, + count: 1, + }); + + await addThreatDocuments({ + id, + timestamp: firstTimestamp, + fields: { + host: { + name: 'host-5700', + }, + }, + count: 1, + }); + + const rule: ThreatMatchRuleCreateProps = { + ...indicatorMatchRule(id), + alert_suppression: { + group_by: ['agent.name'], + missing_fields_strategy: 'suppress', + duration: { + value: 300, + unit: 'm', + }, + }, + from: 'now-35m', + interval: '30m', + }; + + const { previewId } = await previewRule({ + supertest, + rule, + timeframeEnd: new Date('2020-10-28T06:30:00.000Z'), + invocationCount: 2, + }); + + const previewAlerts = await getPreviewAlerts({ + es, + previewId, + sort: ['agent.name', ALERT_ORIGINAL_TIME], + }); + expect(previewAlerts.length).toEqual(1); + expect(previewAlerts[0]._source).toEqual({ + ...previewAlerts[0]._source, + [ALERT_SUPPRESSION_TERMS]: [ + { + field: 'agent.name', + value: ['agent-a'], + }, + ], + // There 4 documents in threats index, each matches one document in source index on each of 2 rule executions + // In total it gives 8 potential alerts. With suppression enabled 1 is created, the rest 7 are suppressed + [ALERT_SUPPRESSION_DOCS_COUNT]: 7, + }); + }); + describe('rule execution only', () => { it('should suppress alerts during rule execution only', async () => { const id = uuidv4(); @@ -2064,6 +2191,7 @@ export default ({ getService }: FtrProviderContext) => { }, ], [ALERT_SUPPRESSION_DOCS_COUNT]: 499, + [ALERT_SUPPRESSION_START]: '2020-10-28T06:50:00.000Z', }); }); From 479a022bd3a8ae79ca9af1eb12a90a26cb53efdf Mon Sep 17 00:00:00 2001 From: Juan Pablo Djeredjian Date: Thu, 8 Feb 2024 13:35:54 +0100 Subject: [PATCH 014/104] [Security Solution] Improve logging for FTR test `retry` function (#176316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary **Fixes:** - https://github.com/elastic/kibana/issues/175481 - https://github.com/elastic/kibana/issues/175250 ### Description Improves logging for the `retry` FTR integration testing utility that is used to wrap helpers that make endpoint calls or direct Elasticsearch operations. The previous logging would only explain that the maximum amount of retries had been reached, with the actual error caused in the test being lost, which proved hard to debug. These changes catches the error and log it, allowing us to understand why a retried test failed. Error now reported as: ``` [00:00:19] │ERROR Retrying installPrebuiltRulesPackageByVersion: Error: expected 500 "Internal Server Error", got 200 "OK" [00:00:19] │ debg --- retry.tryForTime failed again with the same message... [00:00:19] │ERROR Reached maximum number of retries for test: 2/2 [00:00:19] └- ✖ fail: Rules Management - Prebuilt Rules - Update Prebuilt Rules Package @ess @serverless @skipInQA update_prebuilt_rules_package should allow user to install prebuilt rules from scratch, then install new rules and upgrade existing rules from the new package [00:00:19] │ Error: "Reached maximum number of retries for test: 2/2" [00:00:19] │ at block (retry.ts:72:16) [00:00:19] │ at runAttempt (retry_for_success.ts:29:21) [00:00:19] │ at retryForSuccess (retry_for_success.ts:79:27) [00:00:19] │ at RetryService.tryForTime (retry.ts:23:12) [00:00:19] │ at retry (retry.ts:62:20) [00:00:19] │ at installPrebuiltRulesPackageByVersion (install_fleet_package_by_url.ts:77:25) [00:00:19] │ at Context. (update_prebuilt_rules_package.ts:106:46) [00:00:19] │ at Object.apply (wrap_function.js:73:16) ``` Main error is still `"Reached maximum number of retries for test: 2/2"`, but now additional logging of exactly **what failed in the test** is error-logged as seen above: `ERROR Retrying installPrebuiltRulesPackageByVersion: Error: expected 500 "Internal Server Error", got 200 "OK"` **Flaky test run:** - Shared 50 and 50: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5068 - Ess 100 runs: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5091 - Serverless 100 runs: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5092 ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../install_latest_bundled_prebuilt_rules.ts | 3 ++- .../prerelease_packages.ts | 3 ++- .../fleet_integration.ts | 1 + .../update_prebuilt_rules_package.ts | 6 ++++-- .../detections_response/utils/retry.ts | 21 ++++++++++++++++--- .../install_fleet_package_by_url.ts | 11 ++++++++-- .../install_prebuilt_rules_fleet_package.ts | 7 +++++++ 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/install_latest_bundled_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/install_latest_bundled_prebuilt_rules.ts index 32eb1d3dbdf01..dcb2561b1f3e8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/install_latest_bundled_prebuilt_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/install_latest_bundled_prebuilt_rules.ts @@ -61,7 +61,8 @@ export default ({ getService }: FtrProviderContext): void => { es, supertest, '99.0.0', - retry + retry, + log ); // As opposed to "registry" diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/prerelease_packages.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/prerelease_packages.ts index dcafdf8eaf1a7..3ed663f7ecc66 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/prerelease_packages.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/bundled_prebuilt_rules_package/trial_license_complete_tier/prerelease_packages.ts @@ -49,7 +49,8 @@ export default ({ getService }: FtrProviderContext): void => { const fleetPackageInstallationResponse = await installPrebuiltRulesPackageViaFleetAPI( es, supertest, - retry + retry, + log ); expect(fleetPackageInstallationResponse.items.length).toBe(1); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/fleet_integration.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/fleet_integration.ts index 1233af5c33f6a..1a8394a3b5144 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/fleet_integration.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/fleet_integration.ts @@ -49,6 +49,7 @@ export default ({ getService }: FtrProviderContext): void => { supertest, overrideExistingPackage: true, retryService: retry, + log, }); // Verify that status is updated after package installation diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/update_prebuilt_rules_package.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/update_prebuilt_rules_package.ts index 11577bec1b5c7..ffba2bd01d988 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/update_prebuilt_rules_package.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/update_prebuilt_rules_package.ts @@ -107,7 +107,8 @@ export default ({ getService }: FtrProviderContext): void => { es, supertest, previousVersion, - retry + retry, + log ); expect(installPreviousPackageResponse._meta.install_source).toBe('registry'); @@ -160,7 +161,8 @@ export default ({ getService }: FtrProviderContext): void => { es, supertest, currentVersion, - retry + retry, + log ); expect(installLatestPackageResponse.items.length).toBeGreaterThanOrEqual(0); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/retry.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/retry.ts index dafd16aaa9f5f..3007448ed895f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/retry.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/retry.ts @@ -6,7 +6,7 @@ */ import { RetryService } from '@kbn/ftr-common-functional-services'; - +import type { ToolingLog } from '@kbn/tooling-log'; /** * Retry wrapper for async supertests, with a maximum number of retries. * You can pass in a function that executes a supertest test, and make assertions @@ -44,15 +44,19 @@ import { RetryService } from '@kbn/ftr-common-functional-services'; export const retry = async ({ test, retryService, + utilityName, retries = 2, timeout = 30000, retryDelay = 200, + log, }: { test: () => Promise; + utilityName: string; retryService: RetryService; retries?: number; timeout?: number; retryDelay?: number; + log: ToolingLog; }): Promise => { let retryAttempt = 0; const response = await retryService.tryForTime( @@ -61,12 +65,23 @@ export const retry = async ({ if (retryAttempt > retries) { // Log error message if we reached the maximum number of retries // but don't throw an error, return it to break the retry loop. - return new Error('Reached maximum number of retries for test.'); + const errorMessage = `Reached maximum number of retries for test: ${ + retryAttempt - 1 + }/${retries}`; + log?.error(errorMessage); + return new Error(JSON.stringify(errorMessage)); } retryAttempt = retryAttempt + 1; - return test(); + // Catch the error thrown by the test and log it, then throw it again + // to cause `tryForTime` to retry. + try { + return await test(); + } catch (error) { + log.error(`Retrying ${utilityName}: ${error}`); + throw error; + } }, undefined, retryDelay diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_fleet_package_by_url.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_fleet_package_by_url.ts index 988d73660d0ee..2839795ab1976 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_fleet_package_by_url.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_fleet_package_by_url.ts @@ -9,6 +9,7 @@ import type SuperTest from 'supertest'; import { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; import { epmRouteService } from '@kbn/fleet-plugin/common'; import { RetryService } from '@kbn/ftr-common-functional-services'; +import type { ToolingLog } from '@kbn/tooling-log'; import expect from 'expect'; import { retry } from '../../retry'; import { refreshSavedObjectIndices } from '../../refresh_index'; @@ -28,7 +29,8 @@ const ATTEMPT_TIMEOUT = 120000; export const installPrebuiltRulesPackageViaFleetAPI = async ( es: Client, supertest: SuperTest.SuperTest, - retryService: RetryService + retryService: RetryService, + log: ToolingLog ): Promise => { const fleetResponse = await retry({ test: async () => { @@ -44,9 +46,11 @@ export const installPrebuiltRulesPackageViaFleetAPI = async ( return testResponse.body; }, + utilityName: installPrebuiltRulesPackageViaFleetAPI.name, retryService, retries: MAX_RETRIES, timeout: ATTEMPT_TIMEOUT, + log, }); await refreshSavedObjectIndices(es); @@ -67,7 +71,8 @@ export const installPrebuiltRulesPackageByVersion = async ( es: Client, supertest: SuperTest.SuperTest, version: string, - retryService: RetryService + retryService: RetryService, + log: ToolingLog ): Promise => { const fleetResponse = await retry({ test: async () => { @@ -83,9 +88,11 @@ export const installPrebuiltRulesPackageByVersion = async ( return testResponse.body; }, + utilityName: installPrebuiltRulesPackageByVersion.name, retryService, retries: MAX_RETRIES, timeout: ATTEMPT_TIMEOUT, + log, }); await refreshSavedObjectIndices(es); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts index 592406e8c3398..770d966f50a59 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts @@ -15,6 +15,7 @@ import { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; import type SuperTest from 'supertest'; import { RetryService } from '@kbn/ftr-common-functional-services'; import expect from 'expect'; +import { ToolingLog } from '@kbn/tooling-log'; import { retry } from '../../retry'; import { refreshSavedObjectIndices } from '../../refresh_index'; @@ -35,12 +36,14 @@ export const installPrebuiltRulesFleetPackage = async ({ version, overrideExistingPackage, retryService, + log, }: { es: Client; supertest: SuperTest.SuperTest; version?: string; overrideExistingPackage: boolean; retryService: RetryService; + log: ToolingLog; }): Promise => { if (version) { // Install a specific version @@ -59,8 +62,10 @@ export const installPrebuiltRulesFleetPackage = async ({ return testResponse.body; }, retryService, + utilityName: installPrebuiltRulesFleetPackage.name, retries: MAX_RETRIES, timeout: ATTEMPT_TIMEOUT, + log, }); await refreshSavedObjectIndices(es); @@ -91,8 +96,10 @@ export const installPrebuiltRulesFleetPackage = async ({ return body; }, retryService, + utilityName: installPrebuiltRulesFleetPackage.name, retries: MAX_RETRIES, timeout: ATTEMPT_TIMEOUT, + log, }); await refreshSavedObjectIndices(es); From 1c3fa24be396176454df3dd3a67c7acdfcea46d4 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 8 Feb 2024 13:53:29 +0100 Subject: [PATCH 015/104] Add `build_flavor` to `/api/status` response (#176477) ## Summary Fix https://github.com/elastic/kibana/issues/176475 Add the `version.build_flavor` field to the response of the status API --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/status/components/version_header.test.tsx | 1 + .../src/status/lib/load_status.test.ts | 1 + packages/core/status/core-status-common-internal/src/status.ts | 2 ++ packages/core/status/core-status-common-internal/tsconfig.json | 3 ++- .../status/core-status-server-internal/src/routes/status.ts | 3 ++- src/core/server/integration_tests/status/routes/status.test.ts | 1 + 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.test.tsx b/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.test.tsx index 8172b705a6ffe..e0eaf9b2144fa 100644 --- a/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.test.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.test.tsx @@ -17,6 +17,7 @@ const buildServerVersion = (parts: Partial = {}): ServerVersion = build_number: 9000, build_snapshot: false, build_date: '2023-05-15T23:12:09.000Z', + build_flavor: 'traditional', ...parts, }); diff --git a/packages/core/apps/core-apps-browser-internal/src/status/lib/load_status.test.ts b/packages/core/apps/core-apps-browser-internal/src/status/lib/load_status.test.ts index ed6cc186313f3..92aad0f460e70 100644 --- a/packages/core/apps/core-apps-browser-internal/src/status/lib/load_status.test.ts +++ b/packages/core/apps/core-apps-browser-internal/src/status/lib/load_status.test.ts @@ -21,6 +21,7 @@ const mockedResponse: StatusResponse = { build_number: 12, build_snapshot: false, build_date: '2023-05-15T23:12:09.000Z', + build_flavor: 'traditional', }, status: { overall: { diff --git a/packages/core/status/core-status-common-internal/src/status.ts b/packages/core/status/core-status-common-internal/src/status.ts index 806a3ac56b407..0a3f3ad770fe8 100644 --- a/packages/core/status/core-status-common-internal/src/status.ts +++ b/packages/core/status/core-status-common-internal/src/status.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { BuildFlavor } from '@kbn/config'; import type { ServiceStatusLevelId, ServiceStatus, CoreStatus } from '@kbn/core-status-common'; import type { OpsMetrics } from '@kbn/core-metrics-server'; @@ -34,6 +35,7 @@ export interface ServerVersion { build_hash: string; build_number: number; build_snapshot: boolean; + build_flavor: BuildFlavor; build_date: string; } diff --git a/packages/core/status/core-status-common-internal/tsconfig.json b/packages/core/status/core-status-common-internal/tsconfig.json index c746e7133cd2c..7d31fa090eb0f 100644 --- a/packages/core/status/core-status-common-internal/tsconfig.json +++ b/packages/core/status/core-status-common-internal/tsconfig.json @@ -13,7 +13,8 @@ ], "kbn_references": [ "@kbn/core-status-common", - "@kbn/core-metrics-server" + "@kbn/core-metrics-server", + "@kbn/config" ], "exclude": [ "target/**/*", diff --git a/packages/core/status/core-status-server-internal/src/routes/status.ts b/packages/core/status/core-status-server-internal/src/routes/status.ts index 59c7aa23c51d4..1faa623467b58 100644 --- a/packages/core/status/core-status-server-internal/src/routes/status.ts +++ b/packages/core/status/core-status-server-internal/src/routes/status.ts @@ -156,7 +156,7 @@ const getFullStatusResponse = async ({ }; query: { v8format?: boolean; v7format?: boolean }; }): Promise => { - const { version, buildSha, buildNum, buildDate } = config.packageInfo; + const { version, buildSha, buildNum, buildDate, buildFlavor } = config.packageInfo; const versionWithoutSnapshot = version.replace(SNAPSHOT_POSTFIX, ''); let statusInfo: StatusInfo | LegacyStatusInfo; @@ -186,6 +186,7 @@ const getFullStatusResponse = async ({ build_hash: buildSha, build_number: buildNum, build_snapshot: SNAPSHOT_POSTFIX.test(version), + build_flavor: buildFlavor, build_date: buildDate.toISOString(), }, status: statusInfo, diff --git a/src/core/server/integration_tests/status/routes/status.test.ts b/src/core/server/integration_tests/status/routes/status.test.ts index 755b9fc9b46f6..29a55743dd0d5 100644 --- a/src/core/server/integration_tests/status/routes/status.test.ts +++ b/src/core/server/integration_tests/status/routes/status.test.ts @@ -210,6 +210,7 @@ describe('GET /api/status', () => { build_number: 1234, build_snapshot: true, build_date: new Date('2023-05-15T23:12:09.000Z').toISOString(), + build_flavor: 'traditional', }); const metricsMockValue = await firstValueFrom(metrics.getOpsMetrics$()); expect(result.body.metrics).toEqual({ From 0ed5fe66476cbb8d891ec3ba1494251316334ac6 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Thu, 8 Feb 2024 14:24:10 +0100 Subject: [PATCH 016/104] [Lens] Color mapping UX refactoring (#175144) This commit revisits the UX for the Lens color mapping applying a slightly different UX behaviour to allow looping of colors from a chosen palette. --- .../__stories__/color_mapping.stories.tsx | 165 ++++----- .../categorical_color_mapping.test.tsx | 20 +- .../color/color_handling.test.ts | 179 +++++++-- .../color_mapping/color/color_handling.ts | 137 ++++--- .../color_mapping/color/rule_matching.ts | 2 +- .../components/assignment/assignment.tsx | 14 +- .../components/assignment/match.tsx | 7 +- .../components/assignment/range.tsx | 5 +- .../assignment/special_assignment.tsx | 69 ++-- .../components/color_picker/color_picker.tsx | 2 +- .../components/color_picker/color_swatch.tsx | 14 +- .../color_picker/palette_colors.tsx | 8 +- .../components/color_picker/rgb_picker.tsx | 5 +- .../components/container/assigments.tsx | 329 +++++++++++++++++ .../components/container/container.tsx | 282 +++++--------- .../container/unassigned_terms_config.tsx | 150 ++++++++ .../components/palette_selector/gradient.tsx | 345 +++++------------- .../palette_selector/gradient_add_stop.tsx | 110 ++++++ .../palette_selector/palette_selector.tsx | 206 ++--------- .../components/palette_selector/scale.tsx | 144 ++++++++ .../config/assignment_from_categories.ts | 65 ---- .../color_mapping/config/assignments.ts | 74 +--- .../config/default_color_mapping.ts | 55 +-- .../color_mapping/config/types.ts | 12 +- .../shared_components/color_mapping/index.ts | 1 + .../color_mapping/palettes/elastic_brand.ts | 6 +- .../color_mapping/palettes/eui_amsterdam.ts | 6 +- .../color_mapping/palettes/kibana_legacy.ts | 6 +- .../color_mapping/state/color_mapping.ts | 25 +- .../color_mapping/state/selectors.ts | 6 +- .../color_telemetry_helpers.test.ts | 60 +-- .../color_telemetry_helpers.ts | 33 +- .../translations/translations/fr-FR.json | 7 +- .../translations/translations/ja-JP.json | 7 +- .../translations/translations/zh-CN.json | 7 +- .../test/functional/page_objects/lens_page.ts | 5 +- 36 files changed, 1434 insertions(+), 1134 deletions(-) create mode 100644 packages/kbn-coloring/src/shared_components/color_mapping/components/container/assigments.tsx create mode 100644 packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx create mode 100644 packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient_add_stop.tsx create mode 100644 packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/scale.tsx delete mode 100644 packages/kbn-coloring/src/shared_components/color_mapping/config/assignment_from_categories.ts diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/__stories__/color_mapping.stories.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/__stories__/color_mapping.stories.tsx index 95f4ff5623ea3..f1d9add2c0f09 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/__stories__/color_mapping.stories.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/__stories__/color_mapping.stories.tsx @@ -6,122 +6,115 @@ * Side Public License, v 1. */ -import React, { FC } from 'react'; -import { EuiFlyout, EuiForm } from '@elastic/eui'; +import React, { FC, useState } from 'react'; +import { EuiFlyout, EuiForm, EuiPage, isColorDark } from '@elastic/eui'; import { ComponentStory } from '@storybook/react'; +import { css } from '@emotion/react'; import { CategoricalColorMapping, ColorMappingProps } from '../categorical_color_mapping'; -import { AVAILABLE_PALETTES } from '../palettes'; +import { AVAILABLE_PALETTES, getPalette, NeutralPalette } from '../palettes'; import { DEFAULT_COLOR_MAPPING_CONFIG } from '../config/default_color_mapping'; +import { ColorMapping } from '../config'; +import { getColorFactory } from '../color/color_handling'; +import { ruleMatch } from '../color/rule_matching'; +import { getValidColor } from '../color/color_math'; export default { title: 'Color Mapping', component: CategoricalColorMapping, - decorators: [ - (story: Function) => ( - {}} hideCloseButton> - {story()} - - ), - ], + decorators: [(story: Function) => story()], }; -const Template: ComponentStory> = (args) => ( - -); +const Template: ComponentStory> = (args) => { + const [updatedModel, setUpdateModel] = useState( + DEFAULT_COLOR_MAPPING_CONFIG + ); + + const getPaletteFn = getPalette(AVAILABLE_PALETTES, NeutralPalette); + + const colorFactory = getColorFactory(updatedModel, getPaletteFn, false, args.data); + + return ( + +
    + {args.data.type === 'categories' && + args.data.categories.map((c, i) => { + const match = updatedModel.assignments.some(({ rule }) => { + return ruleMatch(rule, c); + }); + const color = colorFactory(c); + const isDark = isColorDark(...getValidColor(color).rgb()); + return ( +
  1. + {c} +
  2. + ); + })} +
+ {}} + hideCloseButton + ownFocus={false} + > + + + + +
+ ); +}; export const Default = Template.bind({}); Default.args = { model: { ...DEFAULT_COLOR_MAPPING_CONFIG, - assignmentMode: 'manual', + colorMode: { - type: 'gradient', - steps: [ - { - type: 'categorical', - colorIndex: 0, - paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId, - touched: false, - }, - { - type: 'categorical', - colorIndex: 1, - paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId, - touched: false, - }, - { - type: 'categorical', - colorIndex: 2, - paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId, - touched: false, - }, - ], - sort: 'asc', + type: 'categorical', }, - assignments: [ - { - rule: { - type: 'matchExactly', - values: ['this is', 'a multi-line combobox that is very long and that will be truncated'], - }, - color: { - type: 'gradient', - }, - touched: false, - }, - { - rule: { - type: 'matchExactly', - values: ['b', ['double', 'value']], - }, - color: { - type: 'gradient', - }, - touched: false, - }, - { - rule: { - type: 'matchExactly', - values: ['c'], - }, - color: { - type: 'gradient', - }, - touched: false, - }, + specialAssignments: [ { rule: { - type: 'matchExactly', - values: [ - 'this is', - 'a multi-line wrap', - 'combo box', - 'test combo', - '3 lines', - ['double', 'value'], - ], + type: 'other', }, color: { - type: 'gradient', + type: 'loop', }, touched: false, }, ], + assignments: [], }, isDarkMode: false, data: { type: 'categories', categories: [ - 'a', - 'b', - 'c', - 'd', - 'this is', - 'a multi-line wrap', - 'combo box', - 'test combo', - '3 lines', + 'US', + 'Mexico', + 'Brasil', + 'Canada', + 'Italy', + 'Germany', + 'France', + 'Spain', + 'UK', + 'Portugal', + 'Greece', + 'Sweden', + 'Finland', ], }, diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/categorical_color_mapping.test.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/categorical_color_mapping.test.tsx index fe8374d7dcdcd..ccc955d2b8947 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/categorical_color_mapping.test.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/categorical_color_mapping.test.tsx @@ -13,8 +13,9 @@ import { AVAILABLE_PALETTES } from './palettes'; import { DEFAULT_COLOR_MAPPING_CONFIG } from './config/default_color_mapping'; import { MULTI_FIELD_KEY_SEPARATOR } from '@kbn/data-plugin/common'; -const AUTO_ASSIGN_SWITCH = '[data-test-subj="lns-colorMapping-autoAssignSwitch"]'; const ASSIGNMENTS_LIST = '[data-test-subj="lns-colorMapping-assignmentsList"]'; +const ASSIGNMENTS_PROMPT = '[data-test-subj="lns-colorMapping-assignmentsPrompt"]'; +const ASSIGNMENTS_PROMPT_ADD_ALL = '[data-test-subj="lns-colorMapping-assignmentsPromptAddAll"]'; const ASSIGNMENT_ITEM = (i: number) => `[data-test-subj="lns-colorMapping-assignmentsItem${i}"]`; describe('color mapping', () => { @@ -35,19 +36,12 @@ describe('color mapping', () => { /> ); - expect(component.find(AUTO_ASSIGN_SWITCH).hostNodes().prop('aria-checked')).toEqual(true); - expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual( - dataInput.categories.length - ); - dataInput.categories.forEach((category, index) => { - const assignment = component.find(ASSIGNMENT_ITEM(index)).hostNodes(); - expect(assignment.text()).toEqual(category); - expect(assignment.hasClass('euiComboBox-isDisabled')).toEqual(true); - }); + // empty list prompt visible + expect(component.find(ASSIGNMENTS_PROMPT)).toBeTruthy(); expect(onModelUpdateFn).not.toBeCalled(); }); - it('switch to manual assignments', () => { + it('Add all terms to assignments', () => { const dataInput: ColorMappingInputData = { type: 'categories', categories: ['categoryA', 'categoryB'], @@ -63,9 +57,8 @@ describe('color mapping', () => { specialTokens={new Map()} /> ); - component.find(AUTO_ASSIGN_SWITCH).hostNodes().simulate('click'); + component.find(ASSIGNMENTS_PROMPT_ADD_ALL).hostNodes().simulate('click'); expect(onModelUpdateFn).toBeCalledTimes(1); - expect(component.find(AUTO_ASSIGN_SWITCH).hostNodes().prop('aria-checked')).toEqual(false); expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual( dataInput.categories.length ); @@ -97,6 +90,7 @@ describe('color mapping', () => { } /> ); + component.find(ASSIGNMENTS_PROMPT_ADD_ALL).hostNodes().simulate('click'); expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual( dataInput.categories.length ); diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.test.ts b/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.test.ts index 93896394daf41..f8631ed5768da 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.test.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.test.ts @@ -23,6 +23,7 @@ import { ColorMapping } from '../config'; describe('Color mapping - color generation', () => { const getPaletteFn = getPalette(AVAILABLE_PALETTES, NeutralPalette); + it('returns EUI light colors from default config', () => { const colorFactory = getColorFactory(DEFAULT_COLOR_MAPPING_CONFIG, getPaletteFn, false, { type: 'categories', @@ -31,18 +32,36 @@ describe('Color mapping - color generation', () => { expect(colorFactory('catA')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); expect(colorFactory('catB')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); expect(colorFactory('catC')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); - // if the category is not available in the `categories` list then a default neutral color is used - expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + // if the category is not available in the `categories` list then a default netural is used + // this is an edge case and ideally never happen + expect(colorFactory('not_available_1')).toBe( + NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX] + ); }); - it('returns max number of colors defined in palette, use other color otherwise', () => { + // currently there is no difference in the two colors, but this could change in the future + // this test will catch the change + it('returns EUI dark colors from default config', () => { + const colorFactory = getColorFactory(DEFAULT_COLOR_MAPPING_CONFIG, getPaletteFn, true, { + type: 'categories', + categories: ['catA', 'catB', 'catC'], + }); + expect(colorFactory('catA')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); + expect(colorFactory('catB')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); + expect(colorFactory('catC')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); + // if the category is not available in the `categories` list then a default netural is used + // this is an edge case and ideally never happen + expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_DARK[DEFAULT_NEUTRAL_PALETTE_INDEX]); + }); + + it('by default loops colors defined in palette', () => { const twoColorPalette: ColorMapping.CategoricalPalette = { id: 'twoColors', name: 'twoColors', colorCount: 2, type: 'categorical', - getColor(valueInRange, isDarkMode) { - return ['red', 'blue'][valueInRange]; + getColor(indexInRange, isDarkMode, loop) { + return ['red', 'blue'][loop ? indexInRange % 2 : indexInRange]; }, }; @@ -53,6 +72,17 @@ describe('Color mapping - color generation', () => { const colorFactory = getColorFactory( { ...DEFAULT_COLOR_MAPPING_CONFIG, + specialAssignments: [ + { + color: { + type: 'loop', + }, + rule: { + type: 'other', + }, + touched: false, + }, + ], paletteId: twoColorPalette.id, }, simplifiedGetPaletteGn, @@ -64,23 +94,58 @@ describe('Color mapping - color generation', () => { ); expect(colorFactory('cat1')).toBe('#ff0000'); expect(colorFactory('cat2')).toBe('#0000ff'); - // return a palette color only up to the max number of color in the palette - expect(colorFactory('cat3')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); - expect(colorFactory('cat4')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + // the palette will loop depending on the number of colors available + expect(colorFactory('cat3')).toBe('#ff0000'); + expect(colorFactory('cat4')).toBe('#0000ff'); }); - // currently there is no difference in the two colors, but this could change in the future - // this test will catch the change - it('returns EUI dark colors from default config', () => { - const colorFactory = getColorFactory(DEFAULT_COLOR_MAPPING_CONFIG, getPaletteFn, true, { - type: 'categories', - categories: ['catA', 'catB', 'catC'], - }); - expect(colorFactory('catA')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); - expect(colorFactory('catB')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); - expect(colorFactory('catC')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); - // if the category is not available in the `categories` list then a default neutral color is used - expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_DARK[DEFAULT_NEUTRAL_PALETTE_INDEX]); + it('returns the unassigned color if configured statically', () => { + const twoColorPalette: ColorMapping.CategoricalPalette = { + id: 'twoColors', + name: 'twoColors', + colorCount: 2, + type: 'categorical', + getColor(indexInRange, darkMode, loop) { + return ['red', 'blue'][loop ? indexInRange % 2 : indexInRange]; + }, + }; + + const simplifiedGetPaletteGn = getPalette( + new Map([[twoColorPalette.id, twoColorPalette]]), + NeutralPalette + ); + const colorFactory = getColorFactory( + { + ...DEFAULT_COLOR_MAPPING_CONFIG, + specialAssignments: [ + { + color: { + type: 'categorical', + paletteId: NeutralPalette.id, + colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, + }, + rule: { + type: 'other', + }, + touched: false, + }, + ], + paletteId: twoColorPalette.id, + }, + simplifiedGetPaletteGn, + false, + { + type: 'categories', + categories: ['cat1', 'cat2', 'cat3', 'cat4'], + } + ); + expect(colorFactory('cat1')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + expect(colorFactory('cat2')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + expect(colorFactory('cat3')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + expect(colorFactory('cat4')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); + // if the category is not available in the `categories` list then a default netural is used + // this is an edge case and ideally never happen + expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); }); it('handles special tokens, multi-field categories and non-trimmed whitespaces', () => { @@ -89,19 +154,19 @@ describe('Color mapping - color generation', () => { categories: ['__other__', ['fieldA', 'fieldB'], '__empty__', ' with-whitespaces '], }); expect(colorFactory('__other__')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); - expect(colorFactory(['fieldA', 'fieldB'])).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); + // expect(colorFactory(['fieldA', 'fieldB'])).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); expect(colorFactory('__empty__')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); expect(colorFactory(' with-whitespaces ')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[3]); }); - it('ignores configured assignments in auto mode', () => { + it('ignores configured assignments in loop mode', () => { const colorFactory = getColorFactory( { ...DEFAULT_COLOR_MAPPING_CONFIG, assignments: [ { color: { type: 'colorCode', colorCode: 'red' }, - rule: { type: 'matchExactly', values: ['assignmentToIgnore'] }, + rule: { type: 'matchExactly', values: ['configuredAssignment'] }, touched: false, }, ], @@ -110,19 +175,19 @@ describe('Color mapping - color generation', () => { false, { type: 'categories', - categories: ['catA', 'catB', 'assignmentToIgnore'], + categories: ['catA', 'catB', 'configuredAssignment', 'nextCat'], } ); expect(colorFactory('catA')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); expect(colorFactory('catB')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[1]); - expect(colorFactory('assignmentToIgnore')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); + expect(colorFactory('configuredAssignment')).toBe('red'); + expect(colorFactory('nextCat')).toBe(EUI_AMSTERDAM_PALETTE_COLORS[2]); }); it('color with auto rule are assigned in order of the configured data input', () => { const colorFactory = getColorFactory( { ...DEFAULT_COLOR_MAPPING_CONFIG, - assignmentMode: 'manual', assignments: [ { color: { type: 'colorCode', colorCode: 'red' }, @@ -154,7 +219,8 @@ describe('Color mapping - color generation', () => { expect(colorFactory('redCat')).toBe('red'); // this matches with the second availabe "auto" rule expect(colorFactory('greenCat')).toBe('green'); - // if the category is not available in the `categories` list then a default neutral color is used + // if the category is not available in the `categories` list then a default netural is used + // this is an edge case and ideally never happen expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); }); @@ -188,7 +254,7 @@ describe('Color mapping - color generation', () => { expect(toHex(colorFactory('cat3'))).toBe('#cce8e0'); }); - it('returns sequential gradient colors from lighter to darker [asc, lightMode]', () => { + it('sequential gradient colors from lighter to darker [asc, lightMode]', () => { const colorFactory = getColorFactory( { ...DEFAULT_COLOR_MAPPING_CONFIG, @@ -212,10 +278,59 @@ describe('Color mapping - color generation', () => { categories: ['cat1', 'cat2', 'cat3'], } ); + // light green expect(toHex(colorFactory('cat1'))).toBe('#cce8e0'); + // mid green point expect(toHex(colorFactory('cat2'))).toBe('#93cebc'); + // initial gradient color + expect(toHex(colorFactory('cat3'))).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); + }); + it('sequential gradients and static color from lighter to darker [asc, lightMode]', () => { + const colorFactory = getColorFactory( + { + ...DEFAULT_COLOR_MAPPING_CONFIG, + assignments: [ + { color: { type: 'gradient' }, rule: { type: 'auto' }, touched: false }, + { color: { type: 'gradient' }, rule: { type: 'auto' }, touched: false }, + ], + + colorMode: { + type: 'gradient', + steps: [ + { + type: 'categorical', + paletteId: EUIAmsterdamColorBlindPalette.id, + colorIndex: 0, + touched: false, + }, + ], + sort: 'asc', + }, + specialAssignments: [ + { + color: { + type: 'categorical', + colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, + paletteId: NeutralPalette.id, + }, + rule: { + type: 'other', + }, + touched: false, + }, + ], + }, + getPaletteFn, + false, + { + type: 'categories', + categories: ['cat1', 'cat2', 'cat3'], + } + ); + expect(toHex(colorFactory('cat1'))).toBe('#cce8e0'); + expect(toHex(colorFactory('cat2'))).toBe(EUI_AMSTERDAM_PALETTE_COLORS[0]); // this matches exactly with the initial step selected - expect(toHex(colorFactory('cat3'))).toBe(toHex(EUI_AMSTERDAM_PALETTE_COLORS[0])); + expect(toHex(colorFactory('cat3'))).toBe(NEUTRAL_COLOR_LIGHT[DEFAULT_NEUTRAL_PALETTE_INDEX]); }); it('returns 2 colors gradient [desc, lightMode]', () => { @@ -287,8 +402,8 @@ describe('Color mapping - color generation', () => { expect(toHex(colorFactory('cat1'))).toBe(toHex(EUI_AMSTERDAM_PALETTE_COLORS[2])); // EUI pink expect(toHex(colorFactory('cat2'))).toBe(NEUTRAL_COLOR_DARK[0]); // NEUTRAL LIGHT GRAY expect(toHex(colorFactory('cat3'))).toBe(toHex(EUI_AMSTERDAM_PALETTE_COLORS[0])); // EUI green - expect(toHex(colorFactory('not available cat'))).toBe( - toHex(NEUTRAL_COLOR_DARK[DEFAULT_NEUTRAL_PALETTE_INDEX]) - ); // check the other + // if the category is not available in the `categories` list then a default netural is used + // this is an edge case and ideally never happen + expect(colorFactory('not_available')).toBe(NEUTRAL_COLOR_DARK[DEFAULT_NEUTRAL_PALETTE_INDEX]); }); }); diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts b/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts index 795f94b740e9b..8867b07572308 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts @@ -6,25 +6,32 @@ * Side Public License, v 1. */ import chroma from 'chroma-js'; +import { findLast } from 'lodash'; import { ColorMapping } from '../config'; import { changeAlpha, combineColors, getValidColor } from './color_math'; -import { generateAutoAssignmentsForCategories } from '../config/assignment_from_categories'; -import { getPalette } from '../palettes'; +import { getPalette, NeutralPalette } from '../palettes'; import { ColorMappingInputData } from '../categorical_color_mapping'; import { ruleMatch } from './rule_matching'; import { GradientColorMode } from '../config/types'; +import { + DEFAULT_NEUTRAL_PALETTE_INDEX, + DEFAULT_OTHER_ASSIGNMENT_INDEX, +} from '../config/default_color_mapping'; export function getAssignmentColor( colorMode: ColorMapping.Config['colorMode'], - color: ColorMapping.Config['assignments'][number]['color'], + color: + | ColorMapping.Config['assignments'][number]['color'] + | (ColorMapping.LoopColor & { paletteId: string; colorIndex: number }), getPaletteFn: ReturnType, isDarkMode: boolean, index: number, total: number -) { +): string { switch (color.type) { case 'colorCode': case 'categorical': + case 'loop': return getColor(color, getPaletteFn, isDarkMode); case 'gradient': { if (colorMode.type === 'categorical') { @@ -37,31 +44,28 @@ export function getAssignmentColor( } export function getColor( - color: ColorMapping.ColorCode | ColorMapping.CategoricalColor, + color: + | ColorMapping.ColorCode + | ColorMapping.CategoricalColor + | (ColorMapping.LoopColor & { paletteId: string; colorIndex: number }), getPaletteFn: ReturnType, isDarkMode: boolean -) { +): string { return color.type === 'colorCode' ? color.colorCode - : getValidColor(getPaletteFn(color.paletteId).getColor(color.colorIndex, isDarkMode)).hex(); + : getValidColor( + getPaletteFn(color.paletteId).getColor(color.colorIndex, isDarkMode, true) + ).hex(); } export function getColorFactory( - model: ColorMapping.Config, + { assignments, specialAssignments, colorMode, paletteId }: ColorMapping.Config, getPaletteFn: ReturnType, isDarkMode: boolean, data: ColorMappingInputData ): (category: string | string[]) => string { - const palette = getPaletteFn(model.paletteId); - // generate on-the-fly assignments in auto-mode based on current data. - // This simplify the code by always using assignments, even if there is no real static assigmnets - const assignments = - model.assignmentMode === 'auto' - ? generateAutoAssignmentsForCategories(data, palette, model.colorMode) - : model.assignments; - // find auto-assigned colors - const autoAssignedColors = + const autoByOrderAssignments = data.type === 'categories' ? assignments.filter((a) => { return ( @@ -71,75 +75,90 @@ export function getColorFactory( : []; // find all categories that doesn't match with an assignment - const nonAssignedCategories = + const notAssignedCategories = data.type === 'categories' ? data.categories.filter((category) => { return !assignments.some(({ rule }) => ruleMatch(rule, category)); }) : []; + const lastCategorical = findLast(assignments, (d) => { + return d.color.type === 'categorical'; + }); + const nextCategoricalIndex = + lastCategorical?.color.type === 'categorical' ? lastCategorical.color.colorIndex + 1 : 0; + return (category: string | string[]) => { if (typeof category === 'string' || Array.isArray(category)) { - const nonAssignedCategoryIndex = nonAssignedCategories.indexOf(category); + const nonAssignedCategoryIndex = notAssignedCategories.indexOf(category); - // return color for a non assigned category + // this category is not assigned to a specific color if (nonAssignedCategoryIndex > -1) { - if (nonAssignedCategoryIndex < autoAssignedColors.length) { + // if the category order is within current number of auto-assigned items pick the defined color + if (nonAssignedCategoryIndex < autoByOrderAssignments.length) { const autoAssignmentIndex = assignments.findIndex( - (d) => d === autoAssignedColors[nonAssignedCategoryIndex] + (d) => d === autoByOrderAssignments[nonAssignedCategoryIndex] ); return getAssignmentColor( - model.colorMode, - autoAssignedColors[nonAssignedCategoryIndex].color, + colorMode, + autoByOrderAssignments[nonAssignedCategoryIndex].color, getPaletteFn, isDarkMode, autoAssignmentIndex, assignments.length ); } - // if no auto-assign color rule/color is available then use the other color - // TODO: the specialAssignment[0] position is arbitrary, we should fix it better - return getColor(model.specialAssignments[0].color, getPaletteFn, isDarkMode); - } + const totalColorsIfGradient = assignments.length || notAssignedCategories.length; + const indexIfGradient = + (nonAssignedCategoryIndex - autoByOrderAssignments.length) % totalColorsIfGradient; - // find the assignment where the category matches the rule - const matchingAssignmentIndex = assignments.findIndex(({ rule }) => { - return ruleMatch(rule, category); - }); - - // return the assigned color - if (matchingAssignmentIndex > -1) { - const assignment = assignments[matchingAssignmentIndex]; + // if no auto-assign color rule/color is available then use the color looping palette return getAssignmentColor( - model.colorMode, - assignment.color, + colorMode, + // TODO: the specialAssignment[0] position is arbitrary, we should fix it better + specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX].color.type === 'loop' + ? colorMode.type === 'gradient' + ? { type: 'gradient' } + : { + type: 'loop', + // those are applied here and depends on the current non-assigned category - auto-assignment list + colorIndex: + nonAssignedCategoryIndex - autoByOrderAssignments.length + nextCategoricalIndex, + paletteId, + } + : specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX].color, getPaletteFn, isDarkMode, - matchingAssignmentIndex, - assignments.length + indexIfGradient, + totalColorsIfGradient ); } - // if no assign color rule/color is available then use the other color - // TODO: the specialAssignment[0] position is arbitrary, we should fix it better - return getColor(model.specialAssignments[0].color, getPaletteFn, isDarkMode); - } else { - const matchingAssignmentIndex = assignments.findIndex(({ rule }) => { - return ruleMatch(rule, category); - }); + } + // find the assignment where the category matches the rule + const matchingAssignmentIndex = assignments.findIndex(({ rule }) => { + return ruleMatch(rule, category); + }); - if (matchingAssignmentIndex > -1) { - const assignment = assignments[matchingAssignmentIndex]; - return getAssignmentColor( - model.colorMode, - assignment.color, - getPaletteFn, - isDarkMode, - matchingAssignmentIndex, - assignments.length - ); - } - return getColor(model.specialAssignments[0].color, getPaletteFn, isDarkMode); + if (matchingAssignmentIndex > -1) { + const assignment = assignments[matchingAssignmentIndex]; + return getAssignmentColor( + colorMode, + assignment.color, + getPaletteFn, + isDarkMode, + matchingAssignmentIndex, + assignments.length + ); } + return getColor( + { + type: 'categorical', + paletteId: NeutralPalette.id, + colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, + }, + getPaletteFn, + isDarkMode + ); }; } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/color/rule_matching.ts b/packages/kbn-coloring/src/shared_components/color_mapping/color/rule_matching.ts index 0d844ca26e27e..a157c7927747c 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/color/rule_matching.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/color/rule_matching.ts @@ -23,7 +23,7 @@ export function ruleMatch( } return rule.values.includes(`${value}`); case 'matchExactlyCI': - return rule.values.some((d) => d.toLowerCase() === `${value}`); + return rule.values.some((d) => d.toLowerCase() === `${value}`.toLowerCase()); case 'range': // TODO: color by value not yet possible in all charts in elastic-charts return typeof value === 'number' ? rangeMatch(rule, value) : false; diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/assignment.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/assignment.tsx index 896f2ea392884..89c4375d4bc10 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/assignment.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/assignment.tsx @@ -31,8 +31,6 @@ export function Assignment({ disableDelete, index, total, - canPickColor, - editable, palette, colorMode, getPaletteFn, @@ -48,8 +46,6 @@ export function Assignment({ disableDelete: boolean; palette: ColorMapping.CategoricalPalette; getPaletteFn: ReturnType; - canPickColor: boolean; - editable: boolean; isDarkMode: boolean; specialTokens: Map; assignmentValuesCounter: Map; @@ -57,18 +53,12 @@ export function Assignment({ const dispatch = useDispatch(); return ( - + { const rule: ColorMapping.RuleRange = { type: 'range', diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/match.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/match.tsx index 1f57e731e84c0..bfef7a270e1a0 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/match.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/match.tsx @@ -15,7 +15,6 @@ import { ColorMapping } from '../../config'; export const Match: React.FC<{ index: number; - editable: boolean; rule: | ColorMapping.RuleAuto | ColorMapping.RuleMatchExactly @@ -25,7 +24,7 @@ export const Match: React.FC<{ options: Array; specialTokens: Map; assignmentValuesCounter: Map; -}> = ({ index, rule, updateValue, editable, options, specialTokens, assignmentValuesCounter }) => { +}> = ({ index, rule, updateValue, options, specialTokens, assignmentValuesCounter }) => { const duplicateWarning = i18n.translate( 'coloring.colorMapping.assignments.duplicateCategoryWarning', { @@ -75,7 +74,6 @@ export const Match: React.FC<{ { - if (selectedOptions.findIndex((option) => option.label.toLowerCase() === label) === -1) { + if (selectedOptions.findIndex((option) => option.label === label) === -1) { updateValue([...selectedOptions, { label, value: label }].map((d) => d.value)); } }} + isCaseSensitive isClearable={false} compressed /> diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/range.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/range.tsx index 70f2cf49609e0..e006a7b23543f 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/range.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/range.tsx @@ -12,9 +12,8 @@ import { ColorMapping } from '../../config'; export const Range: React.FC<{ rule: ColorMapping.RuleRange; - editable: boolean; updateValue: (min: number, max: number, minInclusive: boolean, maxInclusive: boolean) => void; -}> = ({ rule, updateValue, editable }) => { +}> = ({ rule, updateValue }) => { const minValid = rule.min <= rule.max; const maxValid = rule.max >= rule.min; @@ -34,7 +33,6 @@ export const Range: React.FC<{ placeholder="min" value={rule.min} isInvalid={!minValid} - disabled={!editable} onChange={(e) => updateValue(+e.currentTarget.value, rule.max, rule.minInclusive, rule.maxInclusive) } @@ -54,7 +52,6 @@ export const Range: React.FC<{ } placeholder="max" - disabled={!editable} value={rule.max} onChange={(e) => updateValue(rule.min, +e.currentTarget.value, rule.minInclusive, rule.maxInclusive) diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/special_assignment.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/special_assignment.tsx index 29ede59e37f41..fff892fc9cc7b 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/special_assignment.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/assignment/special_assignment.tsx @@ -6,17 +6,16 @@ * Side Public License, v 1. */ -import { EuiFieldText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import React from 'react'; -import { i18n } from '@kbn/i18n'; import { ColorMapping } from '../../config'; import { getPalette } from '../../palettes'; import { ColorSwatch } from '../color_picker/color_swatch'; import { updateSpecialAssignmentColor } from '../../state/color_mapping'; +import { ColorCode, CategoricalColor } from '../../config/types'; export function SpecialAssignment({ - assignment, + assignmentColor, index, palette, getPaletteFn, @@ -25,55 +24,31 @@ export function SpecialAssignment({ }: { isDarkMode: boolean; index: number; - assignment: ColorMapping.Config['specialAssignments'][number]; + assignmentColor: CategoricalColor | ColorCode; palette: ColorMapping.CategoricalPalette; getPaletteFn: ReturnType; total: number; }) { const dispatch = useDispatch(); - const canPickColor = true; return ( - - - { - dispatch( - updateSpecialAssignmentColor({ - assignmentIndex: index, - color, - }) - ); - }} - /> - - - - - + { + dispatch( + updateSpecialAssignmentColor({ + assignmentIndex: index, + color, + }) + ); + }} + /> ); } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_picker.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_picker.tsx index e1e8a08aa6b22..f576daa2096cc 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_picker.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_picker.tsx @@ -107,7 +107,7 @@ export function ColorPicker({ style={{ paddingBottom: 8 }} > {i18n.translate('coloring.colorMapping.colorPicker.removeGradientColorButtonLabel', { - defaultMessage: 'Remove color step', + defaultMessage: 'Remove color stop', })} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_swatch.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_swatch.tsx index 8ddc56d2476c7..34ffbefeca30f 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_swatch.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/color_swatch.tsx @@ -29,11 +29,8 @@ import { getValidColor } from '../../color/color_math'; interface ColorPickerSwatchProps { colorMode: ColorMapping.Config['colorMode']; - assignmentColor: - | ColorMapping.Config['assignments'][number]['color'] - | ColorMapping.Config['specialAssignments'][number]['color']; + assignmentColor: ColorMapping.Config['assignments'][number]['color']; getPaletteFn: ReturnType; - canPickColor: boolean; index: number; total: number; palette: ColorMapping.CategoricalPalette; @@ -46,7 +43,6 @@ export const ColorSwatch = ({ colorMode, assignmentColor, getPaletteFn, - canPickColor, index, total, palette, @@ -71,7 +67,7 @@ export const ColorSwatch = ({ ); const colorIsDark = isColorDark(...getValidColor(colorHex).rgb()); const euiTheme = useEuiTheme(); - return canPickColor && assignmentColor.type !== 'gradient' ? ( + return assignmentColor.type !== 'gradient' ? ( ) : ( @@ -121,7 +117,7 @@ export const ColorSwatch = ({ style={{ // the color swatch can't pickup colors written in rgb/css standard backgroundColor: colorHex, - cursor: canPickColor ? 'pointer' : 'not-allowed', + cursor: 'pointer', width: 32, height: 32, }} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/palette_colors.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/palette_colors.tsx index 21aa18a49f9dc..77a8273654b89 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/palette_colors.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/palette_colors.tsx @@ -35,16 +35,16 @@ export function PaletteColors({ selectColor: (color: ColorMapping.CategoricalColor | ColorMapping.ColorCode) => void; }) { const colors = Array.from({ length: palette.colorCount }, (d, i) => { - return palette.getColor(i, isDarkMode); + return palette.getColor(i, isDarkMode, false); }); const neutralColors = Array.from({ length: NeutralPalette.colorCount }, (d, i) => { - return NeutralPalette.getColor(i, isDarkMode); + return NeutralPalette.getColor(i, isDarkMode, false); }); const originalColor = color.type === 'categorical' ? color.paletteId === NeutralPalette.id - ? NeutralPalette.getColor(color.colorIndex, isDarkMode) - : getPaletteFn(color.paletteId).getColor(color.colorIndex, isDarkMode) + ? NeutralPalette.getColor(color.colorIndex, isDarkMode, false) + : getPaletteFn(color.paletteId).getColor(color.colorIndex, isDarkMode, false) : color.colorCode; return ( <> diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/rgb_picker.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/rgb_picker.tsx index 84f6786922f44..28f155b85fe9b 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/rgb_picker.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/color_picker/rgb_picker.tsx @@ -48,7 +48,8 @@ export function RGBPicker({ customColorMappingColor.type === 'categorical' ? getPaletteFn(customColorMappingColor.paletteId).getColor( customColorMappingColor.colorIndex, - isDarkMode + isDarkMode, + false ) : customColorMappingColor.colorCode; @@ -142,7 +143,7 @@ export function RGBPicker({ if (chromajs.valid(textColor)) { setCustomColorMappingColor({ type: 'colorCode', - colorCode: chromajs(textColor).hex(), + colorCode: textColor, }); } }} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/assigments.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/assigments.tsx new file mode 100644 index 0000000000000..f525311b8afb3 --- /dev/null +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/assigments.tsx @@ -0,0 +1,329 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + EuiButton, + EuiButtonEmpty, + EuiButtonIcon, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiIcon, + EuiNotificationBadge, + EuiPanel, + EuiPopover, + EuiText, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import React, { useCallback, useMemo, useState } from 'react'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { i18n } from '@kbn/i18n'; +import { useDispatch, useSelector } from 'react-redux'; +import { findLast } from 'lodash'; +import { Assignment } from '../assignment/assignment'; +import { + addNewAssignment, + addNewAssignments, + removeAllAssignments, +} from '../../state/color_mapping'; +import { selectColorMode, selectComputedAssignments, selectPalette } from '../../state/selectors'; +import { ColorMappingInputData } from '../../categorical_color_mapping'; +import { ColorMapping } from '../../config'; +import { getPalette, NeutralPalette } from '../../palettes'; +import { ruleMatch } from '../../color/rule_matching'; + +export function AssignmentsConfig({ + data, + palettes, + isDarkMode, + specialTokens, +}: { + palettes: Map; + data: ColorMappingInputData; + isDarkMode: boolean; + /** map between original and formatted tokens used to handle special cases, like the Other bucket and the empty bucket */ + specialTokens: Map; +}) { + const [showOtherActions, setShowOtherActions] = useState(false); + + const dispatch = useDispatch(); + const getPaletteFn = getPalette(palettes, NeutralPalette); + const palette = useSelector(selectPalette(getPaletteFn)); + const colorMode = useSelector(selectColorMode); + const assignments = useSelector(selectComputedAssignments); + + const unmatchingCategories = useMemo(() => { + return data.type === 'categories' + ? data.categories.filter((category) => { + return !assignments.some(({ rule }) => ruleMatch(rule, category)); + }) + : []; + }, [data, assignments]); + + const assignmentValuesCounter = assignments.reduce>( + (acc, assignment) => { + const values = assignment.rule.type === 'matchExactly' ? assignment.rule.values : []; + values.forEach((value) => { + acc.set(value, (acc.get(value) ?? 0) + 1); + }); + return acc; + }, + new Map() + ); + + const onClickAddNewAssignment = useCallback(() => { + const lastCategorical = findLast(assignments, (d) => { + return d.color.type === 'categorical'; + }); + const nextCategoricalIndex = + lastCategorical?.color.type === 'categorical' ? lastCategorical.color.colorIndex + 1 : 0; + dispatch( + addNewAssignment({ + rule: + data.type === 'categories' + ? { + type: 'matchExactly', + values: [], + } + : { type: 'range', min: 0, max: 0, minInclusive: true, maxInclusive: true }, + color: + colorMode.type === 'categorical' + ? { + type: 'categorical', + paletteId: palette.id, + colorIndex: nextCategoricalIndex % palette.colorCount, + } + : { type: 'gradient' }, + touched: false, + }) + ); + }, [assignments, colorMode.type, data.type, dispatch, palette.colorCount, palette.id]); + + const onClickAddAllCurrentCategories = useCallback(() => { + if (data.type === 'categories') { + const lastCategorical = findLast(assignments, (d) => { + return d.color.type === 'categorical'; + }); + const nextCategoricalIndex = + lastCategorical?.color.type === 'categorical' ? lastCategorical.color.colorIndex + 1 : 0; + + const newAssignments: ColorMapping.Config['assignments'] = unmatchingCategories.map( + (c, i) => { + return { + rule: { + type: 'matchExactly', + values: [c], + }, + color: + colorMode.type === 'categorical' + ? { + type: 'categorical', + paletteId: palette.id, + colorIndex: (nextCategoricalIndex + i) % palette.colorCount, + } + : { type: 'gradient' }, + touched: false, + }; + } + ); + dispatch(addNewAssignments(newAssignments)); + } + }, [ + dispatch, + assignments, + colorMode.type, + data.type, + palette.colorCount, + palette.id, + unmatchingCategories, + ]); + + return ( + +
+ + {assignments.map((assignment, i) => { + return ( + + ); + })} + {assignments.length === 0 && ( + +

+ {i18n.translate( + 'coloring.colorMapping.container.mapValuesPromptDescription.mapValuesPromptDetail', + { + defaultMessage: + 'Add new assignments to begin associating terms in your data with specified colors.', + } + )} +

+ + } + actions={[ + + {i18n.translate('coloring.colorMapping.container.AddAssignmentButtonLabel', { + defaultMessage: 'Add assignment', + })} + , + + {i18n.translate('coloring.colorMapping.container.mapValueButtonLabel', { + defaultMessage: 'Add all unassigned terms', + })} + , + ]} + /> + )} +
+
+ {assignments.length > 0 && } +
+ {assignments.length > 0 && ( + + + {i18n.translate('coloring.colorMapping.container.AddAssignmentButtonLabel', { + defaultMessage: 'Add assignment', + })} + + {data.type === 'categories' && ( + setShowOtherActions(true)} + /> + } + isOpen={showOtherActions} + closePopover={() => setShowOtherActions(false)} + panelPaddingSize="xs" + anchorPosition="downRight" + ownFocus + > + { + setShowOtherActions(false); + requestAnimationFrame(() => { + onClickAddAllCurrentCategories(); + }); + }} + disabled={unmatchingCategories.length === 0} + > + + + {i18n.translate( + 'coloring.colorMapping.container.mapCurrentValuesButtonLabel', + { + defaultMessage: 'Add all unsassigned terms', + } + )} + + {unmatchingCategories.length > 0 && ( + + + {unmatchingCategories.length} + + + )} + + , + } + onClick={() => { + setShowOtherActions(false); + dispatch(removeAllAssignments()); + }} + color="danger" + > + {i18n.translate( + 'coloring.colorMapping.container.clearAllAssignmentsButtonLabel', + { + defaultMessage: 'Clear all assignments', + } + )} + , + ]} + /> + + )} + + )} +
+
+ ); +} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/container.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/container.tsx index 748f17fa45842..e3de3c0a24261 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/container.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/container.tsx @@ -8,56 +8,28 @@ import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { - EuiButtonEmpty, - EuiFlexGroup, - EuiFlexItem, - EuiFormLabel, - EuiHorizontalRule, - EuiPanel, - EuiSwitch, - EuiText, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { css } from '@emotion/react'; -import { Assignment } from '../assignment/assignment'; -import { SpecialAssignment } from '../assignment/special_assignment'; import { PaletteSelector } from '../palette_selector/palette_selector'; -import { - RootState, - addNewAssignment, - assignAutomatically, - assignStatically, - changeGradientSortOrder, -} from '../../state/color_mapping'; -import { generateAutoAssignmentsForCategories } from '../../config/assignment_from_categories'; +import { changeGradientSortOrder } from '../../state/color_mapping'; import { ColorMapping } from '../../config'; import { getPalette } from '../../palettes'; -import { getUnusedColorForNewAssignment } from '../../config/assignments'; -import { - selectColorMode, - selectPalette, - selectSpecialAssignments, - selectIsAutoAssignmentMode, -} from '../../state/selectors'; +import { selectColorMode, selectComputedAssignments, selectPalette } from '../../state/selectors'; import { ColorMappingInputData } from '../../categorical_color_mapping'; import { Gradient } from '../palette_selector/gradient'; import { NeutralPalette } from '../../palettes/neutral'; +import { ScaleMode } from '../palette_selector/scale'; +import { UnassignedTermsConfig } from './unassigned_terms_config'; +import { AssignmentsConfig } from './assigments'; -export const MAX_ASSIGNABLE_COLORS = 10; - -function selectComputedAssignments( - data: ColorMappingInputData, - palette: ColorMapping.CategoricalPalette, - colorMode: ColorMapping.Config['colorMode'] -) { - return (state: RootState) => - state.colorMapping.assignmentMode === 'auto' - ? generateAutoAssignmentsForCategories(data, palette, colorMode) - : state.colorMapping.assignments; -} -export function Container(props: { +export function Container({ + data, + palettes, + isDarkMode, + specialTokens, +}: { palettes: Map; data: ColorMappingInputData; isDarkMode: boolean; @@ -66,187 +38,99 @@ export function Container(props: { }) { const dispatch = useDispatch(); - const getPaletteFn = getPalette(props.palettes, NeutralPalette); + const getPaletteFn = getPalette(palettes, NeutralPalette); const palette = useSelector(selectPalette(getPaletteFn)); const colorMode = useSelector(selectColorMode); - const autoAssignmentMode = useSelector(selectIsAutoAssignmentMode); - const assignments = useSelector(selectComputedAssignments(props.data, palette, colorMode)); - const specialAssignments = useSelector(selectSpecialAssignments); - - const canAddNewAssignment = !autoAssignmentMode && assignments.length < MAX_ASSIGNABLE_COLORS; - - const assignmentValuesCounter = assignments.reduce>( - (acc, assignment) => { - const values = assignment.rule.type === 'matchExactly' ? assignment.rule.values : []; - values.forEach((value) => { - acc.set(value, (acc.get(value) ?? 0) + 1); - }); - return acc; - }, - new Map() - ); + const assignments = useSelector(selectComputedAssignments); return ( - - - - + - + - - {i18n.translate('coloring.colorMapping.container.mappingAssignmentHeader', { - defaultMessage: 'Mapping assignments', - })} - + - - {i18n.translate('coloring.colorMapping.container.autoAssignLabel', { - defaultMessage: 'Auto assign', - })} - - } - checked={autoAssignmentMode} - compressed - onChange={() => { - if (autoAssignmentMode) { - dispatch(assignStatically(assignments)); - } else { - dispatch(assignAutomatically()); - } - }} - /> + - - + {colorMode.type === 'gradient' && ( +
- {colorMode.type !== 'gradient' ? null : ( - - )} - {assignments.map((assignment, i) => { - return ( -
- -
- ); - })} -
- - - - - {props.data.type === 'categories' && - specialAssignments.map((assignment, i) => { - return ( - - ); - })} - - -
- - - { - dispatch( - addNewAssignment({ - rule: - props.data.type === 'categories' - ? { - type: 'matchExactly', - values: [], - } - : { type: 'range', min: 0, max: 0, minInclusive: true, maxInclusive: true }, - color: getUnusedColorForNewAssignment(palette, colorMode, assignments), - touched: false, - }) - ); - }} - disabled={!canAddNewAssignment} - css={css` - margin-right: 8px; - `} - > - {i18n.translate('coloring.colorMapping.container.addAssignmentButtonLabel', { - defaultMessage: 'Add assignment', + - {colorMode.type === 'gradient' && ( - + { dispatch(changeGradientSortOrder(colorMode.sort === 'asc' ? 'desc' : 'asc')); }} - > - {i18n.translate('coloring.colorMapping.container.invertGradientButtonLabel', { - defaultMessage: 'Invert gradient', - })} - - )} - - + /> + + + + + +
+ )} + + + + + + {assignments.length > 0 && ( + + + + )}
); } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx new file mode 100644 index 0000000000000..8e90bcc38d119 --- /dev/null +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { + EuiButtonGroup, + EuiButtonGroupOptionProps, + EuiColorPickerSwatch, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useDispatch, useSelector } from 'react-redux'; +import { css } from '@emotion/react'; +import { updateSpecialAssignmentColor } from '../../state/color_mapping'; +import { getPalette, NeutralPalette } from '../../palettes'; +import { + DEFAULT_NEUTRAL_PALETTE_INDEX, + DEFAULT_OTHER_ASSIGNMENT_INDEX, +} from '../../config/default_color_mapping'; +import { SpecialAssignment } from '../assignment/special_assignment'; +import { ColorMapping } from '../../config'; +import { selectColorMode, selectPalette, selectSpecialAssignments } from '../../state/selectors'; +import { ColorMappingInputData } from '../../categorical_color_mapping'; + +export function UnassignedTermsConfig({ + palettes, + data, + isDarkMode, +}: { + palettes: Map; + data: ColorMappingInputData; + isDarkMode: boolean; +}) { + const dispatch = useDispatch(); + + const getPaletteFn = getPalette(palettes, NeutralPalette); + + const palette = useSelector(selectPalette(getPaletteFn)); + const colorMode = useSelector(selectColorMode); + const specialAssignments = useSelector(selectSpecialAssignments); + const otherAssignment = specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX]; + + const colorModes: EuiButtonGroupOptionProps[] = [ + { + id: 'loop', + label: + colorMode.type === 'gradient' + ? i18n.translate( + 'coloring.colorMapping.container.unassignedTermsMode.ReuseGradientLabel', + { + defaultMessage: 'Gradient', + } + ) + : i18n.translate('coloring.colorMapping.container.unassignedTermsMode.ReuseColorsLabel', { + defaultMessage: 'Color palette', + }), + }, + { + id: 'static', + label: i18n.translate( + 'coloring.colorMapping.container.unassignedTermsMode.SingleColorLabel', + { + defaultMessage: 'Single color', + } + ), + }, + ]; + + return ( + + + + { + dispatch( + updateSpecialAssignmentColor({ + assignmentIndex: 0, + color: + optionId === 'loop' + ? { + type: 'loop', + } + : { + type: 'categorical', + colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, + paletteId: NeutralPalette.id, + }, + }) + ); + }} + buttonSize="compressed" + isFullWidth + /> + + + + {data.type === 'categories' && otherAssignment.color.type !== 'loop' ? ( + + ) : ( + + )} + + + + ); +} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient.tsx index c4e22f797deaa..99eda60166ac4 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient.tsx @@ -6,331 +6,174 @@ * Side Public License, v 1. */ -import { euiFocusRing, EuiIcon, euiShadowSmall, useEuiTheme } from '@elastic/eui'; import React from 'react'; -import { useDispatch } from 'react-redux'; - import { euiThemeVars } from '@kbn/ui-theme'; import { css } from '@emotion/react'; +import { useDispatch } from 'react-redux'; import { changeAlpha } from '../../color/color_math'; - import { ColorMapping } from '../../config'; -import { ColorSwatch } from '../color_picker/color_swatch'; import { getPalette } from '../../palettes'; - -import { addGradientColorStep, updateGradientColorStep } from '../../state/color_mapping'; -import { colorPickerVisibility } from '../../state/ui'; import { getGradientColorScale } from '../../color/color_handling'; +import { AddStop } from './gradient_add_stop'; +import { ColorSwatch } from '../color_picker/color_swatch'; +import { updateGradientColorStep } from '../../state/color_mapping'; export function Gradient({ paletteId, colorMode, getPaletteFn, isDarkMode, - assignmentsSize, }: { paletteId: string; isDarkMode: boolean; colorMode: ColorMapping.Config['colorMode']; getPaletteFn: ReturnType; - assignmentsSize: number; }) { + const dispatch = useDispatch(); if (colorMode.type === 'categorical') { return null; } + const currentPalette = getPaletteFn(paletteId); const gradientColorScale = getGradientColorScale(colorMode, getPaletteFn, isDarkMode); - const topMostColorStop = + const startStepColor = colorMode.sort === 'asc' ? colorMode.steps.length === 1 ? undefined : colorMode.steps.at(-1) : colorMode.steps.at(0); - const topMostColorStopIndex = + const startStepIndex = colorMode.sort === 'asc' ? colorMode.steps.length === 1 ? NaN : colorMode.steps.length - 1 : 0; - const bottomMostColorStop = + const endStepColor = colorMode.sort === 'asc' ? colorMode.steps.at(0) : colorMode.steps.length === 1 ? undefined : colorMode.steps.at(-1); - const bottomMostColorStopIndex = + const endStepIndex = colorMode.sort === 'asc' ? 0 : colorMode.steps.length === 1 ? NaN : colorMode.steps.length - 1; - const middleMostColorSep = colorMode.steps.length === 3 ? colorMode.steps[1] : undefined; - const middleMostColorStopIndex = colorMode.steps.length === 3 ? 1 : NaN; + const middleStepColor = colorMode.steps.length === 3 ? colorMode.steps[1] : undefined; + const middleStepIndex = colorMode.steps.length === 3 ? 1 : NaN; return ( - <> - {assignmentsSize > 1 && ( -
- )} +
+ +
- {topMostColorStop ? ( - { + dispatch(updateGradientColorStep({ index: startStepIndex, color })); + }} /> ) : ( )}
- {assignmentsSize > 1 && ( -
-
- {middleMostColorSep ? ( - - ) : colorMode.steps.length === 2 ? ( - - ) : undefined} -
-
- )} - {assignmentsSize > 1 && ( -
- )} -
- {bottomMostColorStop ? ( - { + dispatch(updateGradientColorStep({ index: middleStepIndex, color })); + }} /> - ) : ( + ) : colorMode.steps.length === 2 ? ( - )} + ) : undefined}
- - ); -} - -function AddStop({ - colorMode, - currentPalette, - at, -}: { - colorMode: { - type: 'gradient'; - steps: Array<(ColorMapping.CategoricalColor | ColorMapping.ColorCode) & { touched: boolean }>; - }; - currentPalette: ColorMapping.CategoricalPalette; - at: number; -}) { - const euiTheme = useEuiTheme(); - const dispatch = useDispatch(); - return ( - - ); -} - -function ColorStop({ - colorMode, - step, - index, - currentPalette, - getPaletteFn, - isDarkMode, -}: { - colorMode: ColorMapping.GradientColorMode; - step: ColorMapping.CategoricalColor | ColorMapping.ColorCode; - index: number; - currentPalette: ColorMapping.CategoricalPalette; - getPaletteFn: ReturnType; - isDarkMode: boolean; -}) { - const dispatch = useDispatch(); - return ( - { - dispatch( - updateGradientColorStep({ - index, - color, - }) - ); - }} - forType="gradient" - /> +
); } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient_add_stop.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient_add_stop.tsx new file mode 100644 index 0000000000000..713e780bc32da --- /dev/null +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/gradient_add_stop.tsx @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React from 'react'; + +import { + euiCanAnimate, + euiFocusRing, + EuiIcon, + euiShadowSmall, + EuiToolTip, + useEuiTheme, +} from '@elastic/eui'; +import { useDispatch } from 'react-redux'; +import { i18n } from '@kbn/i18n'; +import { css } from '@emotion/react'; +import { ColorMapping } from '../../config'; +import { addGradientColorStep } from '../../state/color_mapping'; +import { colorPickerVisibility } from '../../state/ui'; + +export function AddStop({ + colorMode, + currentPalette, + at, +}: { + colorMode: ColorMapping.GradientColorMode; + currentPalette: ColorMapping.CategoricalPalette; + at: number; +}) { + const euiTheme = useEuiTheme(); + const dispatch = useDispatch(); + return ( + <> + + + + + ); +} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/palette_selector.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/palette_selector.tsx index c9fab3526a786..3db54cea6b108 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/palette_selector.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/palette_selector.tsx @@ -8,14 +8,7 @@ import React, { useCallback, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { - EuiButtonGroup, - EuiColorPalettePicker, - EuiConfirmModal, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, -} from '@elastic/eui'; +import { EuiColorPalettePicker, EuiConfirmModal, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { RootState, updatePalette } from '../../state/color_mapping'; @@ -33,11 +26,8 @@ export function PaletteSelector({ isDarkMode: boolean; }) { const dispatch = useDispatch(); - const colorMode = useSelector((state: RootState) => state.colorMapping.colorMode); const model = useSelector((state: RootState) => state.colorMapping); - const { paletteId } = model; - const switchPaletteFn = useCallback( (selectedPaletteId: string, preserveColorChanges: boolean) => { dispatch( @@ -45,7 +35,6 @@ export function PaletteSelector({ paletteId: selectedPaletteId, assignments: updateAssignmentsPalette( model.assignments, - model.assignmentMode, model.colorMode, selectedPaletteId, getPaletteFn, @@ -62,37 +51,6 @@ export function PaletteSelector({ [getPaletteFn, model, dispatch] ); - const updateColorMode = useCallback( - (type: 'gradient' | 'categorical', preserveColorChanges: boolean) => { - const updatedColorMode: ColorMapping.Config['colorMode'] = - type === 'gradient' - ? { - type: 'gradient', - steps: [ - { - type: 'categorical', - paletteId, - colorIndex: 0, - touched: false, - }, - ], - sort: 'desc', - } - : { type: 'categorical' }; - - const assignments = updateAssignmentsPalette( - model.assignments, - model.assignmentMode, - updatedColorMode, - paletteId, - getPaletteFn, - preserveColorChanges - ); - dispatch(updatePalette({ paletteId, assignments, colorMode: updatedColorMode })); - }, - [getPaletteFn, model, dispatch, paletteId] - ); - const [preserveModalPaletteId, setPreserveModalPaletteId] = useState(null); const preserveChangesModal = @@ -126,136 +84,44 @@ export function PaletteSelector({ ) : null; - const [colorScaleModalId, setColorScaleModalId] = useState<'gradient' | 'categorical' | null>( - null - ); - - const colorScaleModal = - colorScaleModalId !== null ? ( - { - setColorScaleModalId(null); - }} - onConfirm={() => { - if (colorScaleModalId) updateColorMode(colorScaleModalId, false); - setColorScaleModalId(null); - }} - cancelButtonText={i18n.translate( - 'coloring.colorMapping.colorChangesModal.goBackButtonLabel', - { - defaultMessage: 'Go back', - } - )} - confirmButtonText={i18n.translate( - 'coloring.colorMapping.colorChangesModal.discardButtonLabel', - { - defaultMessage: 'Discard changes', - } - )} - defaultFocusedButton="confirm" - buttonColor="danger" - > -

- {colorScaleModalId === 'categorical' - ? i18n.translate('coloring.colorMapping.colorChangesModal.categoricalModeDescription', { - defaultMessage: `Switching to a categorical mode will discard all your custom color changes`, - }) - : i18n.translate('coloring.colorMapping.colorChangesModal.sequentialModeDescription', { - defaultMessage: `Switching to a sequential mode will discard all your custom color changes`, - })} -

-
- ) : null; - return ( <> {preserveChangesModal} - {colorScaleModal} - - - - d.name !== 'Neutral') - .map((palette) => ({ - 'data-test-subj': `kbnColoring_ColorMapping_Palette-${palette.id}`, - value: palette.id, - title: palette.name, - palette: Array.from({ length: palette.colorCount }, (_, i) => { - return palette.getColor(i, isDarkMode); - }), - type: 'fixed', - }))} - onChange={(selectedPaletteId) => { - const hasChanges = model.assignments.some((a) => a.touched); - const hasGradientChanges = - model.colorMode.type === 'gradient' && - model.colorMode.steps.some((a) => a.touched); - if (hasChanges || hasGradientChanges) { - setPreserveModalPaletteId(selectedPaletteId); - } else { - switchPaletteFn(selectedPaletteId, false); - } - }} - valueOfSelected={model.paletteId} - selectionDisplay={'palette'} - compressed={true} - /> - - - - - { - const hasChanges = model.assignments.some((a) => a.touched); - const hasGradientChanges = - model.colorMode.type === 'gradient' && - model.colorMode.steps.some((a) => a.touched); - - if (hasChanges || hasGradientChanges) { - setColorScaleModalId(id as 'gradient' | 'categorical'); - } else { - updateColorMode(id as 'gradient' | 'categorical', false); - } - }} - isIconOnly - /> - - - + + d.name !== 'Neutral') + .map((palette) => ({ + 'data-test-subj': `kbnColoring_ColorMapping_Palette-${palette.id}`, + value: palette.id, + title: palette.name, + palette: Array.from({ length: palette.colorCount }, (_, i) => { + return palette.getColor(i, isDarkMode, false); + }), + type: 'fixed', + }))} + onChange={(selectedPaletteId) => { + const hasChanges = model.assignments.some((a) => a.touched); + const hasGradientChanges = + model.colorMode.type === 'gradient' && model.colorMode.steps.some((a) => a.touched); + if (hasChanges || hasGradientChanges) { + setPreserveModalPaletteId(selectedPaletteId); + } else { + switchPaletteFn(selectedPaletteId, false); + } + }} + valueOfSelected={model.paletteId} + selectionDisplay={'palette'} + compressed={true} + /> + ); } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/scale.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/scale.tsx new file mode 100644 index 0000000000000..056db47157c60 --- /dev/null +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/palette_selector/scale.tsx @@ -0,0 +1,144 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { useCallback, useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { EuiButtonGroup, EuiConfirmModal, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { RootState, updatePalette } from '../../state/color_mapping'; +import { ColorMapping } from '../../config'; +import { updateAssignmentsPalette } from '../../config/assignments'; +import { getPalette } from '../../palettes'; + +export function ScaleMode({ getPaletteFn }: { getPaletteFn: ReturnType }) { + const dispatch = useDispatch(); + const colorMode = useSelector((state: RootState) => state.colorMapping.colorMode); + const model = useSelector((state: RootState) => state.colorMapping); + + const { paletteId } = model; + + const updateColorMode = useCallback( + (type: 'gradient' | 'categorical', preserveColorChanges: boolean) => { + const updatedColorMode: ColorMapping.Config['colorMode'] = + type === 'gradient' + ? { + type: 'gradient', + steps: [ + { + type: 'categorical', + paletteId, + colorIndex: 0, + touched: false, + }, + ], + sort: 'desc', + } + : { type: 'categorical' }; + + const assignments = updateAssignmentsPalette( + model.assignments, + updatedColorMode, + paletteId, + getPaletteFn, + preserveColorChanges + ); + dispatch(updatePalette({ paletteId, assignments, colorMode: updatedColorMode })); + }, + [getPaletteFn, model, dispatch, paletteId] + ); + + const [colorScaleModalId, setColorScaleModalId] = useState<'gradient' | 'categorical' | null>( + null + ); + + const colorScaleModal = + colorScaleModalId !== null ? ( + { + setColorScaleModalId(null); + }} + onConfirm={() => { + if (colorScaleModalId) updateColorMode(colorScaleModalId, false); + setColorScaleModalId(null); + }} + cancelButtonText={i18n.translate( + 'coloring.colorMapping.colorChangesModal.goBackButtonLabel', + { + defaultMessage: 'Go back', + } + )} + confirmButtonText={i18n.translate( + 'coloring.colorMapping.colorChangesModal.discardButtonLabel', + { + defaultMessage: 'Discard changes', + } + )} + defaultFocusedButton="confirm" + buttonColor="danger" + > +

+ {colorScaleModalId === 'categorical' + ? i18n.translate('coloring.colorMapping.colorChangesModal.categoricalModeDescription', { + defaultMessage: `Switching to a categorical mode will discard all your custom color changes`, + }) + : i18n.translate('coloring.colorMapping.colorChangesModal.sequentialModeDescription', { + defaultMessage: `Switching to a gradient mode will discard all your custom color changes`, + })} +

+
+ ) : null; + + return ( + <> + {colorScaleModal} + + { + const hasChanges = model.assignments.some((a) => a.touched); + const hasGradientChanges = + model.colorMode.type === 'gradient' && model.colorMode.steps.some((a) => a.touched); + + if (hasChanges || hasGradientChanges) { + setColorScaleModalId(id as 'gradient' | 'categorical'); + } else { + updateColorMode(id as 'gradient' | 'categorical', false); + } + }} + /> + + + ); +} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/config/assignment_from_categories.ts b/packages/kbn-coloring/src/shared_components/color_mapping/config/assignment_from_categories.ts deleted file mode 100644 index 97c4d17c35e4d..0000000000000 --- a/packages/kbn-coloring/src/shared_components/color_mapping/config/assignment_from_categories.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { ColorMapping } from '.'; -import { ColorMappingInputData } from '../categorical_color_mapping'; -import { MAX_ASSIGNABLE_COLORS } from '../components/container/container'; - -export function generateAutoAssignmentsForCategories( - data: ColorMappingInputData, - palette: ColorMapping.CategoricalPalette, - colorMode: ColorMapping.Config['colorMode'] -): ColorMapping.Config['assignments'] { - const isCategorical = colorMode.type === 'categorical'; - - const maxColorAssignable = data.type === 'categories' ? data.categories.length : data.bins; - - const assignableColors = isCategorical - ? Math.min(palette.colorCount, maxColorAssignable) - : Math.min(MAX_ASSIGNABLE_COLORS, maxColorAssignable); - - const autoRules: Array = - data.type === 'categories' - ? data.categories.map((c) => ({ type: 'matchExactly', values: [c] })) - : Array.from({ length: data.bins }, (d, i) => { - const step = (data.max - data.min) / data.bins; - return { - type: 'range', - min: data.max - i * step - step, - max: data.max - i * step, - minInclusive: true, - maxInclusive: false, - }; - }); - - const assignments = autoRules - .slice(0, assignableColors) - .map((rule, colorIndex) => { - if (isCategorical) { - return { - rule, - color: { - type: 'categorical', - paletteId: palette.id, - colorIndex, - }, - touched: false, - }; - } else { - return { - rule, - color: { - type: 'gradient', - }, - touched: false, - }; - } - }); - - return assignments; -} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/config/assignments.ts b/packages/kbn-coloring/src/shared_components/color_mapping/config/assignments.ts index 701baa1b1710b..ce21732122150 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/config/assignments.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/config/assignments.ts @@ -7,41 +7,35 @@ */ import type { ColorMapping } from '.'; -import { MAX_ASSIGNABLE_COLORS } from '../components/container/container'; -import { getPalette, NeutralPalette } from '../palettes'; -import { DEFAULT_NEUTRAL_PALETTE_INDEX } from './default_color_mapping'; +import { getPalette } from '../palettes'; export function updateAssignmentsPalette( assignments: ColorMapping.Config['assignments'], - assignmentMode: ColorMapping.Config['assignmentMode'], colorMode: ColorMapping.Config['colorMode'], paletteId: string, getPaletteFn: ReturnType, preserveColorChanges: boolean ): ColorMapping.Config['assignments'] { const palette = getPaletteFn(paletteId); - const maxColors = palette.type === 'categorical' ? palette.colorCount : MAX_ASSIGNABLE_COLORS; - return assignmentMode === 'auto' - ? [] - : assignments.map(({ rule, color, touched }, index) => { - if (preserveColorChanges && touched) { - return { rule, color, touched }; - } else { - const newColor: ColorMapping.Config['assignments'][number]['color'] = - colorMode.type === 'categorical' - ? { - type: 'categorical', - paletteId: index < maxColors ? paletteId : NeutralPalette.id, - colorIndex: index < maxColors ? index : 0, - } - : { type: 'gradient' }; - return { - rule, - color: newColor, - touched: false, - }; - } - }); + return assignments.map(({ rule, color, touched }, index) => { + if (preserveColorChanges && touched) { + return { rule, color, touched }; + } else { + const newColor: ColorMapping.Config['assignments'][number]['color'] = + colorMode.type === 'categorical' + ? { + type: 'categorical', + paletteId, + colorIndex: index % palette.colorCount, + } + : { type: 'gradient' }; + return { + rule, + color: newColor, + touched: false, + }; + } + }); } export function updateColorModePalette( @@ -61,31 +55,3 @@ export function updateColorModePalette( sort: colorMode.sort, }; } - -export function getUnusedColorForNewAssignment( - palette: ColorMapping.CategoricalPalette, - colorMode: ColorMapping.Config['colorMode'], - assignments: ColorMapping.Config['assignments'] -): ColorMapping.Config['assignments'][number]['color'] { - if (colorMode.type === 'categorical') { - // TODO: change the type of color assignment depending on palette - // compute the next unused color index in the palette. - const maxColors = palette.type === 'categorical' ? palette.colorCount : MAX_ASSIGNABLE_COLORS; - const colorIndices = new Set(Array.from({ length: maxColors }, (d, i) => i)); - assignments.forEach(({ color }) => { - if (color.type === 'categorical' && color.paletteId === palette.id) { - colorIndices.delete(color.colorIndex); - } - }); - const paletteForNextUnusedColorIndex = colorIndices.size > 0 ? palette.id : NeutralPalette.id; - const nextUnusedColorIndex = - colorIndices.size > 0 ? [...colorIndices][0] : DEFAULT_NEUTRAL_PALETTE_INDEX; - return { - type: 'categorical', - paletteId: paletteForNextUnusedColorIndex, - colorIndex: nextUnusedColorIndex, - }; - } else { - return { type: 'gradient' }; - } -} diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts b/packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts index e4005770b2883..8a6ae646b7b6b 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts @@ -13,12 +13,12 @@ import { NeutralPalette } from '../palettes/neutral'; import { getColor, getGradientColorScale } from '../color/color_handling'; export const DEFAULT_NEUTRAL_PALETTE_INDEX = 1; +export const DEFAULT_OTHER_ASSIGNMENT_INDEX = 0; /** * The default color mapping used in Kibana, starts with the EUI color palette */ export const DEFAULT_COLOR_MAPPING_CONFIG: ColorMapping.Config = { - assignmentMode: 'auto', assignments: [], specialAssignments: [ { @@ -26,9 +26,7 @@ export const DEFAULT_COLOR_MAPPING_CONFIG: ColorMapping.Config = { type: 'other', }, color: { - type: 'categorical', - paletteId: NeutralPalette.id, - colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, + type: 'loop', }, touched: false, }, @@ -45,17 +43,26 @@ export function getPaletteColors( ): string[] { const colorMappingModel = colorMappings ?? { ...DEFAULT_COLOR_MAPPING_CONFIG }; const palette = getPalette(AVAILABLE_PALETTES, NeutralPalette)(colorMappingModel.paletteId); - return Array.from({ length: palette.colorCount }, (d, i) => palette.getColor(i, isDarkMode)); + return getPaletteColorsFromPaletteId(isDarkMode, palette.id); +} + +export function getPaletteColorsFromPaletteId( + isDarkMode: boolean, + paletteId: ColorMapping.Config['paletteId'] +): string[] { + const palette = getPalette(AVAILABLE_PALETTES, NeutralPalette)(paletteId); + return Array.from({ length: palette.colorCount }, (d, i) => + palette.getColor(i, isDarkMode, true) + ); } export function getColorsFromMapping( isDarkMode: boolean, colorMappings?: ColorMapping.Config ): string[] { - const { colorMode, paletteId, assignmentMode, assignments, specialAssignments } = - colorMappings ?? { - ...DEFAULT_COLOR_MAPPING_CONFIG, - }; + const { colorMode, paletteId, assignments, specialAssignments } = colorMappings ?? { + ...DEFAULT_COLOR_MAPPING_CONFIG, + }; const getPaletteFn = getPalette(AVAILABLE_PALETTES, NeutralPalette); if (colorMode.type === 'gradient') { @@ -63,17 +70,23 @@ export function getColorsFromMapping( return Array.from({ length: 6 }, (d, i) => colorScale(i / 6)); } else { const palette = getPaletteFn(paletteId); - if (assignmentMode === 'auto') { - return Array.from({ length: palette.colorCount }, (d, i) => palette.getColor(i, isDarkMode)); - } else { - return [ - ...assignments.map((a) => { - return a.color.type === 'gradient' ? '' : getColor(a.color, getPaletteFn, isDarkMode); - }), - ...specialAssignments.map((a) => { - return getColor(a.color, getPaletteFn, isDarkMode); - }), - ].filter((color) => color !== ''); - } + const otherColors = + specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX].color.type === 'loop' + ? Array.from({ length: palette.colorCount }, (d, i) => + palette.getColor(i, isDarkMode, true) + ) + : [ + getColor( + specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX].color, + getPaletteFn, + isDarkMode + ), + ]; + return [ + ...assignments.map((a) => { + return a.color.type === 'gradient' ? '' : getColor(a.color, getPaletteFn, isDarkMode); + }), + ...otherColors, + ].filter((color) => color !== ''); } } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/config/types.ts b/packages/kbn-coloring/src/shared_components/color_mapping/config/types.ts index 59cb18435112d..4c62044be9242 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/config/types.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/config/types.ts @@ -30,6 +30,13 @@ export interface GradientColor { type: 'gradient'; } +/** + * An index specified categorical color, coming from paletteId + */ +export interface LoopColor { + type: 'loop'; +} + /** * A special rule that match automatically, in order, all the categories that are not matching a specified rule */ @@ -134,14 +141,13 @@ export interface GradientColorMode { export interface Config { paletteId: string; colorMode: CategoricalColorMode | GradientColorMode; - assignmentMode: 'auto' | 'manual'; assignments: Array< Assignment< RuleAuto | RuleMatchExactly | RuleMatchExactlyCI | RuleRange | RuleRegExp, CategoricalColor | ColorCode | GradientColor > >; - specialAssignments: Array>; + specialAssignments: Array>; } export interface CategoricalPalette { @@ -149,5 +155,5 @@ export interface CategoricalPalette { name: string; type: 'categorical'; colorCount: number; - getColor: (valueInRange: number, isDarkMode: boolean) => string; + getColor: (valueInRange: number, isDarkMode: boolean, loop: boolean) => string; } diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/index.ts b/packages/kbn-coloring/src/shared_components/color_mapping/index.ts index 1b49a2c6a8bf3..7484eabe816ab 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/index.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/index.ts @@ -14,6 +14,7 @@ export * from './color/color_handling'; export { SPECIAL_TOKENS_STRING_CONVERTION } from './color/rule_matching'; export { DEFAULT_COLOR_MAPPING_CONFIG, + DEFAULT_OTHER_ASSIGNMENT_INDEX, getPaletteColors, getColorsFromMapping, } from './config/default_color_mapping'; diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts index d93440c5ac5e4..ce13184ff062a 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts @@ -22,7 +22,9 @@ export const ElasticBrandPalette: ColorMapping.CategoricalPalette = { name: 'Elastic Brand', colorCount: ELASTIC_BRAND_PALETTE_COLORS.length, type: 'categorical', - getColor(valueInRange) { - return ELASTIC_BRAND_PALETTE_COLORS[valueInRange]; + getColor(indexInRange, isDarkMode, loop) { + return ELASTIC_BRAND_PALETTE_COLORS[ + loop ? indexInRange % ELASTIC_BRAND_PALETTE_COLORS.length : indexInRange + ]; }, }; diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts index ec48793e12819..f9836a400b877 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts @@ -26,7 +26,9 @@ export const EUIAmsterdamColorBlindPalette: ColorMapping.CategoricalPalette = { name: 'Default', colorCount: EUI_AMSTERDAM_PALETTE_COLORS.length, type: 'categorical', - getColor(valueInRange) { - return EUI_AMSTERDAM_PALETTE_COLORS[valueInRange]; + getColor(indexInRange, isDarkMode, loop) { + return EUI_AMSTERDAM_PALETTE_COLORS[ + loop ? indexInRange % EUI_AMSTERDAM_PALETTE_COLORS.length : indexInRange + ]; }, }; diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts index 9b576e0b05c66..bb90130a817fe 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts @@ -23,7 +23,9 @@ export const KibanaV7LegacyPalette: ColorMapping.CategoricalPalette = { name: 'Kibana Legacy', colorCount: KIBANA_V7_LEGACY_PALETTE_COLORS.length, type: 'categorical', - getColor(valueInRange) { - return KIBANA_V7_LEGACY_PALETTE_COLORS[valueInRange]; + getColor(indexInRange, isDarkMode, loop) { + return KIBANA_V7_LEGACY_PALETTE_COLORS[ + loop ? indexInRange % KIBANA_V7_LEGACY_PALETTE_COLORS.length : indexInRange + ]; }, }; diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/state/color_mapping.ts b/packages/kbn-coloring/src/shared_components/color_mapping/state/color_mapping.ts index 27588aff2b389..704dbedcfec23 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/state/color_mapping.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/state/color_mapping.ts @@ -9,6 +9,7 @@ import { createSlice } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit'; import type { ColorMapping } from '../config'; +import { DEFAULT_OTHER_ASSIGNMENT_INDEX } from '../config/default_color_mapping'; export interface RootState { colorMapping: ColorMapping.Config; @@ -22,7 +23,6 @@ export interface RootState { } const initialState: RootState['colorMapping'] = { - assignmentMode: 'auto', assignments: [], specialAssignments: [], paletteId: 'eui', @@ -34,7 +34,6 @@ export const colorMappingSlice = createSlice({ initialState, reducers: { updateModel: (state, action: PayloadAction) => { - state.assignmentMode = action.payload.assignmentMode; state.assignments = [...action.payload.assignments]; state.specialAssignments = [...action.payload.specialAssignments]; state.paletteId = action.payload.paletteId; @@ -53,11 +52,9 @@ export const colorMappingSlice = createSlice({ state.colorMode = { ...action.payload.colorMode }; }, assignStatically: (state, action: PayloadAction) => { - state.assignmentMode = 'manual'; state.assignments = [...action.payload]; }, assignAutomatically: (state) => { - state.assignmentMode = 'auto'; state.assignments = []; }, @@ -67,6 +64,9 @@ export const colorMappingSlice = createSlice({ ) => { state.assignments.push({ ...action.payload }); }, + addNewAssignments: (state, action: PayloadAction) => { + state.assignments.push(...action.payload); + }, updateAssignment: ( state, action: PayloadAction<{ @@ -120,6 +120,21 @@ export const colorMappingSlice = createSlice({ }, removeAssignment: (state, action: PayloadAction) => { state.assignments.splice(action.payload, 1); + if (state.assignments.length === 0) { + state.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX] = { + ...state.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX], + color: { type: 'loop' }, + touched: true, + }; + } + }, + removeAllAssignments: (state) => { + state.assignments = []; + state.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX] = { + ...state.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX], + color: { type: 'loop' }, + touched: true, + }; }, changeColorMode: (state, action: PayloadAction) => { state.colorMode = { ...action.payload }; @@ -209,11 +224,13 @@ export const { assignStatically, assignAutomatically, addNewAssignment, + addNewAssignments, updateAssignment, updateAssignmentColor, updateSpecialAssignmentColor, updateAssignmentRule, removeAssignment, + removeAllAssignments, changeColorMode, updateGradientColorStep, removeGradientColorStep, diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/state/selectors.ts b/packages/kbn-coloring/src/shared_components/color_mapping/state/selectors.ts index 69bd57d2d852e..07cfdb9af0a79 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/state/selectors.ts +++ b/packages/kbn-coloring/src/shared_components/color_mapping/state/selectors.ts @@ -18,9 +18,9 @@ export function selectColorMode(state: RootState) { export function selectSpecialAssignments(state: RootState) { return state.colorMapping.specialAssignments; } -export function selectIsAutoAssignmentMode(state: RootState) { - return state.colorMapping.assignmentMode === 'auto'; -} export function selectColorPickerVisibility(state: RootState) { return state.ui.colorPicker; } +export function selectComputedAssignments(state: RootState) { + return state.colorMapping.assignments; +} diff --git a/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.test.ts b/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.test.ts index d6a6701aa658a..7998ba5bda3c0 100644 --- a/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.test.ts +++ b/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.test.ts @@ -10,35 +10,17 @@ import { ColorMapping, EUIAmsterdamColorBlindPalette, ElasticBrandPalette, - NeutralPalette, + DEFAULT_COLOR_MAPPING_CONFIG, + DEFAULT_OTHER_ASSIGNMENT_INDEX, } from '@kbn/coloring'; import faker from 'faker'; -import { DEFAULT_NEUTRAL_PALETTE_INDEX } from '@kbn/coloring/src/shared_components/color_mapping/config/default_color_mapping'; -export const DEFAULT_COLOR_MAPPING_CONFIG: ColorMapping.Config = { - assignmentMode: 'auto', - assignments: [], - specialAssignments: [ - { - rule: { - type: 'other', - }, - color: { - type: 'categorical', - paletteId: NeutralPalette.id, - colorIndex: DEFAULT_NEUTRAL_PALETTE_INDEX, - }, - touched: false, - }, - ], - paletteId: EUIAmsterdamColorBlindPalette.id, - colorMode: { - type: 'categorical', - }, -}; - -const exampleAssignment = (valuesCount = 1, type = 'categorical', overrides = {}) => { - const color = +const exampleAssignment = ( + valuesCount = 1, + type = 'categorical', + overrides = {} +): ColorMapping.Config['assignments'][number] => { + const color: ColorMapping.Config['assignments'][number]['color'] = type === 'categorical' ? { type: 'categorical', @@ -58,11 +40,10 @@ const exampleAssignment = (valuesCount = 1, type = 'categorical', overrides = {} color, touched: false, ...overrides, - } as ColorMapping.Config['assignments'][0]; + }; }; const MANUAL_COLOR_MAPPING_CONFIG: ColorMapping.Config = { - assignmentMode: 'manual', assignments: [ exampleAssignment(4), exampleAssignment(), @@ -90,7 +71,7 @@ const MANUAL_COLOR_MAPPING_CONFIG: ColorMapping.Config = { const specialAssignmentsPalette: ColorMapping.Config['specialAssignments'] = [ { - ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[0], + ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX], color: { type: 'categorical', paletteId: EUIAmsterdamColorBlindPalette.id, @@ -100,7 +81,7 @@ const specialAssignmentsPalette: ColorMapping.Config['specialAssignments'] = [ ]; const specialAssignmentsCustom1: ColorMapping.Config['specialAssignments'] = [ { - ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[0], + ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX], color: { type: 'colorCode', colorCode: '#501a0e', @@ -109,7 +90,7 @@ const specialAssignmentsCustom1: ColorMapping.Config['specialAssignments'] = [ ]; const specialAssignmentsCustom2: ColorMapping.Config['specialAssignments'] = [ { - ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[0], + ...DEFAULT_COLOR_MAPPING_CONFIG.specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX], color: { type: 'colorCode', colorCode: 'red', @@ -129,11 +110,10 @@ describe('color_telemetry_helpers', () => { getColorMappingTelemetryEvents(MANUAL_COLOR_MAPPING_CONFIG, MANUAL_COLOR_MAPPING_CONFIG) ).toEqual([]); }); - it('settings (default): auto color mapping, unassigned terms neutral, default palette returns correct events', () => { + it('settings (default): unassigned terms loop, default palette returns correct events', () => { expect(getColorMappingTelemetryEvents(DEFAULT_COLOR_MAPPING_CONFIG)).toEqual([ - 'lens_color_mapping_auto', 'lens_color_mapping_palette_eui_amsterdam_color_blind', - 'lens_color_mapping_unassigned_terms_neutral', + 'lens_color_mapping_unassigned_terms_loop', ]); }); it('gradient event when user changed colorMode to gradient', () => { @@ -158,9 +138,8 @@ describe('color_telemetry_helpers', () => { ) ).toEqual(['lens_color_mapping_gradient']); }); - it('settings: manual mode, custom palette, unassigned terms from palette, 2 colors with 5 terms in total', () => { + it('settings: custom palette, unassigned terms from palette, 2 colors with 5 terms in total', () => { expect(getColorMappingTelemetryEvents(MANUAL_COLOR_MAPPING_CONFIG)).toEqual([ - 'lens_color_mapping_manual', 'lens_color_mapping_palette_elastic_brand_2023', 'lens_color_mapping_unassigned_terms_palette', 'lens_color_mapping_colors_2_to_4', @@ -170,7 +149,6 @@ describe('color_telemetry_helpers', () => { expect( getColorMappingTelemetryEvents(MANUAL_COLOR_MAPPING_CONFIG, DEFAULT_COLOR_MAPPING_CONFIG) ).toEqual([ - 'lens_color_mapping_manual', 'lens_color_mapping_palette_elastic_brand_2023', 'lens_color_mapping_unassigned_terms_palette', 'lens_color_mapping_colors_2_to_4', @@ -254,7 +232,7 @@ describe('color_telemetry_helpers', () => { }); describe('unassigned terms', () => { - it('unassigned terms changed from neutral to palette', () => { + it('unassigned terms changed from loop to palette', () => { expect( getColorMappingTelemetryEvents( { @@ -265,15 +243,15 @@ describe('color_telemetry_helpers', () => { ) ).toEqual(['lens_color_mapping_unassigned_terms_palette']); }); - it('unassigned terms changed from palette to neutral', () => { + it('unassigned terms changed from palette to loop', () => { expect( getColorMappingTelemetryEvents(DEFAULT_COLOR_MAPPING_CONFIG, { ...DEFAULT_COLOR_MAPPING_CONFIG, specialAssignments: specialAssignmentsPalette, }) - ).toEqual(['lens_color_mapping_unassigned_terms_neutral']); + ).toEqual(['lens_color_mapping_unassigned_terms_loop']); }); - it('unassigned terms changed from neutral to another custom color', () => { + it('unassigned terms changed from loop to another custom color', () => { expect( getColorMappingTelemetryEvents( { diff --git a/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.ts b/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.ts index d6b7acab55c7f..5bbfaaf290ef3 100644 --- a/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.ts +++ b/x-pack/plugins/lens/public/lens_ui_telemetry/color_telemetry_helpers.ts @@ -5,12 +5,7 @@ * 2.0. */ -import { ColorMapping, NeutralPalette } from '@kbn/coloring'; -import type { - CategoricalColor, - ColorCode, - GradientColor, -} from '@kbn/coloring/src/shared_components/color_mapping/config/types'; +import { ColorMapping, NeutralPalette, DEFAULT_OTHER_ASSIGNMENT_INDEX } from '@kbn/coloring'; import { isEqual } from 'lodash'; import { nonNullable } from '../utils'; @@ -24,17 +19,14 @@ export const getColorMappingTelemetryEvents = ( return []; } - const { assignments, specialAssignments, assignmentMode, colorMode, paletteId } = colorMapping; + const { assignments, specialAssignments, colorMode, paletteId } = colorMapping; const { - assignmentMode: prevAssignmentMode, assignments: prevAssignments, specialAssignments: prevSpecialAssignments, colorMode: prevColorMode, paletteId: prevPaletteId, } = prevColorMapping || {}; - const assignmentModeData = assignmentMode !== prevAssignmentMode ? assignmentMode : undefined; - const paletteData = prevPaletteId !== paletteId ? `palette_${paletteId}` : undefined; const gradientData = @@ -42,18 +34,16 @@ export const getColorMappingTelemetryEvents = ( const unassignedTermsType = getUnassignedTermsType(specialAssignments, prevSpecialAssignments); - const diffData = [assignmentModeData, gradientData, paletteData, unassignedTermsType].filter( - nonNullable - ); + const diffData = [gradientData, paletteData, unassignedTermsType].filter(nonNullable); - if (assignmentMode === 'manual') { + if (assignments.length > 0) { const colorCount = assignments.length && !isEqual(assignments, prevAssignments) ? `colors_${getRangeText(assignments.length)}` : undefined; - const prevCustomColors = prevAssignments?.filter((a) => isCustomColor(a.color)); - const customColors = assignments.filter((a) => isCustomColor(a.color)); + const prevCustomColors = prevAssignments?.filter((a) => a.color.type === 'colorCode'); + const customColors = assignments.filter((a) => a.color.type === 'colorCode'); const customColorEvent = customColors.length && !isEqual(prevCustomColors, customColors) ? `custom_colors_${getRangeText(customColors.length, 1)}` @@ -68,10 +58,6 @@ export const getColorMappingTelemetryEvents = ( const constructName = (eventName: string) => `${COLOR_MAPPING_PREFIX}${eventName}`; -const isCustomColor = (color: CategoricalColor | ColorCode | GradientColor): color is ColorCode => { - return color.type === 'colorCode'; -}; - function getRangeText(n: number, min = 2, max = 16) { if (n >= min && (n === 1 || n === 2)) { return String(n); @@ -92,9 +78,12 @@ const getUnassignedTermsType = ( ) => { return !isEqual(prevSpecialAssignments, specialAssignments) ? `unassigned_terms_${ - isCustomColor(specialAssignments?.[0].color) + specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX]?.color.type === 'colorCode' ? 'custom' - : specialAssignments?.[0].color.paletteId === NeutralPalette.id + : specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX]?.color.type === 'loop' + ? 'loop' + : specialAssignments[DEFAULT_OTHER_ASSIGNMENT_INDEX]?.color.paletteId === + NeutralPalette.id ? NeutralPalette.id : 'palette' }` diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index b8d9c9eb44c43..a9b62b8622cdc 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -140,8 +140,6 @@ "coloring.colorMapping.assignments.autoAssignedTermAriaLabel": "Cette couleur sera automatiquement affectée au premier terme qui ne correspond pas à toutes les autres affectations", "coloring.colorMapping.assignments.autoAssignedTermPlaceholder": "Affecté automatiquement", "coloring.colorMapping.assignments.deleteAssignmentButtonLabel": "Supprimer cette affectation", - "coloring.colorMapping.assignments.unassignedAriaLabel": "Affecter cette couleur à tout terme non affecté qui n'est pas décrit dans la liste d'affectation", - "coloring.colorMapping.assignments.unassignedPlaceholder": "Termes non affectés", "coloring.colorMapping.colorChangesModal.categoricalModeDescription": "Basculer en mode de catégorie conduira à l'abandon de toutes vos modifications de couleurs personnalisées", "coloring.colorMapping.colorChangesModal.discardButton": "Abandonner les modifications", "coloring.colorMapping.colorChangesModal.discardButtonLabel": "Abandonner les modifications", @@ -159,14 +157,11 @@ "coloring.colorMapping.colorPicker.removeGradientColorButtonLabel": "Supprimer l'étape couleur", "coloring.colorMapping.colorPicker.themeAwareColorsLabel": "Couleurs neutres", "coloring.colorMapping.colorPicker.themeAwareColorsTooltip": "Les couleurs neutres fournies se conforment au thème et s'adapteront en fonction du basculement entre les thèmes clair et sombre", - "coloring.colorMapping.container.addAssignmentButtonLabel": "Ajouter une affectation", - "coloring.colorMapping.container.autoAssignLabel": "Affectation automatique", "coloring.colorMapping.container.invertGradientButtonLabel": "Inverser le gradient", "coloring.colorMapping.container.mappingAssignmentHeader": "Mapping des affectations", "coloring.colorMapping.paletteSelector.categoricalLabel": "De catégorie", "coloring.colorMapping.paletteSelector.paletteLabel": "Palette de couleurs", "coloring.colorMapping.paletteSelector.scaleLabel": "Scaling", - "coloring.colorMapping.paletteSelector.sequentialLabel": "Séquentiel", "coloring.dynamicColoring.customPalette.addColor": "Ajouter une couleur", "coloring.dynamicColoring.customPalette.addColorAriaLabel": "Ajouter une couleur", "coloring.dynamicColoring.customPalette.colorStopsHelpPercentage": "Les types de valeurs en pourcentage sont relatifs à la plage complète des valeurs de données disponibles.", @@ -42905,4 +42900,4 @@ "xpack.serverlessObservability.nav.projectSettings": "Paramètres de projet", "xpack.serverlessObservability.nav.visualizations": "Visualisations" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index cf3ea4c3fe0a9..77335897bd208 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -140,8 +140,6 @@ "coloring.colorMapping.assignments.autoAssignedTermAriaLabel": "この色は、他のすべての割り当てと一致しない最初の用語に自動的に割り当てられます。", "coloring.colorMapping.assignments.autoAssignedTermPlaceholder": "自動割り当て済み", "coloring.colorMapping.assignments.deleteAssignmentButtonLabel": "この割り当てを削除", - "coloring.colorMapping.assignments.unassignedAriaLabel": "割り当てリストに記載されていない未割り当てのすべての色にこの色を割り当てます。", - "coloring.colorMapping.assignments.unassignedPlaceholder": "割り当てられていない用語", "coloring.colorMapping.colorChangesModal.categoricalModeDescription": "分類モードに切り替えると、カスタム色の変更はすべて破棄されます。", "coloring.colorMapping.colorChangesModal.discardButton": "変更を破棄", "coloring.colorMapping.colorChangesModal.discardButtonLabel": "変更を破棄", @@ -159,14 +157,11 @@ "coloring.colorMapping.colorPicker.removeGradientColorButtonLabel": "色ステップを削除", "coloring.colorMapping.colorPicker.themeAwareColorsLabel": "中間色", "coloring.colorMapping.colorPicker.themeAwareColorsTooltip": "提供されている中間色はテーマを意識しており、明るいテーマと暗いテーマを切り替えると適切に変化します。", - "coloring.colorMapping.container.addAssignmentButtonLabel": "割り当てを追加", - "coloring.colorMapping.container.autoAssignLabel": "自動割り当て", "coloring.colorMapping.container.invertGradientButtonLabel": "グラデーションを反転", "coloring.colorMapping.container.mappingAssignmentHeader": "マッピング割り当て", "coloring.colorMapping.paletteSelector.categoricalLabel": "分類", "coloring.colorMapping.paletteSelector.paletteLabel": "カラーパレット", "coloring.colorMapping.paletteSelector.scaleLabel": "スケール", - "coloring.colorMapping.paletteSelector.sequentialLabel": "連続", "coloring.dynamicColoring.customPalette.addColor": "色を追加", "coloring.dynamicColoring.customPalette.addColorAriaLabel": "色を追加", "coloring.dynamicColoring.customPalette.colorStopsHelpPercentage": "割合値は使用可能なデータ値の全範囲に対して相対的です。", @@ -42897,4 +42892,4 @@ "xpack.serverlessObservability.nav.projectSettings": "プロジェクト設定", "xpack.serverlessObservability.nav.visualizations": "ビジュアライゼーション" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 26029615545f8..70fe8f8c91298 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -140,8 +140,6 @@ "coloring.colorMapping.assignments.autoAssignedTermAriaLabel": "会将此颜色自动分配给第一个与所有其他分配均不匹配的词", "coloring.colorMapping.assignments.autoAssignedTermPlaceholder": "已自动分配", "coloring.colorMapping.assignments.deleteAssignmentButtonLabel": "删除此分配", - "coloring.colorMapping.assignments.unassignedAriaLabel": "将此颜色分配给分配列表中未描述的每个未分配项", - "coloring.colorMapping.assignments.unassignedPlaceholder": "未分配的词", "coloring.colorMapping.colorChangesModal.categoricalModeDescription": "切换到分类模式将丢弃您的所有定制颜色更改", "coloring.colorMapping.colorChangesModal.discardButton": "放弃更改", "coloring.colorMapping.colorChangesModal.discardButtonLabel": "放弃更改", @@ -159,14 +157,11 @@ "coloring.colorMapping.colorPicker.removeGradientColorButtonLabel": "移除色阶", "coloring.colorMapping.colorPicker.themeAwareColorsLabel": "中性色", "coloring.colorMapping.colorPicker.themeAwareColorsTooltip": "提供的中性色能够感知主题,在浅色主题与深色主题之间切换时会做出相应更改", - "coloring.colorMapping.container.addAssignmentButtonLabel": "添加分配", - "coloring.colorMapping.container.autoAssignLabel": "自动分配", "coloring.colorMapping.container.invertGradientButtonLabel": "反向渐变", "coloring.colorMapping.container.mappingAssignmentHeader": "映射分配", "coloring.colorMapping.paletteSelector.categoricalLabel": "分类", "coloring.colorMapping.paletteSelector.paletteLabel": "调色板", "coloring.colorMapping.paletteSelector.scaleLabel": "比例", - "coloring.colorMapping.paletteSelector.sequentialLabel": "顺序", "coloring.dynamicColoring.customPalette.addColor": "添加颜色", "coloring.dynamicColoring.customPalette.addColorAriaLabel": "添加颜色", "coloring.dynamicColoring.customPalette.colorStopsHelpPercentage": "百分比值是相对于全范围可用数据值的类型。", @@ -42877,4 +42872,4 @@ "xpack.serverlessObservability.nav.projectSettings": "项目设置", "xpack.serverlessObservability.nav.visualizations": "可视化" } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index c159fb17b4db7..c5018bda39ffa 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -1934,8 +1934,9 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await testSubjects.existOrFail('lns-indexPattern-dimensionContainerClose'); }); await testSubjects.click('lns_colorEditing_trigger'); - // disable autoAssign - await testSubjects.setEuiSwitch('lns-colorMapping-autoAssignSwitch', 'uncheck'); + + // assign all + await testSubjects.click('lns-colorMapping-assignmentsPromptAddAll'); await testSubjects.click(`lns-colorMapping-colorSwatch-${colorSwatchIndex}`); From 69bd69992e1b4f707eeb0ec6cf7892354fe57363 Mon Sep 17 00:00:00 2001 From: jennypavlova Date: Thu, 8 Feb 2024 14:31:39 +0100 Subject: [PATCH 017/104] [Infra] Kubernetes form - update survey link for correct cluster version (#176385) Closes #174347 ## Summary This PR changes the Kibana version query parameter in the k8s feedback URL to fix the issue with prefilling the form and adds an option to have more flexibility in the feedback button regarding the form parameter names. ## Testing - Open Inventory view and select Kubernetes Pods from the `Show` menu - Click on the feedback button - Check if the Kibana version is prefilled correctly in the form https://github.com/elastic/kibana/assets/14139027/b62edb51-d990-49dc-9214-764dbbf6f47c --- .../components/survey_kubernetes.tsx | 3 ++ .../feature_feedback_button.tsx | 50 +++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx index c5524bae4eb41..ce36a396b150f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/survey_kubernetes.tsx @@ -35,6 +35,9 @@ export const SurveyKubernetes = () => { defaultMessage="Tell us what you think! (K8s)" /> } + formConfig={{ + kibanaVersionQueryParam: 'entry.184582718', + }} /> {!isToastSeen && ( { +const getSurveyFeedbackURL = ({ + formUrl, + formConfig, + kibanaVersion, + deploymentType, + sanitizedPath, +}: { + formUrl: string; + formConfig?: FormConfig; + kibanaVersion?: string; + deploymentType?: string; + sanitizedPath?: string; +}) => { const url = new URL(formUrl); if (kibanaVersion) { - url.searchParams.append(KIBANA_VERSION_QUERY_PARAM, kibanaVersion); + url.searchParams.append( + formConfig?.kibanaVersionQueryParam || KIBANA_VERSION_QUERY_PARAM, + kibanaVersion + ); } if (deploymentType) { - url.searchParams.append(KIBANA_DEPLOYMENT_TYPE_PARAM, deploymentType); + url.searchParams.append( + formConfig?.kibanaDeploymentTypeQueryParam || KIBANA_DEPLOYMENT_TYPE_PARAM, + deploymentType + ); } if (sanitizedPath) { - url.searchParams.append(SANITIZED_PATH_PARAM, sanitizedPath); + url.searchParams.append( + formConfig?.sanitizedPathQueryParam || SANITIZED_PATH_PARAM, + sanitizedPath + ); } return url.href; }; +interface FormConfig { + kibanaVersionQueryParam?: string; + kibanaDeploymentTypeQueryParam?: string; + sanitizedPathQueryParam?: string; +} + interface FeatureFeedbackButtonProps { formUrl: string; 'data-test-subj': string; @@ -53,10 +75,12 @@ interface FeatureFeedbackButtonProps { isCloudEnv?: boolean; isServerlessEnv?: boolean; sanitizedPath?: string; + formConfig?: FormConfig; } export const FeatureFeedbackButton = ({ formUrl, + formConfig, 'data-test-subj': dts, onClickCapture, defaultButton, @@ -78,7 +102,13 @@ export const FeatureFeedbackButton = ({ return ( Date: Thu, 8 Feb 2024 15:12:30 +0100 Subject: [PATCH 018/104] More ES|QL in-product help updates for 8.13 (#176330) --- .../src/esql_documentation_sections.tsx | 245 +++++++++++++++--- 1 file changed, 216 insertions(+), 29 deletions(-) diff --git a/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx b/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx index 6f96c1366800d..2c47f7f309531 100644 --- a/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx +++ b/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx @@ -585,9 +585,12 @@ FROM employees defaultMessage: `### STATS ... BY Use \`STATS ... BY\` to group rows according to a common value and calculate one or more aggregated values over the grouped rows. +**Examples**: + \`\`\` FROM employees -| STATS count = COUNT(languages) BY languages +| STATS count = COUNT(emp_no) BY languages +| SORT languages \`\`\` If \`BY\` is omitted, the output table contains exactly one row with the aggregations applied over the entire dataset: @@ -615,6 +618,40 @@ FROM employees \`\`\` Refer to **Aggregation functions** for a list of functions that can be used with \`STATS ... BY\`. + +Both the aggregating functions and the grouping expressions accept other functions. This is useful for using \`STATS...BY\` on multivalue columns. For example, to calculate the average salary change, you can use \`MV_AVG\` to first average the multiple values per employee, and use the result with the \`AVG\` function: + +\`\`\` +FROM employees +| STATS avg_salary_change = AVG(MV_AVG(salary_change)) +\`\`\` + +An example of grouping by an expression is grouping employees on the first letter of their last name: + +\`\`\` +FROM employees +| STATS my_count = COUNT() BY LEFT(last_name, 1) +| SORT \`LEFT(last_name, 1)\` +\`\`\` + +Specifying the output column name is optional. If not specified, the new column name is equal to the expression. The following query returns a column named \`AVG(salary)\`: + +\`\`\` +FROM employees +| STATS AVG(salary) +\`\`\` + +Because this name contains special characters, it needs to be quoted with backticks (\`) when using it in subsequent commands: + +\`\`\` +FROM employees +| STATS AVG(salary) +| EVAL avg_salary_rounded = ROUND(\`AVG(salary)\`) +\`\`\` + +**Note**: \`STATS\` without any groups is much faster than adding a group. + +**Note**: Grouping on a single expression is currently much more optimized than grouping on many expressions. `, description: 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', @@ -934,7 +971,7 @@ ROW a=1.8 | EVAL a=CEIL(a) \`\`\` -Note: This is a noop for \`long\` (including unsigned) and \`integer\`. For \`double\` this picks the the closest \`double\` value to the integer similar to Java's \`Math.ceil\`. +Note: This is a noop for \`long\` (including unsigned) and \`integer\`. For \`double\` this picks the closest \`double\` value to the integer similar to Java's \`Math.ceil\`. `, description: 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', @@ -1081,6 +1118,33 @@ ROW a=1.8 /> ), }, + { + label: i18n.translate( + 'textBasedEditor.query.textBasedLanguagesEditor.documentationESQL.dateDiffFunction', + { + defaultMessage: 'DATE_DIFF', + } + ), + description: ( + + ), + }, { label: i18n.translate( 'textBasedEditor.query.textBasedLanguagesEditor.documentationESQL.dateExtractFunction', @@ -1099,6 +1163,13 @@ Extracts parts of a date, like year, month, day, hour. The supported field types \`\`\` ROW date = DATE_PARSE("yyyy-MM-dd", "2022-05-06") | EVAL year = DATE_EXTRACT("year", date) +\`\`\` + +For example, to find all events that occurred outside of business hours (before 9 AM or after 5 PM), on any given date: + +\`\`\` +FROM sample_data +| WHERE DATE_EXTRACT("hour_of_day", @timestamp) < 9 AND DATE_EXTRACT("hour_of_day", @timestamp) >= 17 \`\`\` `, description: @@ -1145,12 +1216,13 @@ FROM employees ), description: ( + ), + }, + { + label: i18n.translate( + 'textBasedEditor.query.textBasedLanguagesEditor.documentationESQL.stCentroidFunction', + { + defaultMessage: 'ST_CENTROID', + } + ), + description: ( + Date: Thu, 8 Feb 2024 08:32:11 -0600 Subject: [PATCH 019/104] [Console] Add support to remotely open Embeddable Console (#176017) ## Summary Updated the embeddable console and console start to allow triggering the Console open from the ConsolePluginStart object with or without specific content to be pre-loaded. ### Checklist - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../components/code_box.tsx | 4 + .../components/ingest_data.tsx | 4 + .../components/try_in_console_button.tsx | 17 +- packages/kbn-search-api-panels/tsconfig.json | 3 +- .../editor/legacy/console_editor/editor.tsx | 2 +- .../containers/embeddable/console_wrapper.tsx | 16 +- .../embeddable/embeddable_console.tsx | 30 ++- .../public/application/lib/load_from.test.ts | 236 ++++++++++++++++++ .../public/application/lib/load_from.ts | 49 ++++ .../application/stores/embeddable_console.ts | 41 +++ src/plugins/console/public/plugin.ts | 12 +- .../services/embeddable_console.test.ts | 53 ++++ .../public/services/embeddable_console.ts | 29 +++ src/plugins/console/public/services/index.ts | 1 + .../public/types/embeddable_console.ts | 11 + .../public/types/plugin_dependencies.ts | 10 + .../common/types/kibana_deps.ts | 2 + .../panels/add_data_panel_content.tsx | 1 + .../panels/search_query_panel_content.tsx | 1 + .../application/components/overview.tsx | 2 + 20 files changed, 510 insertions(+), 14 deletions(-) create mode 100644 src/plugins/console/public/application/lib/load_from.test.ts create mode 100644 src/plugins/console/public/application/lib/load_from.ts create mode 100644 src/plugins/console/public/application/stores/embeddable_console.ts create mode 100644 src/plugins/console/public/services/embeddable_console.test.ts create mode 100644 src/plugins/console/public/services/embeddable_console.ts diff --git a/packages/kbn-search-api-panels/components/code_box.tsx b/packages/kbn-search-api-panels/components/code_box.tsx index 21c4085f44a9b..5a4ff7cc13240 100644 --- a/packages/kbn-search-api-panels/components/code_box.tsx +++ b/packages/kbn-search-api-panels/components/code_box.tsx @@ -23,6 +23,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { ApplicationStart } from '@kbn/core-application-browser'; +import type { ConsolePluginStart } from '@kbn/console-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import { LanguageDefinition } from '../types'; @@ -38,6 +39,7 @@ interface CodeBoxProps { setSelectedLanguage: (language: LanguageDefinition) => void; assetBasePath: string; application?: ApplicationStart; + consolePlugin?: ConsolePluginStart; sharePlugin: SharePluginStart; consoleRequest?: string; } @@ -45,6 +47,7 @@ interface CodeBoxProps { export const CodeBox: React.FC = ({ application, codeSnippet, + consolePlugin, languageType, languages, assetBasePath, @@ -117,6 +120,7 @@ export const CodeBox: React.FC = ({ diff --git a/packages/kbn-search-api-panels/components/ingest_data.tsx b/packages/kbn-search-api-panels/components/ingest_data.tsx index f8ba59d29bf30..0700d2d56d661 100644 --- a/packages/kbn-search-api-panels/components/ingest_data.tsx +++ b/packages/kbn-search-api-panels/components/ingest_data.tsx @@ -11,6 +11,7 @@ import React from 'react'; import { EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { ApplicationStart } from '@kbn/core-application-browser'; +import type { ConsolePluginStart } from '@kbn/console-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import { CodeBox } from './code_box'; import { LanguageDefinition } from '../types'; @@ -26,6 +27,7 @@ interface IngestDataProps { }; assetBasePath: string; application?: ApplicationStart; + consolePlugin?: ConsolePluginStart; sharePlugin: SharePluginStart; languages: LanguageDefinition[]; consoleRequest?: string; @@ -39,6 +41,7 @@ export const IngestData: React.FC = ({ docLinks, assetBasePath, application, + consolePlugin, sharePlugin, languages, consoleRequest, @@ -58,6 +61,7 @@ export const IngestData: React.FC = ({ setSelectedLanguage={setSelectedLanguage} assetBasePath={assetBasePath} application={application} + consolePlugin={consolePlugin} sharePlugin={sharePlugin} /> } diff --git a/packages/kbn-search-api-panels/components/try_in_console_button.tsx b/packages/kbn-search-api-panels/components/try_in_console_button.tsx index fe109e025e2e5..7007c306a2cd6 100644 --- a/packages/kbn-search-api-panels/components/try_in_console_button.tsx +++ b/packages/kbn-search-api-panels/components/try_in_console_button.tsx @@ -11,6 +11,7 @@ import React from 'react'; import { EuiButtonEmpty } from '@elastic/eui'; import type { ApplicationStart } from '@kbn/core-application-browser'; import type { SharePluginStart } from '@kbn/share-plugin/public'; +import type { ConsolePluginStart } from '@kbn/console-plugin/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { compressToEncodedURIComponent } from 'lz-string'; @@ -18,11 +19,13 @@ import { compressToEncodedURIComponent } from 'lz-string'; export interface TryInConsoleButtonProps { request: string; application?: ApplicationStart; + consolePlugin?: ConsolePluginStart; sharePlugin: SharePluginStart; } export const TryInConsoleButton = ({ request, application, + consolePlugin, sharePlugin, }: TryInConsoleButtonProps) => { const { url } = sharePlugin; @@ -39,8 +42,20 @@ export const TryInConsoleButton = ({ ); if (!consolePreviewLink) return null; + const onClick = () => { + const embeddedConsoleAvailable = + (consolePlugin?.openEmbeddedConsole !== undefined && + consolePlugin?.isEmbeddedConsoleAvailable?.()) ?? + false; + if (embeddedConsoleAvailable) { + consolePlugin!.openEmbeddedConsole!(request); + } else { + window.open(consolePreviewLink, '_blank', 'noreferrer'); + } + }; + return ( - + { - const [, queryString] = (window.location.hash || '').split('?'); + const [, queryString] = (window.location.hash || window.location.search || '').split('?'); return parse(queryString || '', { sort: false }) as Required; }; diff --git a/src/plugins/console/public/application/containers/embeddable/console_wrapper.tsx b/src/plugins/console/public/application/containers/embeddable/console_wrapper.tsx index 340b20c91b6cd..3618194e194dc 100644 --- a/src/plugins/console/public/application/containers/embeddable/console_wrapper.tsx +++ b/src/plugins/console/public/application/containers/embeddable/console_wrapper.tsx @@ -14,8 +14,10 @@ import { I18nStart, CoreTheme, DocLinksStart, + CoreStart, } from '@kbn/core/public'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; +import { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import { ObjectStorageClient } from '../../../../common/types'; @@ -62,10 +64,10 @@ interface ConsoleDependencies { trackUiMetric: MetricsTracker; } -const loadDependencies = async ({ - core, - usageCollection, -}: EmbeddableConsoleDependencies): Promise => { +const loadDependencies = async ( + core: CoreStart, + usageCollection?: UsageCollectionStart +): Promise => { const { docLinks: { DOC_LINK_VERSION, links }, http, @@ -107,10 +109,12 @@ const loadDependencies = async ({ }; }; -export const ConsoleWrapper = (props: EmbeddableConsoleDependencies): React.ReactElement => { +type ConsoleWrapperProps = Omit; + +export const ConsoleWrapper: React.FunctionComponent = (props) => { const [dependencies, setDependencies] = useState(null); useEffect(() => { - loadDependencies(props).then(setDependencies); + loadDependencies(props.core, props.usageCollection).then(setDependencies); }, [setDependencies, props]); useEffect(() => { return () => { diff --git a/src/plugins/console/public/application/containers/embeddable/embeddable_console.tsx b/src/plugins/console/public/application/containers/embeddable/embeddable_console.tsx index 2577c9d4841d7..2167ec12c52c0 100644 --- a/src/plugins/console/public/application/containers/embeddable/embeddable_console.tsx +++ b/src/plugins/console/public/application/containers/embeddable/embeddable_console.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useState } from 'react'; +import React, { useReducer, useEffect } from 'react'; import classNames from 'classnames'; import useObservable from 'react-use/lib/useObservable'; import { @@ -25,6 +25,9 @@ import { EmbeddableConsoleDependencies, } from '../../../types/embeddable_console'; +import * as store from '../../stores/embeddable_console'; +import { setLoadFromParameter, removeLoadFromParameter } from '../../lib/load_from'; + import { ConsoleWrapper } from './console_wrapper'; import './_index.scss'; @@ -36,10 +39,31 @@ export const EmbeddableConsole = ({ size = 'm', core, usageCollection, + setDispatch, }: EmbeddableConsoleProps & EmbeddableConsoleDependencies) => { - const [isConsoleOpen, setIsConsoleOpen] = useState(false); - const toggleConsole = () => setIsConsoleOpen(!isConsoleOpen); + const [consoleState, consoleDispatch] = useReducer( + store.reducer, + store.initialValue, + (value) => ({ ...value }) + ); const chromeStyle = useObservable(core.chrome.getChromeStyle$()); + useEffect(() => { + setDispatch(consoleDispatch); + return () => setDispatch(null); + }, [setDispatch, consoleDispatch]); + useEffect(() => { + if (consoleState.isOpen && consoleState.loadFromContent) { + setLoadFromParameter(consoleState.loadFromContent); + } else if (!consoleState.isOpen) { + removeLoadFromParameter(); + } + }, [consoleState.isOpen, consoleState.loadFromContent]); + + const isConsoleOpen = consoleState.isOpen; + const setIsConsoleOpen = (value: boolean) => { + consoleDispatch(value ? { type: 'open' } : { type: 'close' }); + }; + const toggleConsole = () => setIsConsoleOpen(!isConsoleOpen); const onKeyDown = (event: any) => { if (event.key === keys.ESCAPE) { diff --git a/src/plugins/console/public/application/lib/load_from.test.ts b/src/plugins/console/public/application/lib/load_from.test.ts new file mode 100644 index 0000000000000..289718f46cf10 --- /dev/null +++ b/src/plugins/console/public/application/lib/load_from.test.ts @@ -0,0 +1,236 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { compressToEncodedURIComponent } from 'lz-string'; +import { setLoadFromParameter, removeLoadFromParameter } from './load_from'; + +const baseMockWindow = () => { + return { + history: { + pushState: jest.fn(), + }, + location: { + host: 'my-kibana.elastic.co', + pathname: '', + protocol: 'https:', + search: '', + hash: '', + }, + }; +}; +let windowSpy: jest.SpyInstance; +let mockWindow = baseMockWindow(); + +describe('load from lib', () => { + beforeEach(() => { + mockWindow = baseMockWindow(); + windowSpy = jest.spyOn(globalThis, 'window', 'get'); + windowSpy.mockImplementation(() => mockWindow); + }); + + afterEach(() => { + windowSpy.mockRestore(); + }); + + describe('setLoadFromParameter', () => { + it('adds load_from as expected', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: '#/console', + }; + const codeSnippet = 'GET /_stats'; + const expectedUrl = + 'https://my-kibana.elastic.co/foo/app/dev_tools#/console?load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgzgFwIYLkA'; + + setLoadFromParameter(codeSnippet); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('can replace an existing value', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: `#/console?load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgxgQwC5QJYDsAmq4FMDOQA`, + }; + const codeSnippet = 'GET /_stats'; + const expectedUrl = + 'https://my-kibana.elastic.co/foo/app/dev_tools#/console?load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgzgFwIYLkA'; + + setLoadFromParameter(codeSnippet); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('works with other query params', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: '#/console?foo=bar', + }; + const codeSnippet = 'GET /_stats'; + const expectedUrl = + 'https://my-kibana.elastic.co/foo/app/dev_tools#/console?foo=bar&load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgzgFwIYLkA'; + + setLoadFromParameter(codeSnippet); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('works with a non-hash route', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/enterprise_search/overview', + }; + const codeSnippet = 'GET /_stats'; + const expectedUrl = + 'https://my-kibana.elastic.co/foo/app/enterprise_search/overview?load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgzgFwIYLkA'; + + setLoadFromParameter(codeSnippet); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('works with a non-hash route and other params', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/enterprise_search/overview', + search: '?foo=bar', + }; + const codeSnippet = 'GET /_stats'; + const expectedUrl = + 'https://my-kibana.elastic.co/foo/app/enterprise_search/overview?foo=bar&load_from=data%3Atext%2Fplain%2COIUQKgBA9A%2BgzgFwIYLkA'; + + setLoadFromParameter(codeSnippet); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + }); + + describe('removeLoadFromParameter', () => { + it('leaves other params in place', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + search: `?foo=bar&load_from=data:text/plain,${compressToEncodedURIComponent( + 'GET /_cat/indices' + )}`, + }; + + const expectedUrl = 'https://my-kibana.elastic.co/foo/app/dev_tools?foo=bar'; + + removeLoadFromParameter(); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('leaves other params with a hashroute', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: `#/console?foo=bar&load_from=data:text/plain,${compressToEncodedURIComponent( + 'GET /_cat/indices' + )}`, + }; + + const expectedUrl = 'https://my-kibana.elastic.co/foo/app/dev_tools#/console?foo=bar'; + + removeLoadFromParameter(); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('removes ? if load_from was the only param', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + search: `?load_from=data:text/plain,${compressToEncodedURIComponent('GET /_cat/indices')}`, + }; + + const expectedUrl = 'https://my-kibana.elastic.co/foo/app/dev_tools'; + + removeLoadFromParameter(); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('removes ? if load_from was the only param in a hashroute', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: `#/console?load_from=data:text/plain,${compressToEncodedURIComponent( + 'GET /_cat/indices' + )}`, + }; + + const expectedUrl = 'https://my-kibana.elastic.co/foo/app/dev_tools#/console'; + + removeLoadFromParameter(); + expect(mockWindow.history.pushState).toHaveBeenCalledTimes(1); + expect(mockWindow.history.pushState).toHaveBeenCalledWith( + { + path: expectedUrl, + }, + '', + expectedUrl + ); + }); + it('noop if load_from not currently defined on QS', () => { + mockWindow.location = { + ...mockWindow.location, + pathname: '/foo/app/dev_tools', + hash: `#/console?foo=bar`, + }; + + removeLoadFromParameter(); + expect(mockWindow.history.pushState).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/src/plugins/console/public/application/lib/load_from.ts b/src/plugins/console/public/application/lib/load_from.ts new file mode 100644 index 0000000000000..c601eafb6f3a9 --- /dev/null +++ b/src/plugins/console/public/application/lib/load_from.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import qs from 'query-string'; +import { compressToEncodedURIComponent } from 'lz-string'; + +function getBaseUrl() { + return `${window.location.protocol}//${window.location.host}${window.location.pathname}`; +} +function parseQueryString() { + const [hashRoute, queryString] = (window.location.hash || window.location.search || '').split( + '?' + ); + + const parsedQueryString = qs.parse(queryString || '', { sort: false }); + return { + hasHash: !!window.location.hash, + hashRoute, + queryString: parsedQueryString, + }; +} + +export const setLoadFromParameter = (value: string) => { + const baseUrl = getBaseUrl(); + const { hasHash, hashRoute, queryString } = parseQueryString(); + const consoleDataUri = compressToEncodedURIComponent(value); + queryString.load_from = `data:text/plain,${consoleDataUri}`; + const params = `?${qs.stringify(queryString)}`; + const newUrl = hasHash ? `${baseUrl}${hashRoute}${params}` : `${baseUrl}${params}`; + + window.history.pushState({ path: newUrl }, '', newUrl); +}; + +export const removeLoadFromParameter = () => { + const baseUrl = getBaseUrl(); + const { hasHash, hashRoute, queryString } = parseQueryString(); + if (queryString.load_from) { + delete queryString.load_from; + + const params = Object.keys(queryString).length ? `?${qs.stringify(queryString)}` : ''; + const newUrl = hasHash ? `${baseUrl}${hashRoute}${params}` : `${baseUrl}${params}`; + window.history.pushState({ path: newUrl }, '', newUrl); + } +}; diff --git a/src/plugins/console/public/application/stores/embeddable_console.ts b/src/plugins/console/public/application/stores/embeddable_console.ts new file mode 100644 index 0000000000000..4bfb38d094c13 --- /dev/null +++ b/src/plugins/console/public/application/stores/embeddable_console.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Reducer } from 'react'; +import { produce } from 'immer'; +import { identity } from 'fp-ts/lib/function'; + +import { EmbeddedConsoleAction, EmbeddedConsoleStore } from '../../types/embeddable_console'; + +export const initialValue: EmbeddedConsoleStore = produce( + { + isOpen: false, + }, + identity +); + +export const reducer: Reducer = (state, action) => + produce(state, (draft) => { + switch (action.type) { + case 'open': + if (!state.isOpen) { + draft.isOpen = true; + draft.loadFromContent = action.payload?.content; + return; + } + break; + case 'close': + if (state.isOpen) { + draft.isOpen = false; + draft.loadFromContent = undefined; + return; + } + break; + } + return draft; + }); diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts index 711b4304af9b0..53cb16befe865 100644 --- a/src/plugins/console/public/plugin.ts +++ b/src/plugins/console/public/plugin.ts @@ -5,7 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - import { i18n } from '@kbn/i18n'; import { Plugin, CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/public'; @@ -20,10 +19,12 @@ import { EmbeddableConsoleProps, EmbeddableConsoleDependencies, } from './types'; -import { AutocompleteInfo, setAutocompleteInfo } from './services'; +import { AutocompleteInfo, setAutocompleteInfo, EmbeddableConsoleInfo } from './services'; export class ConsoleUIPlugin implements Plugin { private readonly autocompleteInfo = new AutocompleteInfo(); + private _embeddableConsole: EmbeddableConsoleInfo = new EmbeddableConsoleInfo(); + constructor(private ctx: PluginInitializerContext) {} public setup( @@ -118,9 +119,16 @@ export class ConsoleUIPlugin implements Plugin { + this._embeddableConsole.setDispatch(d); + }, }; return renderEmbeddableConsole(props, consoleDeps); }; + consoleStart.isEmbeddedConsoleAvailable = () => + this._embeddableConsole.isEmbeddedConsoleAvailable(); + consoleStart.openEmbeddedConsole = (content?: string) => + this._embeddableConsole.openEmbeddedConsole(content); } return consoleStart; diff --git a/src/plugins/console/public/services/embeddable_console.test.ts b/src/plugins/console/public/services/embeddable_console.test.ts new file mode 100644 index 0000000000000..7df8230b6dbdf --- /dev/null +++ b/src/plugins/console/public/services/embeddable_console.test.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EmbeddableConsoleInfo } from './embeddable_console'; + +describe('EmbeddableConsoleInfo', () => { + let eConsole: EmbeddableConsoleInfo; + beforeEach(() => { + eConsole = new EmbeddableConsoleInfo(); + }); + describe('isEmbeddedConsoleAvailable', () => { + it('returns true if dispatch has been set', () => { + eConsole.setDispatch(jest.fn()); + expect(eConsole.isEmbeddedConsoleAvailable()).toBe(true); + }); + it('returns false if dispatch has not been set', () => { + expect(eConsole.isEmbeddedConsoleAvailable()).toBe(false); + }); + it('returns false if dispatch has been cleared', () => { + eConsole.setDispatch(jest.fn()); + eConsole.setDispatch(null); + expect(eConsole.isEmbeddedConsoleAvailable()).toBe(false); + }); + }); + describe('openEmbeddedConsole', () => { + const mockDispatch = jest.fn(); + beforeEach(() => { + jest.clearAllMocks(); + + eConsole.setDispatch(mockDispatch); + }); + it('dispatches open action', () => { + eConsole.openEmbeddedConsole(); + + expect(mockDispatch).toHaveBeenCalledTimes(1); + expect(mockDispatch).toHaveBeenCalledWith({ type: 'open' }); + }); + it('can set content', () => { + eConsole.openEmbeddedConsole('GET /_cat/_indices'); + + expect(mockDispatch).toHaveBeenCalledTimes(1); + expect(mockDispatch).toHaveBeenCalledWith({ + type: 'open', + payload: { content: 'GET /_cat/_indices' }, + }); + }); + }); +}); diff --git a/src/plugins/console/public/services/embeddable_console.ts b/src/plugins/console/public/services/embeddable_console.ts new file mode 100644 index 0000000000000..6bc32b8475eef --- /dev/null +++ b/src/plugins/console/public/services/embeddable_console.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { Dispatch } from 'react'; + +import { EmbeddedConsoleAction as EmbeddableConsoleAction } from '../types/embeddable_console'; + +export class EmbeddableConsoleInfo { + private _dispatch: Dispatch | null = null; + + public setDispatch(d: Dispatch | null) { + this._dispatch = d; + } + + public isEmbeddedConsoleAvailable(): boolean { + return this._dispatch !== null; + } + + public openEmbeddedConsole(content?: string) { + // Embedded Console is not rendered on the page, nothing to do + if (!this._dispatch) return; + + this._dispatch({ type: 'open', payload: content ? { content } : undefined }); + } +} diff --git a/src/plugins/console/public/services/index.ts b/src/plugins/console/public/services/index.ts index 73929f89e386f..669ed890729dc 100644 --- a/src/plugins/console/public/services/index.ts +++ b/src/plugins/console/public/services/index.ts @@ -16,3 +16,4 @@ export { setAutocompleteInfo, ENTITIES, } from './autocomplete'; +export { EmbeddableConsoleInfo } from './embeddable_console'; diff --git a/src/plugins/console/public/types/embeddable_console.ts b/src/plugins/console/public/types/embeddable_console.ts index da0e3346a7bd2..71a755b7dd544 100644 --- a/src/plugins/console/public/types/embeddable_console.ts +++ b/src/plugins/console/public/types/embeddable_console.ts @@ -7,6 +7,7 @@ */ import type { CoreStart } from '@kbn/core/public'; import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; +import type { Dispatch } from 'react'; /** * EmbeddableConsoleProps are optional props used when rendering the embeddable developer console. @@ -21,4 +22,14 @@ export interface EmbeddableConsoleProps { export interface EmbeddableConsoleDependencies { core: CoreStart; usageCollection?: UsageCollectionStart; + setDispatch: (dispatch: Dispatch | null) => void; +} + +export type EmbeddedConsoleAction = + | { type: 'open'; payload?: { content?: string } } + | { type: 'close' }; + +export interface EmbeddedConsoleStore { + isOpen: boolean; + loadFromContent?: string; } diff --git a/src/plugins/console/public/types/plugin_dependencies.ts b/src/plugins/console/public/types/plugin_dependencies.ts index e4f65d44cb727..199e59d4b9b92 100644 --- a/src/plugins/console/public/types/plugin_dependencies.ts +++ b/src/plugins/console/public/types/plugin_dependencies.ts @@ -47,4 +47,14 @@ export interface ConsolePluginStart { * render an embeddable version of the developer console on the page. */ renderEmbeddableConsole?: (props?: EmbeddableConsoleProps) => ReactElement | null; + /** + * isEmbeddedConsoleAvailable is available if the embedded console can be rendered. Returns true when + * called if the Embedded Console is currently rendered. + */ + isEmbeddedConsoleAvailable?: () => boolean; + /** + * openEmbeddedConsole is available if the embedded console can be rendered. Calling + * this function will open the embedded console on the page if it is currently rendered. + */ + openEmbeddedConsole?: (content?: string) => void; } diff --git a/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts b/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts index 2379692abb736..4ab0cfae0932d 100644 --- a/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts +++ b/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts @@ -7,6 +7,7 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { CloudStart } from '@kbn/cloud-plugin/public'; +import type { ConsolePluginStart } from '@kbn/console-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; import type { FeaturesPluginStart } from '@kbn/features-plugin/public'; @@ -19,6 +20,7 @@ import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; export interface KibanaDeps { charts: ChartsPluginStart; cloud: CloudStart; + console?: ConsolePluginStart; data: DataPublicPluginStart; discover: DiscoverStart; features: FeaturesPluginStart; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/add_data_panel_content.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/add_data_panel_content.tsx index e834e9ff45fe5..5d2d8cecf8466 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/add_data_panel_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/add_data_panel_content.tsx @@ -43,6 +43,7 @@ export const AddDataPanelContent: React.FC = ({ setSelectedLanguage={setSelectedLanguage} assetBasePath={assetBasePath} application={services.application} + consolePlugin={services.console} sharePlugin={services.share} /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/search_query_panel_content.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/search_query_panel_content.tsx index 2ce2801f033e0..d32614865b614 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/search_query_panel_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/search_query_panel_content.tsx @@ -47,6 +47,7 @@ export const SearchQueryPanelContent: React.FC = ( setSelectedLanguage={setSelectedLanguage} assetBasePath={assetBasePath} application={services.application} + consolePlugin={services.console} sharePlugin={services.share} /> ); diff --git a/x-pack/plugins/serverless_search/public/application/components/overview.tsx b/x-pack/plugins/serverless_search/public/application/components/overview.tsx index 2a2313564c2e2..1cb337e6584b9 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview.tsx @@ -250,6 +250,7 @@ export const ElasticsearchOverview = () => { assetBasePath={assetBasePath} docLinks={docLinks} application={application} + consolePlugin={consolePlugin} sharePlugin={share} additionalIngestionPanel={} /> @@ -277,6 +278,7 @@ export const ElasticsearchOverview = () => { setSelectedLanguage={setSelectedLanguage} assetBasePath={assetBasePath} application={application} + consolePlugin={consolePlugin} sharePlugin={share} /> } From d8f44220c00ed51ab86ee5f201ff70f2235b1214 Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Thu, 8 Feb 2024 15:37:50 +0100 Subject: [PATCH 020/104] [Discover] Include global filters when opening a saved search (#175814) - Closes https://github.com/elastic/kibana/issues/171212 ## Summary Discover ignored global filters when loading a saved search, because it loads a saved search before it starts syncing with global URL state. This PR does not change the order of events but it adds a manual sync for global filters so they are included in search request anyway. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../discover_saved_search_container.ts | 31 +++++- .../main/services/discover_state.ts | 1 + .../main/services/load_saved_search.ts | 25 ++++- .../apps/discover/group1/_url_state.ts | 102 ++++++++++++++++++ 4 files changed, 155 insertions(+), 4 deletions(-) diff --git a/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts b/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts index ef88aba74d7db..ecae2208bffcc 100644 --- a/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts +++ b/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts @@ -8,6 +8,7 @@ import { SavedSearch } from '@kbn/saved-search-plugin/public'; import { BehaviorSubject } from 'rxjs'; +import { cloneDeep } from 'lodash'; import { COMPARE_ALL_OPTIONS, FilterCompareOptions } from '@kbn/es-query'; import type { SearchSourceFields } from '@kbn/data-plugin/common'; import type { DataView } from '@kbn/data-views-plugin/common'; @@ -110,6 +111,11 @@ export interface DiscoverSavedSearchContainer { * @param params */ update: (params: UpdateParams) => SavedSearch; + /** + * Passes filter manager filters to saved search filters + * @param params + */ + updateWithFilterManagerFilters: () => SavedSearch; } export function getSavedSearchContainer({ @@ -169,6 +175,26 @@ export function getSavedSearchContainer({ } return { id }; }; + + const assignNextSavedSearch = ({ nextSavedSearch }: { nextSavedSearch: SavedSearch }) => { + const hasChanged = !isEqualSavedSearch(savedSearchInitial$.getValue(), nextSavedSearch); + hasChanged$.next(hasChanged); + savedSearchCurrent$.next(nextSavedSearch); + }; + + const updateWithFilterManagerFilters = () => { + const nextSavedSearch: SavedSearch = { + ...getState(), + }; + + nextSavedSearch.searchSource.setField('filter', cloneDeep(services.filterManager.getFilters())); + + assignNextSavedSearch({ nextSavedSearch }); + + addLog('[savedSearch] updateWithFilterManagerFilters done', nextSavedSearch); + return nextSavedSearch; + }; + const update = ({ nextDataView, nextState, useFilterAndQueryServices }: UpdateParams) => { addLog('[savedSearch] update', { nextDataView, nextState }); @@ -186,9 +212,7 @@ export function getSavedSearchContainer({ useFilterAndQueryServices, }); - const hasChanged = !isEqualSavedSearch(savedSearchInitial$.getValue(), nextSavedSearch); - hasChanged$.next(hasChanged); - savedSearchCurrent$.next(nextSavedSearch); + assignNextSavedSearch({ nextSavedSearch }); addLog('[savedSearch] update done', nextSavedSearch); return nextSavedSearch; @@ -221,6 +245,7 @@ export function getSavedSearchContainer({ persist, set, update, + updateWithFilterManagerFilters, }; } diff --git a/src/plugins/discover/public/application/main/services/discover_state.ts b/src/plugins/discover/public/application/main/services/discover_state.ts index af3675156a93d..79577a8f8e616 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.ts @@ -357,6 +357,7 @@ export function getDiscoverStateContainer({ dataStateContainer, internalStateContainer, savedSearchContainer, + globalStateContainer, services, setDataView, }); diff --git a/src/plugins/discover/public/application/main/services/load_saved_search.ts b/src/plugins/discover/public/application/main/services/load_saved_search.ts index a921e7a69e58c..30ed1792a50e0 100644 --- a/src/plugins/discover/public/application/main/services/load_saved_search.ts +++ b/src/plugins/discover/public/application/main/services/load_saved_search.ts @@ -22,6 +22,7 @@ import { DiscoverAppStateContainer, getInitialState, } from './discover_app_state_container'; +import { DiscoverGlobalStateContainer } from './discover_global_state_container'; import { DiscoverServices } from '../../../build_services'; interface LoadSavedSearchDeps { @@ -29,6 +30,7 @@ interface LoadSavedSearchDeps { dataStateContainer: DiscoverDataStateContainer; internalStateContainer: DiscoverInternalStateContainer; savedSearchContainer: DiscoverSavedSearchContainer; + globalStateContainer: DiscoverGlobalStateContainer; services: DiscoverServices; setDataView: DiscoverStateContainer['actions']['setDataView']; } @@ -44,7 +46,13 @@ export const loadSavedSearch = async ( ): Promise => { addLog('[discoverState] loadSavedSearch'); const { savedSearchId } = params ?? {}; - const { appStateContainer, internalStateContainer, savedSearchContainer, services } = deps; + const { + appStateContainer, + internalStateContainer, + savedSearchContainer, + globalStateContainer, + services, + } = deps; const appStateExists = !appStateContainer.isEmptyURL(); const appState = appStateExists ? appStateContainer.getState() : undefined; @@ -59,6 +67,15 @@ export const loadSavedSearch = async ( services.filterManager.setAppFilters([]); services.data.query.queryString.clearQuery(); + // Sync global filters (coming from URL) to filter manager. + // It needs to be done manually here as `syncGlobalQueryStateWithUrl` is being called after this `loadSavedSearch` function. + const globalFilters = globalStateContainer?.get()?.filters; + const shouldUpdateWithGlobalFilters = + globalFilters?.length && !services.filterManager.getGlobalFilters()?.length; + if (shouldUpdateWithGlobalFilters) { + services.filterManager.setGlobalFilters(globalFilters); + } + // reset appState in case a saved search with id is loaded and // the url is empty so the saved search is loaded in a clean // state else it might be updated by the previous app state @@ -103,6 +120,10 @@ export const loadSavedSearch = async ( // Update all other services and state containers by the next saved search updateBySavedSearch(nextSavedSearch, deps); + if (!appState && shouldUpdateWithGlobalFilters) { + nextSavedSearch = savedSearchContainer.updateWithFilterManagerFilters(); + } + return nextSavedSearch; }; @@ -125,6 +146,7 @@ function updateBySavedSearch(savedSearch: SavedSearch, deps: LoadSavedSearchDeps // set data service filters const filters = savedSearch.searchSource.getField('filter'); if (Array.isArray(filters) && filters.length) { + // Saved search SO persists all filters as app filters services.data.query.filterManager.setAppFilters(cloneDeep(filters)); } // some filters may not be valid for this context, so update @@ -134,6 +156,7 @@ function updateBySavedSearch(savedSearch: SavedSearch, deps: LoadSavedSearchDeps if (!isEqual(currentFilters, validFilters)) { services.filterManager.setFilters(validFilters); } + // set data service query const query = savedSearch.searchSource.getField('query'); if (query) { diff --git a/test/functional/apps/discover/group1/_url_state.ts b/test/functional/apps/discover/group1/_url_state.ts index 027e767e8fe3d..e97ac332e8b6e 100644 --- a/test/functional/apps/discover/group1/_url_state.ts +++ b/test/functional/apps/discover/group1/_url_state.ts @@ -11,6 +11,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { + const deployment = getService('deployment'); const browser = getService('browser'); const log = getService('log'); const retry = getService('retry'); @@ -19,6 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const testSubjects = getService('testSubjects'); const appsMenu = getService('appsMenu'); + const dataGrid = getService('dataGrid'); const PageObjects = getPageObjects([ 'common', 'discover', @@ -30,6 +32,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const defaultSettings = { defaultIndex: 'logstash-*', + hideAnnouncements: true, }; describe('discover URL state', () => { @@ -117,5 +120,104 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); expect(await PageObjects.discover.getHitCount()).to.be('11,268'); }); + + it('should merge custom global filters with saved search filters', async () => { + await kibanaServer.uiSettings.update({ + 'timepicker:timeDefaults': + '{ "from": "Sep 18, 2015 @ 19:37:13.000", "to": "Sep 23, 2015 @ 02:30:09.000"}', + }); + await PageObjects.common.navigateToApp('discover'); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + await filterBar.addFilter({ + field: 'bytes', + operation: 'is between', + value: { from: '1000', to: '2000' }, + }); + await PageObjects.unifiedFieldList.clickFieldListItemAdd('extension'); + await PageObjects.unifiedFieldList.clickFieldListItemAdd('bytes'); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + const totalHitsForOneFilter = '737'; + const totalHitsForTwoFilters = '137'; + + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForOneFilter); + + await PageObjects.discover.saveSearch('testFilters'); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForOneFilter); + + await browser.refresh(); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForOneFilter); + + const url = await browser.getCurrentUrl(); + const savedSearchIdMatch = url.match(/view\/([^?]+)\?/); + const savedSearchId = savedSearchIdMatch?.length === 2 ? savedSearchIdMatch[1] : null; + + expect(typeof savedSearchId).to.be('string'); + + await browser.openNewTab(); + await browser.get(`${deployment.getHostPort()}/app/discover#/view/${savedSearchId}`); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + expect(await dataGrid.getRowsText()).to.eql([ + 'Sep 22, 2015 @ 20:44:05.521jpg1,808', + 'Sep 22, 2015 @ 20:41:53.463png1,969', + 'Sep 22, 2015 @ 20:40:22.952jpg1,576', + 'Sep 22, 2015 @ 20:11:39.532png1,708', + 'Sep 22, 2015 @ 19:45:13.813php1,406', + ]); + + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForOneFilter); + + await browser.openNewTab(); + await browser.get( + `${deployment.getHostPort()}/app/discover#/view/${savedSearchId}` + + "?_g=(filters:!(('$state':(store:globalState)," + + "meta:(alias:!n,disabled:!f,field:extension.raw,index:'logstash-*'," + + 'key:extension.raw,negate:!f,params:!(png,css),type:phrases,value:!(png,css)),' + + 'query:(bool:(minimum_should_match:1,should:!((match_phrase:(extension.raw:png)),' + + "(match_phrase:(extension.raw:css))))))),query:(language:kuery,query:'')," + + "refreshInterval:(pause:!t,value:60000),time:(from:'2015-09-19T06:31:44.000Z'," + + "to:'2015-09-23T18:31:44.000Z'))" + ); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + const filteredRows = [ + 'Sep 22, 2015 @ 20:41:53.463png1,969', + 'Sep 22, 2015 @ 20:11:39.532png1,708', + 'Sep 22, 2015 @ 18:50:22.335css1,841', + 'Sep 22, 2015 @ 18:40:32.329css1,945', + 'Sep 22, 2015 @ 18:13:35.361css1,752', + ]; + + expect(await dataGrid.getRowsText()).to.eql(filteredRows); + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForTwoFilters); + await testSubjects.existOrFail('unsavedChangesBadge'); + + await browser.refresh(); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + expect(await dataGrid.getRowsText()).to.eql(filteredRows); + expect(await PageObjects.discover.getHitCount()).to.be(totalHitsForTwoFilters); + await testSubjects.existOrFail('unsavedChangesBadge'); + }); }); } From b62011026850bf968a90c403cae11c453c4e9130 Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Thu, 8 Feb 2024 15:59:23 +0100 Subject: [PATCH 021/104] [Fleet] Allow back previously disabled bulk actions (#176485) Patch for https://github.com/elastic/kibana/issues/171914 ## Summary In https://github.com/elastic/kibana/pull/175318 I had disabled the bulk actions when the count was incorrect (negative). This was not a good idea, since some of those actions could still be applied (like unenrolling) even if the shown count is not correct. Here I'm removing that check. ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../sections/agents/agent_list_page/components/bulk_actions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx index cd00c194a6c11..3871473d40bae 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx @@ -105,7 +105,7 @@ export const AgentBulkActions: React.FunctionComponent = ({ const atLeastOneActiveAgentSelected = selectionMode === 'manual' ? !!selectedAgents.find((agent) => agent.active) - : agentCount > 0 && shownAgents > inactiveShownAgents; + : shownAgents > inactiveShownAgents; const agents = selectionMode === 'manual' ? selectedAgents : selectionQuery; const [tagsPopoverButton, setTagsPopoverButton] = useState(); From 3d431f3816255779ac5d71e88d5ef54a15a533b9 Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Thu, 8 Feb 2024 07:27:09 -0800 Subject: [PATCH 022/104] [Cloud Security] [Posture Dashboard] Update links to the findings page with groupBy option (#176463) --- .../common/utils/helpers.ts | 11 ++- .../public/common/constants.ts | 7 ++ .../common/hooks/use_navigate_findings.ts | 5 +- .../accounts_evaluated_widget.test.tsx | 69 +++++++++++++++++++ .../components/accounts_evaluated_widget.tsx | 32 +++++---- .../benchmark_details_box.tsx | 34 ++++++--- .../latest_findings/constants.ts | 16 ++--- .../latest_findings_group_renderer.tsx | 11 +-- .../use_latest_findings_grouping.tsx | 21 +++--- 9 files changed, 151 insertions(+), 55 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx diff --git a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts index cbeb334e2aa61..6222b457e7ad6 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts @@ -196,6 +196,15 @@ const CLOUD_PROVIDER_NAMES = { GCP: 'Google Cloud Platform', }; +export const CLOUD_PROVIDERS = { + AWS: 'aws', + AZURE: 'azure', + GCP: 'gcp', +}; + +/** + * Returns the cloud provider name or benchmark applicable name for the given benchmark id + */ export const getBenchmarkApplicableTo = (benchmarkId: BenchmarksCisId) => { switch (benchmarkId) { case 'cis_k8s': @@ -205,7 +214,7 @@ export const getBenchmarkApplicableTo = (benchmarkId: BenchmarksCisId) => { case 'cis_aws': return CLOUD_PROVIDER_NAMES.AWS; case 'cis_eks': - return 'Amazon Elastic Kubernetes Service'; + return 'Amazon Elastic Kubernetes Service (EKS)'; case 'cis_gcp': return CLOUD_PROVIDER_NAMES.GCP; } diff --git a/x-pack/plugins/cloud_security_posture/public/common/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/constants.ts index bd266c98b8015..735a28a8ed0e1 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/constants.ts @@ -230,3 +230,10 @@ export const DETECTION_ENGINE_RULES_KEY = 'detection_engine_rules'; export const DETECTION_ENGINE_ALERTS_KEY = 'detection_engine_alerts'; export const DEFAULT_GROUPING_TABLE_HEIGHT = 512; + +export const FINDINGS_GROUPING_OPTIONS = { + RESOURCE_NAME: 'resource.name', + RULE_NAME: 'rule.name', + CLOUD_ACCOUNT_NAME: 'cloud.account.name', + ORCHESTRATOR_CLUSTER_NAME: 'orchestrator.cluster.name', +}; diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts index fbeeeb32a0c2e..4b98057fc10c4 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts @@ -57,7 +57,7 @@ const useNavigate = (pathname: string, dataViewId = SECURITY_DEFAULT_DATA_VIEW_I const { services } = useKibana(); return useCallback( - (filterParams: NavFilter = {}) => { + (filterParams: NavFilter = {}, groupBy?: string[]) => { const filters = Object.entries(filterParams).map(([key, filterValue]) => createFilter(key, filterValue, dataViewId) ); @@ -68,10 +68,11 @@ const useNavigate = (pathname: string, dataViewId = SECURITY_DEFAULT_DATA_VIEW_I // Set query language from user's preference query: services.data.query.queryString.getDefaultQuery(), filters, + ...(groupBy && { groupBy }), }), }); }, - [pathname, history, services.data.query.queryString, dataViewId] + [history, pathname, services.data.query.queryString, dataViewId] ); }; diff --git a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx new file mode 100644 index 0000000000000..1973620c8d9d8 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, fireEvent } from '@testing-library/react'; +import { AccountsEvaluatedWidget } from './accounts_evaluated_widget'; +import { BenchmarkData } from '../../common/types_old'; +import { TestProvider } from '../test/test_provider'; + +const mockNavToFindings = jest.fn(); +jest.mock('../common/hooks/use_navigate_findings', () => ({ + useNavigateFindings: () => mockNavToFindings, +})); + +describe('AccountsEvaluatedWidget', () => { + const benchmarkAssets = [ + { meta: { benchmarkId: 'cis_aws', assetCount: 10 } }, + { meta: { benchmarkId: 'cis_k8s', assetCount: 20 } }, + ] as BenchmarkData[]; + + it('renders the component with benchmark data correctly', () => { + const { getByText } = render( + + + + ); + + expect(getByText('10')).toBeInTheDocument(); + expect(getByText('20')).toBeInTheDocument(); + }); + + it('calls navToFindingsByCloudProvider when a benchmark with provider is clicked', () => { + const { getByText } = render( + + + + ); + + fireEvent.click(getByText('10')); + + expect(mockNavToFindings).toHaveBeenCalledWith( + { + 'cloud.provider': 'aws', + }, + ['cloud.account.name'] + ); + }); + + it('calls navToFindingsByCisBenchmark when a benchmark with benchmarkId is clicked', () => { + const { getByText } = render( + + + + ); + + fireEvent.click(getByText('20')); + + expect(mockNavToFindings).toHaveBeenCalledWith( + { + 'rule.benchmark.id': 'cis_k8s', + }, + ['orchestrator.cluster.name'] + ); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx index a9b118be899ab..aeb734005a65b 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx @@ -7,38 +7,40 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; +import { CLOUD_PROVIDERS, getBenchmarkApplicableTo } from '../../common/utils/helpers'; import { CIS_AWS, CIS_GCP, CIS_AZURE, CIS_K8S, CIS_EKS } from '../../common/constants'; import { CISBenchmarkIcon } from './cis_benchmark_icon'; import { CompactFormattedNumber } from './compact_formatted_number'; import { useNavigateFindings } from '../common/hooks/use_navigate_findings'; import { BenchmarkData } from '../../common/types_old'; +import { FINDINGS_GROUPING_OPTIONS } from '../common/constants'; // order in array will determine order of appearance in the dashboard const benchmarks = [ { type: CIS_AWS, - name: 'Amazon Web Services (AWS)', - provider: 'aws', + name: getBenchmarkApplicableTo(CIS_AWS), + provider: CLOUD_PROVIDERS.AWS, }, { type: CIS_GCP, - name: 'Google Cloud Platform (GCP)', - provider: 'gcp', + name: getBenchmarkApplicableTo(CIS_GCP), + provider: CLOUD_PROVIDERS.GCP, }, { type: CIS_AZURE, - name: 'Azure', - provider: 'azure', + name: getBenchmarkApplicableTo(CIS_AZURE), + provider: CLOUD_PROVIDERS.AZURE, }, { type: CIS_K8S, - name: 'Kubernetes', - benchmarkId: 'cis_k8s', + name: getBenchmarkApplicableTo(CIS_K8S), + benchmarkId: CIS_K8S, }, { type: CIS_EKS, - name: 'Amazon Elastic Kubernetes Service (EKS)', - benchmarkId: 'cis_eks', + name: getBenchmarkApplicableTo(CIS_EKS), + benchmarkId: CIS_EKS, }, ]; @@ -59,11 +61,13 @@ export const AccountsEvaluatedWidget = ({ const navToFindings = useNavigateFindings(); const navToFindingsByCloudProvider = (provider: string) => { - navToFindings({ 'cloud.provider': provider }); + navToFindings({ 'cloud.provider': provider }, [FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]); }; const navToFindingsByCisBenchmark = (cisBenchmark: string) => { - navToFindings({ 'rule.benchmark.id': cisBenchmark }); + navToFindings({ 'rule.benchmark.id': cisBenchmark }, [ + FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME, + ]); }; const benchmarkElements = benchmarks.map((benchmark) => { @@ -75,10 +79,10 @@ export const AccountsEvaluatedWidget = ({ key={benchmark.type} onClick={() => { if (benchmark.provider) { - navToFindingsByCloudProvider(benchmark.provider); + return navToFindingsByCloudProvider(benchmark.provider); } if (benchmark.benchmarkId) { - navToFindingsByCisBenchmark(benchmark.benchmarkId); + return navToFindingsByCisBenchmark(benchmark.benchmarkId); } }} css={css` diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx index dc140fef121b3..ac9b48ddfdbfe 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx @@ -17,23 +17,32 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants'; import { getBenchmarkIdQuery } from './benchmarks_section'; import { BenchmarkData } from '../../../../common/types_old'; import { useNavigateFindings } from '../../../common/hooks/use_navigate_findings'; import { CISBenchmarkIcon } from '../../../components/cis_benchmark_icon'; import cisLogoIcon from '../../../assets/icons/cis_logo.svg'; + +interface BenchmarkInfo { + name: string; + assetType: string; + handleClick: () => void; +} + export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) => { const navToFindings = useNavigateFindings(); - const handleBenchmarkClick = () => { - return navToFindings(getBenchmarkIdQuery(benchmark)); - }; + const handleClickCloudProvider = () => + navToFindings(getBenchmarkIdQuery(benchmark), [FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]); + + const handleClickCluster = () => + navToFindings(getBenchmarkIdQuery(benchmark), [ + FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME, + ]); - const getBenchmarkInfo = ( - benchmarkId: string, - cloudAssetCount: number - ): { name: string; assetType: string } => { - const benchmarks: Record = { + const getBenchmarkInfo = (benchmarkId: string, cloudAssetCount: number): BenchmarkInfo => { + const benchmarks: Record = { cis_gcp: { name: i18n.translate( 'xpack.csp.dashboard.benchmarkSection.benchmarkName.cisGcpBenchmarkName', @@ -48,6 +57,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) values: { count: cloudAssetCount }, } ), + handleClick: handleClickCloudProvider, }, cis_aws: { name: i18n.translate( @@ -63,6 +73,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) values: { count: cloudAssetCount }, } ), + handleClick: handleClickCloudProvider, }, cis_azure: { name: i18n.translate( @@ -78,6 +89,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) values: { count: cloudAssetCount }, } ), + handleClick: handleClickCloudProvider, }, cis_k8s: { name: i18n.translate( @@ -93,6 +105,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) values: { count: cloudAssetCount }, } ), + handleClick: handleClickCluster, }, cis_eks: { name: i18n.translate( @@ -108,6 +121,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) values: { count: cloudAssetCount }, } ), + handleClick: handleClickCluster, }, }; return benchmarks[benchmarkId]; @@ -149,14 +163,14 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) } > - +
{benchmarkInfo.name}
- + {benchmarkInfo.assetType} diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts index 3d8200a144bd5..1292da8601357 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { GroupOption } from '@kbn/securitysolution-grouping'; +import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants'; import { FindingsBaseURLQuery } from '../../../common/types'; import { CloudSecurityDefaultColumn } from '../../../components/cloud_security_data_table'; @@ -16,13 +17,6 @@ export const FINDINGS_UNIT = (totalCount: number) => defaultMessage: `{totalCount, plural, =1 {finding} other {findings}}`, }); -export const GROUPING_OPTIONS = { - RESOURCE_NAME: 'resource.name', - RULE_NAME: 'rule.name', - CLOUD_ACCOUNT_NAME: 'cloud.account.name', - ORCHESTRATOR_CLUSTER_NAME: 'orchestrator.cluster.name', -}; - export const NULL_GROUPING_UNIT = i18n.translate('xpack.csp.findings.grouping.nullGroupUnit', { defaultMessage: 'findings', }); @@ -51,25 +45,25 @@ export const defaultGroupingOptions: GroupOption[] = [ label: i18n.translate('xpack.csp.findings.latestFindings.groupByResource', { defaultMessage: 'Resource', }), - key: GROUPING_OPTIONS.RESOURCE_NAME, + key: FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME, }, { label: i18n.translate('xpack.csp.findings.latestFindings.groupByRuleName', { defaultMessage: 'Rule name', }), - key: GROUPING_OPTIONS.RULE_NAME, + key: FINDINGS_GROUPING_OPTIONS.RULE_NAME, }, { label: i18n.translate('xpack.csp.findings.latestFindings.groupByCloudAccount', { defaultMessage: 'Cloud account', }), - key: GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME, + key: FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME, }, { label: i18n.translate('xpack.csp.findings.latestFindings.groupByKubernetesCluster', { defaultMessage: 'Kubernetes cluster', }), - key: GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME, + key: FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME, }, ]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx index fe8536eaf0f69..6dbc78cbf0857 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx @@ -17,6 +17,7 @@ import { css } from '@emotion/react'; import { GroupPanelRenderer, RawBucket, StatRenderer } from '@kbn/securitysolution-grouping/src'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants'; import { NullGroup, LoadingGroup, @@ -26,7 +27,7 @@ import { getAbbreviatedNumber } from '../../../common/utils/get_abbreviated_numb import { CISBenchmarkIcon } from '../../../components/cis_benchmark_icon'; import { ComplianceScoreBar } from '../../../components/compliance_score_bar'; import { FindingsGroupingAggregation } from './use_grouped_findings'; -import { GROUPING_OPTIONS, NULL_GROUPING_MESSAGES, NULL_GROUPING_UNIT } from './constants'; +import { NULL_GROUPING_MESSAGES, NULL_GROUPING_UNIT } from './constants'; import { FINDINGS_GROUPING_COUNTER } from '../test_subjects'; export const groupPanelRenderer: GroupPanelRenderer = ( @@ -45,7 +46,7 @@ export const groupPanelRenderer: GroupPanelRenderer ); switch (selectedGroup) { - case GROUPING_OPTIONS.RESOURCE_NAME: + case FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME: return nullGroupMessage ? ( renderNullGroup(NULL_GROUPING_MESSAGES.RESOURCE_NAME) ) : ( @@ -78,7 +79,7 @@ export const groupPanelRenderer: GroupPanelRenderer ); - case GROUPING_OPTIONS.RULE_NAME: + case FINDINGS_GROUPING_OPTIONS.RULE_NAME: return nullGroupMessage ? ( renderNullGroup(NULL_GROUPING_MESSAGES.RULE_NAME) ) : ( @@ -100,7 +101,7 @@ export const groupPanelRenderer: GroupPanelRenderer ); - case GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME: + case FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME: return nullGroupMessage ? ( renderNullGroup(NULL_GROUPING_MESSAGES.CLOUD_ACCOUNT_NAME) ) : ( @@ -129,7 +130,7 @@ export const groupPanelRenderer: GroupPanelRenderer ); - case GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME: + case FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME: return nullGroupMessage ? ( renderNullGroup(NULL_GROUPING_MESSAGES.ORCHESTRATOR_CLUSTER_NAME) ) : ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx index 74efd68b5378b..81df07731c5dd 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx @@ -15,7 +15,10 @@ import { } from '@kbn/securitysolution-grouping/src'; import { useMemo } from 'react'; import { buildEsQuery, Filter } from '@kbn/es-query'; -import { LOCAL_STORAGE_FINDINGS_GROUPING_KEY } from '../../../common/constants'; +import { + FINDINGS_GROUPING_OPTIONS, + LOCAL_STORAGE_FINDINGS_GROUPING_KEY, +} from '../../../common/constants'; import { useDataViewContext } from '../../../common/contexts/data_view_context'; import { Evaluation } from '../../../../common/types_old'; import { LATEST_FINDINGS_RETENTION_POLICY } from '../../../../common/constants'; @@ -24,13 +27,7 @@ import { FindingsRootGroupingAggregation, useGroupedFindings, } from './use_grouped_findings'; -import { - FINDINGS_UNIT, - groupingTitle, - defaultGroupingOptions, - getDefaultQuery, - GROUPING_OPTIONS, -} from './constants'; +import { FINDINGS_UNIT, groupingTitle, defaultGroupingOptions, getDefaultQuery } from './constants'; import { useCloudSecurityGrouping } from '../../../components/cloud_security_grouping'; import { getFilters } from '../utils/get_filters'; import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api'; @@ -80,26 +77,26 @@ const getAggregationsByGroupField = (field: string): NamedAggregation[] => { ]; switch (field) { - case GROUPING_OPTIONS.RESOURCE_NAME: + case FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME: return [ ...aggMetrics, getTermAggregation('resourceName', 'resource.id'), getTermAggregation('resourceSubType', 'resource.sub_type'), getTermAggregation('resourceType', 'resource.type'), ]; - case GROUPING_OPTIONS.RULE_NAME: + case FINDINGS_GROUPING_OPTIONS.RULE_NAME: return [ ...aggMetrics, getTermAggregation('benchmarkName', 'rule.benchmark.name'), getTermAggregation('benchmarkVersion', 'rule.benchmark.version'), ]; - case GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME: + case FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME: return [ ...aggMetrics, getTermAggregation('benchmarkName', 'rule.benchmark.name'), getTermAggregation('benchmarkId', 'rule.benchmark.id'), ]; - case GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME: + case FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME: return [ ...aggMetrics, getTermAggregation('benchmarkName', 'rule.benchmark.name'), From 7a55b8c94a89bb0b593dcb413e3e0f45a9668d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:34:19 +0000 Subject: [PATCH 023/104] [Index Management] Change the column Components in the Index templates table (#175823) ## Summary Fixes https://github.com/elastic/kibana/issues/175690 This PR changes the column Components to display a number of component templates instead of listing the names, since the text is truncated and in my opinion is not really readable. The full list of component templates can still be viewed in the index templates details flyout. The number of component templates is also a link that redirects to the Component templates table with a filter initialized in the search bar to view only those component templates that are used by a specific index template. ### Screenshots #### Index templates Before Screenshot 2024-01-29 at 16 41 55 After Screenshot 2024-01-29 at 16 40 40 #### Component templates Screenshot 2024-01-29 at 16 40 48 Summarize your PR. If it involves visual changes include a screenshot or gif. ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] 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)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] 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)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../helpers/test_subjects.ts | 3 +- .../home/index_templates_tab.helpers.ts | 4 +-- .../home/index_templates_tab.test.ts | 29 +++++++++++++++---- .../common/types/templates.ts | 1 + .../component_template_list.test.ts | 18 ++++++++++++ .../component_template_list.helpers.ts | 20 +++++++++---- .../component_template_list.tsx | 3 ++ .../component_template_list_container.tsx | 11 ++++++- .../component_template_list/table.tsx | 4 +++ .../template_table/template_table.tsx | 22 ++++++++++---- .../public/application/services/routing.ts | 9 ++++++ .../test/fixtures/template.ts | 2 ++ 12 files changed, 107 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/test_subjects.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/test_subjects.ts index 6448b9b79d0a5..c68dcdfc53cec 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/test_subjects.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/test_subjects.ts @@ -113,4 +113,5 @@ export type TestSubjects = | 'createIndexMessage' | 'indicesSearch' | 'noIndicesMessage' - | 'clearIndicesSearch'; + | 'clearIndicesSearch' + | 'componentTemplatesLink'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts index a56d633217f96..6add533ef57fc 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts @@ -67,7 +67,7 @@ const createActions = (testBed: TestBed) => { component.update(); }; - const clickTemplateAction = ( + const clickTemplateAction = async ( templateName: TemplateDeserialized['name'], action: 'edit' | 'clone' | 'delete' ) => { @@ -76,7 +76,7 @@ const createActions = (testBed: TestBed) => { clickActionMenu(templateName); - act(() => { + await act(async () => { component.find('button.euiContextMenuItem').at(actions.indexOf(action)).simulate('click'); }); component.update(); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts index f052317513194..615b8df18f905 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts @@ -78,6 +78,26 @@ describe('Index Templates tab', () => { expect(exists('templateTable')).toBe(true); expect(exists('legacyTemplateTable')).toBe(false); }); + + test('Components column renders a link to Component templates', async () => { + httpRequestsMockHelpers.setLoadTemplatesResponse({ + templates: [ + fixtures.getComposableTemplate({ + name: 'Test', + composedOf: ['component1', 'component2'], + }), + ], + legacyTemplates: [], + }); + + await act(async () => { + testBed = await setup(httpSetup); + }); + const { exists, component } = testBed; + component.update(); + + expect(exists('componentTemplatesLink')).toBe(true); + }); }); describe('when there are index templates', () => { @@ -168,19 +188,18 @@ describe('Index Templates tab', () => { // Test composable table content tableCellsValues.forEach((row, i) => { const indexTemplate = templates[i]; - const { name, indexPatterns, ilmPolicy, composedOf, template } = indexTemplate; + const { name, indexPatterns, composedOf, template } = indexTemplate; const hasContent = !!template?.settings || !!template?.mappings || !!template?.aliases; - const ilmPolicyName = ilmPolicy && ilmPolicy.name ? ilmPolicy.name : ''; - const composedOfString = composedOf ? composedOf.join(',') : ''; + const composedOfCount = `${composedOf ? composedOf.length : 0}`; try { expect(removeWhiteSpaceOnArrayValues(row)).toEqual([ '', // Checkbox to select row name, indexPatterns.join(', '), - ilmPolicyName, - composedOfString, + composedOfCount, + '', // data stream column hasContent ? 'M S A' : 'None', // M S A -> Mappings Settings Aliases badges 'EditDelete', // Column of actions ]); diff --git a/x-pack/plugins/index_management/common/types/templates.ts b/x-pack/plugins/index_management/common/types/templates.ts index 756d631202445..e2f530b4ad502 100644 --- a/x-pack/plugins/index_management/common/types/templates.ts +++ b/x-pack/plugins/index_management/common/types/templates.ts @@ -91,6 +91,7 @@ export interface TemplateListItem { ilmPolicy?: { name: string; }; + composedOf?: string[]; _kbnMeta: { type: TemplateType; hasDatastream: boolean; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts index c4595998bcd20..a843f9fe28597 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts @@ -173,6 +173,24 @@ describe('', () => { }); }); + describe('if filter is set, component templates are filtered', () => { + test('search value is set if url param is set', async () => { + const filter = 'usedBy=(test_index_template_1)'; + await act(async () => { + testBed = await setup(httpSetup, { filter }); + }); + + testBed.component.update(); + + const { table } = testBed; + const search = testBed.actions.getSearchValue(); + expect(search).toBe(filter); + + const { rows } = table.getMetaData('componentTemplatesTable'); + expect(rows.length).toBe(1); + }); + }); + describe('No component templates', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts index 1bd0152c86d40..8ebc905543a26 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts @@ -19,13 +19,14 @@ import { BASE_PATH } from '../../../../../../../common'; import { WithAppDependencies } from './setup_environment'; import { ComponentTemplateList } from '../../../component_template_list/component_template_list'; -const testBedConfig: AsyncTestBedConfig = { +const getTestBedConfig = (props?: any): AsyncTestBedConfig => ({ memoryRouter: { initialEntries: [`${BASE_PATH}component_templates`], componentRoutePath: `${BASE_PATH}component_templates`, }, doMountAsync: true, -}; + defaultProps: props, +}); export type ComponentTemplateListTestBed = TestBed & { actions: ReturnType; @@ -73,18 +74,26 @@ const createActions = (testBed: TestBed) => { deleteButton.simulate('click'); }; + const getSearchValue = () => { + return find('componentTemplatesSearch').prop('defaultValue'); + }; + return { clickReloadButton, clickComponentTemplateAt, clickDeleteActionAt, clickTableColumnSortButton, + getSearchValue, }; }; -export const setup = async (httpSetup: HttpSetup): Promise => { +export const setup = async ( + httpSetup: HttpSetup, + props?: any +): Promise => { const initTestBed = registerTestBed( WithAppDependencies(ComponentTemplateList, httpSetup), - testBedConfig + getTestBedConfig(props) ); const testBed = await initTestBed(); @@ -104,7 +113,8 @@ export type ComponentTemplateTestSubjects = | 'sectionLoading' | 'componentTemplatesLoadError' | 'deleteComponentTemplateButton' - | 'deprecatedComponentTemplateBadge' | 'reloadButton' + | 'componentTemplatesSearch' + | 'deprecatedComponentTemplateBadge' | 'componentTemplatesFiltersButton' | 'componentTemplates--deprecatedFilter'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index fc309751bfe8d..65e369cc8c880 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -36,6 +36,7 @@ import { useRedirectPath } from '../../../hooks/redirect_path'; interface Props { componentTemplateName?: string; history: RouteComponentProps['history']; + filter?: string; } const { useGlobalFlyout } = GlobalFlyout; @@ -43,6 +44,7 @@ const { useGlobalFlyout } = GlobalFlyout; export const ComponentTemplateList: React.FunctionComponent = ({ componentTemplateName, history, + filter, }) => { const { addContent: addContentToGlobalFlyout, removeContent: removeContentFromGlobalFlyout } = useGlobalFlyout(); @@ -183,6 +185,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ { const { executionContext } = useComponentTemplatesContext(); @@ -33,10 +35,17 @@ export const ComponentTemplateListContainer: React.FunctionComponent< page: 'indexManagementComponentTemplatesTab', }); + const urlParams = qs.parse(location.search); + const filter = urlParams.filter ?? ''; + return ( - + ); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx index f4d9c55407fd9..7f6eb87566410 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx @@ -51,6 +51,7 @@ const deprecatedFilterLabel = i18n.translate( export interface Props { componentTemplates: ComponentTemplateListItem[]; + defaultFilter: string; onReloadClick: () => void; onDeleteClick: (componentTemplateName: string[]) => void; onEditClick: (componentTemplateName: string) => void; @@ -60,6 +61,7 @@ export interface Props { export const ComponentTable: FunctionComponent = ({ componentTemplates, + defaultFilter, onReloadClick, onDeleteClick, onEditClick, @@ -188,6 +190,7 @@ export const ComponentTable: FunctionComponent = ({ ], box: { incremental: true, + 'data-test-subj': 'componentTemplatesSearch', }, filters: [ { @@ -220,6 +223,7 @@ export const ComponentTable: FunctionComponent = ({ }, }, ], + defaultQuery: defaultFilter, }, pagination: { initialPageSize: 10, diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx index a0b4f07e61722..4a08a93c9a0c4 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx @@ -18,8 +18,8 @@ import { UseRequestResponse, reactRouterNavigate } from '../../../../../shared_i import { useServices } from '../../../../app_context'; import { TemplateDeleteModal } from '../../../../components'; import { TemplateContentIndicator } from '../../../../components/shared'; +import { getComponentTemplatesLink, getTemplateDetailsLink } from '../../../../services/routing'; import { TemplateTypeIndicator, TemplateDeprecatedBadge } from '../components'; -import { getTemplateDetailsLink } from '../../../../services/routing'; interface Props { templates: TemplateListItem[]; @@ -85,12 +85,24 @@ export const TemplateTable: React.FunctionComponent = ({ { field: 'composedOf', name: i18n.translate('xpack.idxMgmt.templateList.table.componentsColumnTitle', { - defaultMessage: 'Components', + defaultMessage: 'Component templates', }), + width: '100px', truncateText: true, - sortable: true, - width: '20%', - render: (composedOf: string[] = []) => {composedOf.join(', ')}, + sortable: (template) => { + return template.composedOf?.length; + }, + render: (composedOf: string[] = [], item: TemplateListItem) => + composedOf.length === 0 ? ( + 0 + ) : ( + + {composedOf.length} + + ), }, { name: i18n.translate('xpack.idxMgmt.templateList.table.dataStreamColumnTitle', { diff --git a/x-pack/plugins/index_management/public/application/services/routing.ts b/x-pack/plugins/index_management/public/application/services/routing.ts index a2d4a03013556..07653d2591ffc 100644 --- a/x-pack/plugins/index_management/public/application/services/routing.ts +++ b/x-pack/plugins/index_management/public/application/services/routing.ts @@ -69,3 +69,12 @@ export const getIndexDetailsLink = ( } return link; }; + +export const getComponentTemplatesLink = (usedByTemplateName?: string) => { + let url = '/component_templates'; + if (usedByTemplateName) { + const filter = `usedBy=(${usedByTemplateName})`; + url = `${url}?filter=${encodeURIComponent(filter)}`; + } + return url; +}; diff --git a/x-pack/plugins/index_management/test/fixtures/template.ts b/x-pack/plugins/index_management/test/fixtures/template.ts index 01f83e2d76ff5..f7db386095b07 100644 --- a/x-pack/plugins/index_management/test/fixtures/template.ts +++ b/x-pack/plugins/index_management/test/fixtures/template.ts @@ -23,6 +23,7 @@ export const getComposableTemplate = ({ isLegacy = false, type = 'default', allowAutoCreate = false, + composedOf = [], }: Partial< TemplateDeserialized & { isLegacy?: boolean; @@ -53,6 +54,7 @@ export const getComposableTemplate = ({ hasDatastream, isLegacy, }, + composedOf, }; return indexTemplate; From ebb387692c397e1eb1636ee8f0005b179a99424c Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:38:35 +0100 Subject: [PATCH 024/104] [Fleet] more detailed error message on top-level manifest archive error (#176492) Logging more specific info in the error message about which manifest file is not found. --- .../plugins/fleet/server/services/epm/archive/parse.test.ts | 2 +- x-pack/plugins/fleet/server/services/epm/archive/parse.ts | 4 +++- .../test/fleet_api_integration/apis/epm/install_by_upload.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts index ac72f56946d04..f8f2734444b25 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts @@ -408,7 +408,7 @@ describe('parseAndVerifyArchive', () => { it('should throw on missing manifest file', () => { expect(() => parseAndVerifyArchive(['input_only-0.1.0/test/manifest.yml'], {})).toThrowError( new PackageInvalidArchiveError( - 'Package at top-level directory input_only-0.1.0 must contain a top-level manifest.yml file.' + 'Manifest file input_only-0.1.0/manifest.yml not found in paths.' ) ); }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts index b7a2b8a26400c..b0b5d8a94f06f 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts @@ -220,7 +220,9 @@ export function parseAndVerifyArchive( logger.debug(`Verifying archive - checking manifest file and manifest buffer`); if (!paths.includes(manifestFile) || !manifestBuffer) { throw new PackageInvalidArchiveError( - `Package at top-level directory ${toplevelDir} must contain a top-level ${MANIFEST_NAME} file.` + !paths.includes(manifestFile) + ? `Manifest file ${manifestFile} not found in paths.` + : `Manifest buffer is not found in assets map for manifest file ${manifestFile}.` ); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts index c34413aaae2c2..ac741e10db1e1 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts @@ -207,7 +207,7 @@ export default function (providerContext: FtrProviderContext) { .send(buf) .expect(400); expect(res.error.text).to.equal( - '{"statusCode":400,"error":"Bad Request","message":"Package at top-level directory apache-0.1.4 must contain a top-level manifest.yml file."}' + '{"statusCode":400,"error":"Bad Request","message":"Manifest file apache-0.1.4/manifest.yml not found in paths."}' ); }); From bb11c087a4e18846aa049e79c164b867b86c3b3f Mon Sep 17 00:00:00 2001 From: Jill Guyonnet Date: Thu, 8 Feb 2024 15:43:13 +0000 Subject: [PATCH 025/104] [Fleet] Add serverless dev docs (#176304) ## Summary Add Fleet dev docs with detailed instructions for running Kibana in serverless mode. --- x-pack/plugins/fleet/README.md | 4 + .../developing_kibana_and_fleet_server.md | 9 +- .../developing_kibana_in_serverless.md | 122 ++++++++++++++++++ 3 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/fleet/dev_docs/developing_kibana_in_serverless.md diff --git a/x-pack/plugins/fleet/README.md b/x-pack/plugins/fleet/README.md index 07dd4bfd67c00..4fd48aa82aff6 100644 --- a/x-pack/plugins/fleet/README.md +++ b/x-pack/plugins/fleet/README.md @@ -38,6 +38,8 @@ Note: The plugin was previously named Ingest Manager, it's possible that some va These are some additional recommendations to the steps detailed in the [Kibana Developer Guide](https://docs.elastic.dev/kibana-dev-docs/getting-started/setup-dev-env). +Note: this section details how to run Kibana in stateful mode. For serverless development, see the [Developing Kibana in serverless mode](dev_docs/developing_kibana_and_fleet_server.md) guide. + 1. Create a `config/kibana.dev.yml` file by copying the existing `config/kibana.yml` file. 2. It is recommended to explicitly set a base path for Kibana (refer to [Considerations for basepath](https://www.elastic.co/guide/en/kibana/current/development-basepath.html) for details). To do this, add the following to your `kibana.dev.yml`: @@ -93,6 +95,8 @@ Refer to the [Running Elasticsearch during development](https://www.elastic.co/g It can be useful to run Fleet Server in a container on your local machine in order to free up your actual "bare metal" machine to run Elastic Agent for testing purposes. Otherwise, you'll only be able to a single instance of Elastic Agent dedicated to Fleet Server on your local machine, and this can make testing integrations and policies difficult. +Note: if you need to do simultaneous Kibana and Fleet Server development, refer to the [Developing Kibana and Fleet Server simulatanously](dev_docs/developing_kibana_and_fleet_server.md) guide. + _The following is adapted from the Fleet Server [README](https://github.com/elastic/fleet-server#running-elastic-agent-with-fleet-server-in-container)_ 1. Add the following configuration to your `kibana.dev.yml` diff --git a/x-pack/plugins/fleet/dev_docs/developing_kibana_and_fleet_server.md b/x-pack/plugins/fleet/dev_docs/developing_kibana_and_fleet_server.md index 376d6cbb739e6..745f205c72a03 100644 --- a/x-pack/plugins/fleet/dev_docs/developing_kibana_and_fleet_server.md +++ b/x-pack/plugins/fleet/dev_docs/developing_kibana_and_fleet_server.md @@ -402,11 +402,14 @@ _To do: add specific docs for enrolling Multipass agents and link here_ ## Running in serverless mode -If you want to run your local stack in serverless mode, you'll only need to alter the commands used to start Elasticsearch and Kibana. Fleet Server does not require any changes outside of what's listed above to run in a serverless context. From your Kibana, start a serverless Elasticsearch snapshot, and then run Kibana as either a security or observability project. +If you want to run your local stack in serverless mode, you'll only need to alter the commands used to start Elasticsearch and Kibana. Fleet Server does not require any changes outside of what's listed above to run in a serverless context. From your Kibana, start a serverless Elasticsearch snapshot as either a security or observability project, and then run Kibana using the same project type. ```bash -# Start Elasticsearch in serverless mode -yarn es serverless --kill +# Start Elasticsearch in serverless mode as a security project +yarn es serverless --projectType=security --kill + +# Start Elasticsearch in serverless mode as an observability project +yarn es serverless --projectType=oblt --kill # Run kibana as a security project yarn serverless-security diff --git a/x-pack/plugins/fleet/dev_docs/developing_kibana_in_serverless.md b/x-pack/plugins/fleet/dev_docs/developing_kibana_in_serverless.md new file mode 100644 index 0000000000000..f52ec7bcec700 --- /dev/null +++ b/x-pack/plugins/fleet/dev_docs/developing_kibana_in_serverless.md @@ -0,0 +1,122 @@ +# Developing Kibana in serverless mode + +Fleet is enabled for the observability and security serverless project types. + +To run Elasticsearch and Kibana in serverless mode, the relevant commands are: + +For the observability project type: +```bash +# Start Elasticsearch in serverless mode as an observability project +yarn es serverless --projectType=oblt --kill + +# Run Kibana as an observability project +yarn serverless-oblt +``` + +and one of: + +```bash +# Start Elasticsearch in serverless mode as a security project +yarn es serverless --projectType=security --kill + +# Run Kibana as a security project +yarn serverless-security +``` + +Once running, you can login at `http://localhost:5601` with the username `elastic_serverless` or `system_indices_superuser` and the password `changeme`. + +Note: it is not possible to use a base path in serverless mode. In case of issue, make sure the `server.basePath` property is not set in the config. + +Tip: to reset Elasticsearch data, delete the following folder: + +```bash +# Run this from the kibana folder: +rm -rf .es/stateless +``` + +## Kibana config + +### Setting a project id + +Create a `config/serverless.dev.yml` config file if you don't already have one and add a project id: + +```yaml +xpack.cloud.serverless.project_id: test-123 +``` + +The project id is required for some functionality, such as the `isServerless` flag in Fleet's cloud setup. + +### Fleet config + +The `kibana.dev.yml` settings should be mostly the same as for stateful mode. There are however a few key differences. + +As noted above, the base path should not be set (`server.basePath` setting). + +To enroll agents with a standalone Fleet Server set: +```yaml +xpack.fleet.internal.fleetServerStandalone: true +``` + +Finally, it may be necessary for the Fleet config to accurately reflect the generated config for serverless projects, which is defined in [project-controller](https://github.com/elastic/project-controller/blob/69dc1e6b0761bd9c933c23c2a471f32e1b8f1d28/internal/application/kibana/fleet_config.go#L43). At the time of writing, this concerns the default Fleet Server host and default output: + +```yaml +xpack.fleet.fleetServerHosts: + - id: default-fleet-server + name: Default Fleet server + is_default: true + host_urls: ['http://localhost:8220'] + # If you want to run a Fleet Server containers via Docker, use this URL: + # host_urls: ['https://host.docker.internal:8220'] +xpack.fleet.outputs: + - id: es-default-output + name: Default output + type: elasticsearch + is_default: true + is_default_monitoring: true + hosts: ['https://localhost:9200'] + # # If you enroll agents via Docker, use this URL: + # hosts: ['https://host.docker.internal:9200'] +``` + +## Running a Fleet Server and enrolling agents + +In serverless mode, Fleet Server runs in standalone mode. Unless you are [simultaneously developing Kibana and Fleet Server](./developing_kibana_and_fleet_server.mddeveloping_), it is easier to run Fleet Server as a Docker container. + +The Kibana's dev utils package defines a hard-coded [Fleet Server service token](ttps://github.com/elastic/kibana/blob/92b6fd64cd58fd62f69898c222e86409d5f15b60/packages/kbn-dev-utils/src/dev_service_account.ts#L21-L25) and fingerprint of the ca.crt certificate. + +Running a standalone Fleet Server: + +```bash +docker run -it --rm \ + -e ELASTICSEARCH_HOSTS="http://host.docker.internal:9200" \ + -e ELASTICSEARCH_SERVICE_TOKEN="AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL2ZsZWV0LXNlcnZlci1kZXY6VVo1TWd6MnFTX3FVTWliWGNXNzlwQQ" \ + -e ELASTICSEARCH_CA_TRUSTED_FINGERPRINT="F71F73085975FD977339A1909EBFE2DF40DB255E0D5BB56FC37246BF383FFC84" \ + -p 8220:8220 \ + docker.elastic.co/observability-ci/fleet-server:latest +``` + +Containerized elastic agents can then be enrolled using: + +```bash +docker run \ + -e FLEET_URL=http://host.docker.internal:8220 \ + -e FLEET_ENROLL=1 \ + -e FLEET_ENROLLMENT_TOKEN=== \ + -e FLEET_INSECURE=1 \ + --rm docker.elastic.co/beats/elastic-agent: +``` + +## Troubleshooting + +### `Cannot read existing Message Signing Key pair` issue + +At the time of writing, there is a known issue where Fleet may fail to load due to error generating key pair for message signing. This may in particular happen after running API integration tests. The easiest solution in development is to reset Elasticsearch data: + +```bash +# Run this from the kibana folder: +rm -rf .es/stateless +``` + +## Release + +Serverless Kibana is periodically released from `main` following a deployment workflow composed of four environments (CI, QA, Staging, Production). It is therefore important to be aware of the release schedule and ensure timely communication with our QA team prior to merging. From f50e5bb8b7efb8fade7f8c1dac74de0e40c04d93 Mon Sep 17 00:00:00 2001 From: Janki Salvi <117571355+js-jankisalvi@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:44:34 +0100 Subject: [PATCH 026/104] [Cases] Update custom field internal api (#176168) ## Summary Related to https://github.com/elastic/kibana/issues/175931 This PR creates an internal API to update single custom field of a case Path: `PATCH /internal/cases//custom_fields/{customFieldId}` Body: `{ "customFieldDetails": { "type": customField type, "value": customField value, }, "version": Cases version }` **Flaky test runner:** https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5065 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../plugins/cases/common/constants/index.ts | 2 +- .../plugins/cases/common/types/api/case/v1.ts | 9 +- .../common/types/api/custom_field/v1.test.ts | 64 ++- .../cases/common/types/api/custom_field/v1.ts | 12 + .../cases/server/client/cases/client.ts | 10 +- .../client/cases/replace_custom_field.test.ts | 394 +++++++++++++++ .../client/cases/replace_custom_field.ts | 169 +++++++ x-pack/plugins/cases/server/client/mocks.ts | 1 + .../server/routes/api/get_internal_routes.ts | 2 + .../api/internal/replace_custom_field.ts | 48 ++ .../common/lib/api/index.ts | 37 ++ .../security_and_spaces/tests/common/index.ts | 1 + .../common/internal/replace_custom_field.ts | 464 ++++++++++++++++++ 13 files changed, 1206 insertions(+), 7 deletions(-) create mode 100644 x-pack/plugins/cases/server/client/cases/replace_custom_field.test.ts create mode 100644 x-pack/plugins/cases/server/client/cases/replace_custom_field.ts create mode 100644 x-pack/plugins/cases/server/routes/api/internal/replace_custom_field.ts create mode 100644 x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/replace_custom_field.ts diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index ba7e98d775efb..50dda0c185176 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -82,7 +82,7 @@ export const INTERNAL_DELETE_FILE_ATTACHMENTS_URL = export const INTERNAL_GET_CASE_CATEGORIES_URL = `${CASES_INTERNAL_URL}/categories` as const; export const INTERNAL_CASE_METRICS_URL = `${CASES_INTERNAL_URL}/metrics` as const; export const INTERNAL_CASE_METRICS_DETAILS_URL = `${CASES_INTERNAL_URL}/metrics/{case_id}` as const; - +export const INTERNAL_PUT_CUSTOM_FIELDS_URL = `${CASES_INTERNAL_URL}/{case_id}/custom_fields/{custom_field_id}`; /** * Action routes */ diff --git a/x-pack/plugins/cases/common/types/api/case/v1.ts b/x-pack/plugins/cases/common/types/api/case/v1.ts index acb8049e01737..0dff1cac0d95d 100644 --- a/x-pack/plugins/cases/common/types/api/case/v1.ts +++ b/x-pack/plugins/cases/common/types/api/case/v1.ts @@ -51,7 +51,7 @@ const CaseCustomFieldTextWithValidationRt = rt.strict({ const CustomFieldRt = rt.union([CaseCustomFieldTextWithValidationRt, CaseCustomFieldToggleRt]); -const CustomFieldsRt = limitedArraySchema({ +export const CaseRequestCustomFieldsRt = limitedArraySchema({ codec: CustomFieldRt, fieldName: 'customFields', min: 0, @@ -124,7 +124,7 @@ export const CasePostRequestRt = rt.intersection([ /** * The list of custom field values of the case. */ - customFields: CustomFieldsRt, + customFields: CaseRequestCustomFieldsRt, }) ), ]); @@ -418,7 +418,7 @@ export const CasePatchRequestRt = rt.intersection([ /** * Custom fields of the case */ - customFields: CustomFieldsRt, + customFields: CaseRequestCustomFieldsRt, }) ), /** @@ -510,6 +510,7 @@ export type GetReportersResponse = rt.TypeOf; export type CasesBulkGetRequest = rt.TypeOf; export type CasesBulkGetResponse = rt.TypeOf; export type GetRelatedCasesByAlertResponse = rt.TypeOf; -export type CaseRequestCustomFields = rt.TypeOf; +export type CaseRequestCustomFields = rt.TypeOf; +export type CaseRequestCustomField = rt.TypeOf; export type BulkCreateCasesRequest = rt.TypeOf; export type BulkCreateCasesResponse = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/types/api/custom_field/v1.test.ts b/x-pack/plugins/cases/common/types/api/custom_field/v1.test.ts index e2f54761d6670..83d9a437c998d 100644 --- a/x-pack/plugins/cases/common/types/api/custom_field/v1.test.ts +++ b/x-pack/plugins/cases/common/types/api/custom_field/v1.test.ts @@ -7,7 +7,7 @@ import { PathReporter } from 'io-ts/lib/PathReporter'; import { MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH } from '../../../constants'; -import { CaseCustomFieldTextWithValidationValueRt } from './v1'; +import { CaseCustomFieldTextWithValidationValueRt, CustomFieldPutRequestRt } from './v1'; describe('Custom Fields', () => { describe('CaseCustomFieldTextWithValidationValueRt', () => { @@ -38,4 +38,66 @@ describe('Custom Fields', () => { ); }); }); + + describe('CustomFieldPutRequestRt', () => { + const defaultRequest = { + caseVersion: 'WzQ3LDFd', + value: 'this is a text field value', + }; + + it('has expected attributes in request', () => { + const query = CustomFieldPutRequestRt.decode(defaultRequest); + + expect(query).toStrictEqual({ + _tag: 'Right', + right: defaultRequest, + }); + }); + + it('has expected attributes of toggle field in request', () => { + const newRequest = { + caseVersion: 'WzQ3LDFd', + value: false, + }; + const query = CustomFieldPutRequestRt.decode(newRequest); + + expect(query).toStrictEqual({ + _tag: 'Right', + right: newRequest, + }); + }); + + it('removes foo:bar attributes from request', () => { + const query = CustomFieldPutRequestRt.decode({ ...defaultRequest, foo: 'bar' }); + + expect(query).toStrictEqual({ + _tag: 'Right', + right: defaultRequest, + }); + }); + + it(`throws an error when a text customField is longer than ${MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH}`, () => { + expect( + PathReporter.report( + CustomFieldPutRequestRt.decode({ + caseVersion: 'WzQ3LDFd', + value: '#'.repeat(MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH + 1), + }) + ) + ).toContain( + `The length of the value is too long. The maximum length is ${MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH}.` + ); + }); + + it('throws an error when a text customField is empty', () => { + expect( + PathReporter.report( + CustomFieldPutRequestRt.decode({ + caseVersion: 'WzQ3LDFd', + value: '', + }) + ) + ).toContain('The value field cannot be an empty string.'); + }); + }); }); diff --git a/x-pack/plugins/cases/common/types/api/custom_field/v1.ts b/x-pack/plugins/cases/common/types/api/custom_field/v1.ts index 4ee70642c86b1..fb59f187991b3 100644 --- a/x-pack/plugins/cases/common/types/api/custom_field/v1.ts +++ b/x-pack/plugins/cases/common/types/api/custom_field/v1.ts @@ -5,6 +5,7 @@ * 2.0. */ +import * as rt from 'io-ts'; import { MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH } from '../../../constants'; import { limitedStringSchema } from '../../../schema'; @@ -14,3 +15,14 @@ export const CaseCustomFieldTextWithValidationValueRt = (fieldName: string) => min: 1, max: MAX_CUSTOM_FIELD_TEXT_VALUE_LENGTH, }); + +/** + * Update custom_field + */ + +export const CustomFieldPutRequestRt = rt.strict({ + value: rt.union([rt.boolean, rt.null, CaseCustomFieldTextWithValidationValueRt('value')]), + caseVersion: rt.string, +}); + +export type CustomFieldPutRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/server/client/cases/client.ts b/x-pack/plugins/cases/server/client/cases/client.ts index 2c19df9b4c0f1..4819ca3fc1672 100644 --- a/x-pack/plugins/cases/server/client/cases/client.ts +++ b/x-pack/plugins/cases/server/client/cases/client.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Case, Cases, User } from '../../../common/types/domain'; +import type { Case, CaseCustomField, Cases, User } from '../../../common/types/domain'; import type { CasePostRequest, CasesFindResponse, @@ -34,6 +34,8 @@ import type { PushParams } from './push'; import { push } from './push'; import { update } from './update'; import { bulkCreate } from './bulk_create'; +import type { ReplaceCustomFieldArgs } from './replace_custom_field'; +import { replaceCustomField } from './replace_custom_field'; /** * API for interacting with the cases entities. @@ -96,6 +98,10 @@ export interface CasesSubClient { * Retrieves the cases ID and title that have the requested alert attached to them */ getCasesByAlertID(params: CasesByAlertIDParams): Promise; + /** + * Replace custom field with specific customFieldId and CaseId + */ + replaceCustomField(params: ReplaceCustomFieldArgs): Promise; } /** @@ -122,6 +128,8 @@ export const createCasesSubClient = ( getCategories: (params: AllCategoriesFindRequest) => getCategories(params, clientArgs), getReporters: (params: AllReportersFindRequest) => getReporters(params, clientArgs), getCasesByAlertID: (params: CasesByAlertIDParams) => getCasesByAlertID(params, clientArgs), + replaceCustomField: (params: ReplaceCustomFieldArgs) => + replaceCustomField(params, clientArgs, casesClient), }; return Object.freeze(casesSubClient); diff --git a/x-pack/plugins/cases/server/client/cases/replace_custom_field.test.ts b/x-pack/plugins/cases/server/client/cases/replace_custom_field.test.ts new file mode 100644 index 0000000000000..f4c3666db7083 --- /dev/null +++ b/x-pack/plugins/cases/server/client/cases/replace_custom_field.test.ts @@ -0,0 +1,394 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CustomFieldTypes } from '../../../common/types/domain'; +import { MAX_USER_ACTIONS_PER_CASE } from '../../../common/constants'; +import { mockCases } from '../../mocks'; +import { createCasesClientMock, createCasesClientMockArgs } from '../mocks'; +import { replaceCustomField } from './replace_custom_field'; + +describe('Replace custom field', () => { + const customFields = [ + { + key: 'first_key', + type: CustomFieldTypes.TEXT as const, + value: 'this is a text field value', + }, + { + key: 'second_key', + type: CustomFieldTypes.TOGGLE as const, + value: null, + }, + ]; + + const theCase = { ...mockCases[0], attributes: { ...mockCases[0].attributes, customFields } }; + const clientArgs = createCasesClientMockArgs(); + const casesClient = createCasesClientMock(); + + beforeEach(() => { + jest.clearAllMocks(); + clientArgs.services.caseService.getCase.mockResolvedValue(theCase); + clientArgs.services.userActionService.getMultipleCasesUserActionsTotal.mockResolvedValue({ + [mockCases[0].id]: 1, + }); + + casesClient.configure.get = jest.fn().mockResolvedValue([ + { + owner: mockCases[0].attributes.owner, + customFields: [ + { + key: 'first_key', + type: CustomFieldTypes.TEXT, + label: 'missing field 1', + required: true, + }, + { + key: 'second_key', + type: CustomFieldTypes.TOGGLE, + label: 'foo', + required: false, + }, + ], + }, + ]); + }); + + it('can replace text customField', async () => { + clientArgs.services.caseService.patchCase.mockResolvedValue({ + ...theCase, + }); + + await expect( + replaceCustomField( + { + caseId: theCase.id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: 'Updated text field value', + }, + }, + clientArgs, + casesClient + ) + ).resolves.not.toThrow(); + + expect(clientArgs.services.caseService.patchCase).toHaveBeenCalledWith( + expect.objectContaining({ + caseId: theCase.id, + version: theCase.version, + originalCase: { + ...theCase, + }, + updatedAttributes: { + customFields: [ + { + key: 'first_key', + type: CustomFieldTypes.TEXT as const, + value: 'Updated text field value', + }, + { + key: 'second_key', + type: CustomFieldTypes.TOGGLE as const, + value: null, + }, + ], + updated_at: expect.any(String), + updated_by: expect.any(Object), + }, + refresh: false, + }) + ); + }); + + it('can replace toggle customField', async () => { + clientArgs.services.caseService.patchCase.mockResolvedValue({ + ...theCase, + }); + + await expect( + replaceCustomField( + { + caseId: theCase.id, + customFieldId: 'second_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: true, + }, + }, + clientArgs, + casesClient + ) + ).resolves.not.toThrow(); + + expect(clientArgs.services.caseService.patchCase).toHaveBeenCalledWith( + expect.objectContaining({ + caseId: theCase.id, + version: theCase.version, + originalCase: { + ...theCase, + }, + updatedAttributes: { + customFields: [ + { + key: 'second_key', + type: CustomFieldTypes.TOGGLE as const, + value: true, + }, + { + key: 'first_key', + type: CustomFieldTypes.TEXT as const, + value: 'this is a text field value', + }, + ], + updated_at: expect.any(String), + updated_by: expect.any(Object), + }, + refresh: false, + }) + ); + }); + + it('does not throw error when customField value is null and the custom field is not required', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'second_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: null, + }, + }, + clientArgs, + casesClient + ) + ).resolves.not.toThrow(); + }); + + it('throws error when request is invalid', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + // @ts-expect-error check for invalid attribute + foo: 'bar', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: first_key of case: mock-id-1 version:WzAsMV0= : Error: Invalid value \\"undefined\\" supplied to \\"value\\""` + ); + }); + + it('throws error when case version does not match', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: 'random-version', + value: 'test', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: first_key of case: mock-id-1 version:random-version : Error: This case mock-id-1 has been updated. Please refresh before saving additional updates."` + ); + }); + + it('throws error when customField value is null and the custom field is required', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: null, + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: first_key of case: mock-id-1 version:WzAsMV0= : Error: Custom field value cannot be null or undefined."` + ); + }); + + it('throws error when required customField of type text has value as empty string', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: ' ', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: first_key of case: mock-id-1 version:WzAsMV0= : Error: Invalid value \\" \\" supplied to \\"value\\",The value field cannot be an empty string."` + ); + }); + + it('throws error when customField value is undefined and the custom field is required', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + // @ts-expect-error: undefined value + value: undefined, + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: first_key of case: mock-id-1 version:WzAsMV0= : Error: Invalid value \\"undefined\\" supplied to \\"value\\""` + ); + }); + + it('throws error when customField key is not present in configuration', async () => { + clientArgs.services.caseService.getCase.mockResolvedValue(mockCases[0]); + + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'missing_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: 'updated', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: missing_key of case: mock-id-1 version:WzAsMV0= : Error: cannot find custom field"` + ); + }); + + it('throws error when the customField type does not match the configuration', async () => { + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'second_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: 'foobar', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: second_key of case: mock-id-1 version:WzAsMV0= : Error: Invalid value \\"foobar\\" supplied to \\"value\\""` + ); + }); + + it('throws error when the customField not found after update', async () => { + clientArgs.services.caseService.patchCase.mockResolvedValue({ + ...theCase, + attributes: { + ...theCase.attributes, + customFields: [], + }, + }); + + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'second_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: false, + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failed to replace customField, id: second_key of case: mock-id-1 version:WzAsMV0= : Error: Cannot find updated custom field."` + ); + }); + + describe('Validate max user actions', () => { + it('passes validation if max user actions per case is not reached', async () => { + clientArgs.services.userActionService.getMultipleCasesUserActionsTotal.mockResolvedValue({ + [mockCases[0].id]: MAX_USER_ACTIONS_PER_CASE - 1, + }); + + // @ts-ignore: only the array length matters here + clientArgs.services.userActionService.creator.buildUserActions.mockReturnValue({ + [mockCases[0].id]: [1], + }); + + clientArgs.services.caseService.patchCase.mockResolvedValue(theCase); + + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: 'foobar', + }, + }, + clientArgs, + casesClient + ) + ).resolves.not.toThrow(); + }); + + it(`throws an error when the user actions to be created will reach ${MAX_USER_ACTIONS_PER_CASE}`, async () => { + clientArgs.services.userActionService.getMultipleCasesUserActionsTotal.mockResolvedValue({ + [mockCases[0].id]: MAX_USER_ACTIONS_PER_CASE, + }); + + // @ts-ignore: only the array length matters here + clientArgs.services.userActionService.creator.buildUserActions.mockReturnValue({ + [mockCases[0].id]: [1, 2, 3], + }); + + await expect( + replaceCustomField( + { + caseId: mockCases[0].id, + customFieldId: 'first_key', + request: { + caseVersion: mockCases[0].version ?? '', + value: 'foobar', + }, + }, + clientArgs, + casesClient + ) + ).rejects.toThrow( + `Failed to replace customField, id: first_key of case: mock-id-1 version:WzAsMV0= : Error: The case with id mock-id-1 has reached the limit of ${MAX_USER_ACTIONS_PER_CASE} user actions.` + ); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/cases/replace_custom_field.ts b/x-pack/plugins/cases/server/client/cases/replace_custom_field.ts new file mode 100644 index 0000000000000..5a87c2acc1bf9 --- /dev/null +++ b/x-pack/plugins/cases/server/client/cases/replace_custom_field.ts @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Boom from '@hapi/boom'; + +import type { CasesClient, CasesClientArgs } from '..'; + +import type { CustomFieldPutRequest } from '../../../common/types/api'; +import { CustomFieldPutRequestRt, CaseRequestCustomFieldsRt } from '../../../common/types/api'; +import { Operations } from '../../authorization'; +import { createCaseError } from '../../common/error'; +import { validateMaxUserActions } from '../../../common/utils/validators'; +import { decodeOrThrow } from '../../../common/api/runtime_types'; +import type { CaseCustomField } from '../../../common/types/domain'; +import { CaseCustomFieldRt } from '../../../common/types/domain'; +import { decodeWithExcessOrThrow } from '../../../common/api'; +import { validateCustomFieldTypesInRequest } from './validators'; +import type { UserActionEvent } from '../../services/user_actions/types'; + +export interface ReplaceCustomFieldArgs { + /** + * The ID of a case + */ + caseId: string; + /** + * The ID of a custom field to be updated + */ + customFieldId: string; + /** + * value of custom field to update, case version + */ + request: CustomFieldPutRequest; +} + +/** + * Updates the specified cases with new values + * + * @ignore + */ +export const replaceCustomField = async ( + { caseId, customFieldId, request }: ReplaceCustomFieldArgs, + clientArgs: CasesClientArgs, + casesClient: CasesClient +): Promise => { + const { + services: { caseService, userActionService }, + user, + logger, + authorization, + } = clientArgs; + + try { + const { value, caseVersion } = request; + + decodeWithExcessOrThrow(CustomFieldPutRequestRt)(request); + + const caseToUpdate = await caseService.getCase({ + id: caseId, + }); + + if (caseToUpdate.version !== caseVersion) { + throw Boom.conflict( + `This case ${caseToUpdate.id} has been updated. Please refresh before saving additional updates.` + ); + } + + const configurations = await casesClient.configure.get({ + owner: caseToUpdate.attributes.owner, + }); + + await authorization.ensureAuthorized({ + entities: [{ owner: caseToUpdate.attributes.owner, id: caseToUpdate.id }], + operation: Operations.updateCase, + }); + + const foundCustomField = configurations[0]?.customFields.find( + (item) => item.key === customFieldId + ); + + if (!foundCustomField) { + throw Boom.badRequest('cannot find custom field'); + } + + validateCustomFieldTypesInRequest({ + requestCustomFields: [ + { + value, + type: foundCustomField.type, + key: customFieldId, + } as CaseCustomField, + ], + customFieldsConfiguration: configurations[0].customFields, + }); + + if (value == null && foundCustomField.required) { + throw Boom.badRequest('Custom field value cannot be null or undefined.'); + } + + const customFieldsToUpdate = [ + { + value, + type: foundCustomField.type, + key: customFieldId, + }, + ...caseToUpdate.attributes.customFields.filter((field) => field.key !== customFieldId), + ]; + + const decodedCustomFields = + decodeWithExcessOrThrow(CaseRequestCustomFieldsRt)(customFieldsToUpdate); + + const updatedAt = new Date().toISOString(); + + const patchCasesPayload = { + caseId, + originalCase: caseToUpdate, + updatedAttributes: { + customFields: decodedCustomFields, + updated_at: updatedAt, + updated_by: user, + }, + version: caseVersion, + }; + + const userActionsDict = userActionService.creator.buildUserActions({ + updatedCases: { + cases: [patchCasesPayload], + }, + user, + }); + + await validateMaxUserActions({ caseId, userActionService, userActionsToAdd: 1 }); + + const updatedCase = await caseService.patchCase({ + ...patchCasesPayload, + refresh: false, + }); + + const updatedCustomField = updatedCase.attributes.customFields?.find( + (cf) => cf.key === customFieldId + ); + + if (!updatedCustomField) { + throw new Error('Cannot find updated custom field.'); + } + + const builtUserActions = + userActionsDict != null + ? Object.keys(userActionsDict).reduce((acc, key) => { + return [...acc, ...userActionsDict[key]]; + }, []) + : []; + + await userActionService.creator.bulkCreateUpdateCase({ + builtUserActions, + }); + + return decodeOrThrow(CaseCustomFieldRt)(updatedCustomField); + } catch (error) { + throw createCaseError({ + message: `Failed to replace customField, id: ${customFieldId} of case: ${caseId} version:${request.caseVersion} : ${error}`, + error, + logger, + }); + } +}; diff --git a/x-pack/plugins/cases/server/client/mocks.ts b/x-pack/plugins/cases/server/client/mocks.ts index f9d02c094e425..c558fc258d3a2 100644 --- a/x-pack/plugins/cases/server/client/mocks.ts +++ b/x-pack/plugins/cases/server/client/mocks.ts @@ -59,6 +59,7 @@ const createCasesSubClientMock = (): CasesSubClientMock => { getReporters: jest.fn(), getCasesByAlertID: jest.fn(), getCategories: jest.fn(), + replaceCustomField: jest.fn(), }; }; diff --git a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts index e6c5793064545..79e5189c02f57 100644 --- a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts +++ b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts @@ -19,6 +19,7 @@ import { getCategoriesRoute } from './cases/categories/get_categories'; import { getCaseMetricRoute } from './internal/get_case_metrics'; import { getCasesMetricRoute } from './internal/get_cases_metrics'; import { searchCasesRoute } from './internal/search_cases'; +import { replaceCustomFieldRoute } from './internal/replace_custom_field'; export const getInternalRoutes = (userProfileService: UserProfileService) => [ @@ -34,4 +35,5 @@ export const getInternalRoutes = (userProfileService: UserProfileService) => getCaseMetricRoute, getCasesMetricRoute, searchCasesRoute, + replaceCustomFieldRoute, ] as CaseRoute[]; diff --git a/x-pack/plugins/cases/server/routes/api/internal/replace_custom_field.ts b/x-pack/plugins/cases/server/routes/api/internal/replace_custom_field.ts new file mode 100644 index 0000000000000..c243c10064c24 --- /dev/null +++ b/x-pack/plugins/cases/server/routes/api/internal/replace_custom_field.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 { schema } from '@kbn/config-schema'; +import { INTERNAL_PUT_CUSTOM_FIELDS_URL } from '../../../../common/constants'; +import { createCaseError } from '../../../common/error'; +import { createCasesRoute } from '../create_cases_route'; +import type { customFieldsApiV1 } from '../../../../common/types/api'; +import type { customFieldDomainV1 } from '../../../../common/types/domain'; + +export const replaceCustomFieldRoute = createCasesRoute({ + method: 'put', + path: INTERNAL_PUT_CUSTOM_FIELDS_URL, + params: { + params: schema.object({ + case_id: schema.string(), + custom_field_id: schema.string(), + }), + }, + handler: async ({ context, request, response }) => { + try { + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); + const caseId = request.params.case_id; + const customFieldId = request.params.custom_field_id; + const details = request.body as customFieldsApiV1.CustomFieldPutRequest; + + const res: customFieldDomainV1.CaseCustomField = await casesClient.cases.replaceCustomField({ + caseId, + customFieldId, + request: details, + }); + + return response.ok({ + body: res, + }); + } catch (error) { + throw createCaseError({ + message: `Failed to replace customField in route: ${error}`, + error, + }); + } + }, +}); diff --git a/x-pack/test/cases_api_integration/common/lib/api/index.ts b/x-pack/test/cases_api_integration/common/lib/api/index.ts index 4d7d64bbc4487..0b7f9c542a6d0 100644 --- a/x-pack/test/cases_api_integration/common/lib/api/index.ts +++ b/x-pack/test/cases_api_integration/common/lib/api/index.ts @@ -37,6 +37,7 @@ import { Case, Cases, CaseStatuses, + CaseCustomField, } from '@kbn/cases-plugin/common/types/domain'; import { AlertResponse, @@ -45,6 +46,7 @@ import { CasesFindResponse, CasesPatchRequest, CasesStatusResponse, + CustomFieldPutRequest, GetRelatedCasesByAlertResponse, } from '@kbn/cases-plugin/common/types/api'; import { User } from '../authentication/types'; @@ -808,3 +810,38 @@ export const searchCases = async ({ return res; }; + +export const replaceCustomField = async ({ + supertest, + caseId, + customFieldId, + params, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, + headers = {}, +}: { + supertest: SuperTest.SuperTest; + caseId: string; + customFieldId: string; + params: CustomFieldPutRequest; + expectedHttpCode?: number; + auth?: { user: User; space: string | null } | null; + headers?: Record; +}): Promise => { + const apiCall = supertest.put( + `${getSpaceUrlPrefix( + auth?.space + )}${CASES_INTERNAL_URL}/${caseId}/custom_fields/${customFieldId}` + ); + + setupAuth({ apiCall, headers, auth }); + + const { body: theCustomField } = await apiCall + .set('kbn-xsrf', 'true') + .set('x-elastic-internal-origin', 'foo') + .set(headers) + .send(params) + .expect(expectedHttpCode); + + return theCustomField; +}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts index 636c166169808..e731e0101bdc0 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts @@ -56,6 +56,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./internal/user_actions_get_users')); loadTestFile(require.resolve('./internal/bulk_delete_file_attachments')); loadTestFile(require.resolve('./internal/search_cases')); + loadTestFile(require.resolve('./internal/replace_custom_field')); /** * Attachments framework diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/replace_custom_field.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/replace_custom_field.ts new file mode 100644 index 0000000000000..b76079f81c62f --- /dev/null +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/replace_custom_field.ts @@ -0,0 +1,464 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { CustomFieldTypes } from '@kbn/cases-plugin/common/types/domain'; + +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { postCaseReq, getPostCaseRequest } from '../../../../common/lib/mock'; +import { + deleteAllCaseItems, + createCase, + createConfiguration, + getConfigurationRequest, + replaceCustomField, +} from '../../../../common/lib/api'; +import { + globalRead, + noKibanaPrivileges, + obsOnly, + obsOnlyRead, + obsSecRead, + secOnly, + secOnlyRead, + superUser, +} from '../../../../common/lib/authentication/users'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('replace_custom_field', () => { + afterEach(async () => { + await deleteAllCaseItems(es); + }); + + describe('basic tests', () => { + it('should replace a text customField', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field_1', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + { + key: 'test_custom_field_2', + label: 'toggle', + type: CustomFieldTypes.TOGGLE, + required: true, + }, + ], + }, + }) + ); + + const postedCase = await createCase(supertest, { + ...postCaseReq, + customFields: [ + { + key: 'test_custom_field_1', + type: CustomFieldTypes.TEXT, + value: 'text field value', + }, + { + key: 'test_custom_field_2', + type: CustomFieldTypes.TOGGLE, + value: true, + }, + ], + }); + const replacedCustomField = await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'test_custom_field_1', + params: { + value: 'this is updated text field value', + caseVersion: postedCase.version, + }, + }); + + expect(replacedCustomField).to.eql({ + key: 'test_custom_field_1', + type: CustomFieldTypes.TEXT, + value: 'this is updated text field value', + }); + }); + + it('should patch a toggle customField', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field_1', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + { + key: 'test_custom_field_2', + label: 'toggle', + type: CustomFieldTypes.TOGGLE, + required: true, + }, + ], + }, + }) + ); + + const postedCase = await createCase(supertest, { + ...postCaseReq, + customFields: [ + { + key: 'test_custom_field_1', + type: CustomFieldTypes.TEXT, + value: 'text field value', + }, + { + key: 'test_custom_field_2', + type: CustomFieldTypes.TOGGLE, + value: true, + }, + ], + }); + const replacedCustomField = await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'test_custom_field_2', + params: { + value: false, + caseVersion: postedCase.version, + }, + }); + + expect(replacedCustomField).to.eql({ + key: 'test_custom_field_2', + type: CustomFieldTypes.TOGGLE, + value: false, + }); + }); + + it('does not throw error when updating an optional custom field with a null value', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + ], + }, + }) + ); + + const postedCase = await createCase(supertest, { + ...postCaseReq, + customFields: [ + { + key: 'test_custom_field', + type: CustomFieldTypes.TEXT, + value: 'hello', + }, + ], + }); + + await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: null, + }, + expectedHttpCode: 200, + }); + }); + }); + + describe('errors', () => { + it('400s when trying to patch with a custom field key that does not exist', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + ], + }, + }) + ); + const postedCase = await createCase(supertest, postCaseReq); + + await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'random_key', + params: { + caseVersion: postedCase.version, + value: 'this is updated text field value', + }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to patch a case with a required custom field with null value', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: true, + }, + ], + }, + }) + ); + + const postedCase = await createCase(supertest, { + ...postCaseReq, + customFields: [ + { + key: 'test_custom_field', + type: CustomFieldTypes.TEXT, + value: 'hello', + }, + ], + }); + + await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: null, + }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to patch a case with a custom field with the wrong type', async () => { + await createConfiguration( + supertest, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + ], + }, + }) + ); + const postedCase = await createCase(supertest, postCaseReq); + + await replaceCustomField({ + supertest, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: true, + }, + expectedHttpCode: 400, + }); + }); + }); + + describe('rbac', () => { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + it('should replace the custom field when the user has the correct permissions', async () => { + await createConfiguration( + supertestWithoutAuth, + getConfigurationRequest({ + overrides: { + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + ], + }, + }), + 200, + { + user: secOnly, + space: 'space1', + } + ); + + const postedCase = await createCase(supertestWithoutAuth, postCaseReq, 200, { + user: secOnly, + space: 'space1', + }); + + await replaceCustomField({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + + value: 'this is updated text field value', + }, + auth: { user: secOnly, space: 'space1' }, + expectedHttpCode: 200, + }); + }); + + it('should not replace a custom field when the user does not have the correct ownership', async () => { + await createConfiguration( + supertestWithoutAuth, + getConfigurationRequest({ + overrides: { + owner: 'observabilityFixture', + customFields: [ + { + key: 'test_custom_field', + label: 'text', + type: CustomFieldTypes.TEXT, + required: false, + }, + ], + }, + }), + 200, + { + user: obsOnly, + space: 'space1', + } + ); + + const postedCase = await createCase( + supertestWithoutAuth, + getPostCaseRequest({ + owner: 'observabilityFixture', + customFields: [ + { + key: 'test_custom_field', + type: CustomFieldTypes.TEXT, + value: 'hello', + }, + ], + }), + 200, + { user: obsOnly, space: 'space1' } + ); + + await replaceCustomField({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: 'this is updated text field value', + }, + auth: { user: secOnly, space: 'space1' }, + expectedHttpCode: 403, + }); + }); + + for (const user of [globalRead, secOnlyRead, obsOnlyRead, obsSecRead, noKibanaPrivileges]) { + it(`User ${ + user.username + } with role(s) ${user.roles.join()} - should NOT replace a custom field`, async () => { + await createConfiguration( + supertestWithoutAuth, + { ...getConfigurationRequest(), owner: 'observabilityFixture' }, + 200, + { + user: superUser, + space: 'space1', + } + ); + + const postedCase = await createCase( + supertestWithoutAuth, + getPostCaseRequest({ owner: 'securitySolutionFixture' }), + 200, + { + user: superUser, + space: 'space1', + } + ); + + await replaceCustomField({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: 'this is updated text field value', + }, + auth: { user, space: 'space1' }, + expectedHttpCode: 403, + }); + }); + } + + it('should NOT replace a custom field in a space with no permissions', async () => { + await createConfiguration( + supertestWithoutAuth, + { ...getConfigurationRequest(), owner: 'observabilityFixture' }, + 200, + { + user: superUser, + space: 'space2', + } + ); + + const postedCase = await createCase( + supertestWithoutAuth, + getPostCaseRequest({ owner: 'securitySolutionFixture' }), + 200, + { + user: superUser, + space: 'space2', + } + ); + + await replaceCustomField({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + customFieldId: 'test_custom_field', + params: { + caseVersion: postedCase.version, + value: 'this is updated text field value', + }, + auth: { user: secOnly, space: 'space2' }, + expectedHttpCode: 403, + }); + }); + }); + }); +}; From 8709754bb2901758f5a65ad2e47b8ca97c013e0e Mon Sep 17 00:00:00 2001 From: Nick Partridge Date: Thu, 8 Feb 2024 08:55:20 -0700 Subject: [PATCH 027/104] [Lens] Fix flaky serverless tests in group 3 (#176423) --- .../test_suites/common/visualizations/group2/index.ts | 3 +-- .../group2/open_in_lens/agg_based/goal.ts | 11 ++++++++++- .../group2/open_in_lens/agg_based/metric.ts | 11 ++++++++++- .../group2/open_in_lens/agg_based/table.ts | 11 +++++++---- .../visualizations/group3/open_in_lens/tsvb/table.ts | 8 ++++---- .../visualizations/group3/open_in_lens/tsvb/top_n.ts | 7 ++++--- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts index 4b7e3588669d1..f3abd6dccef91 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts @@ -10,8 +10,7 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default ({ loadTestFile, getPageObject }: FtrProviderContext) => { const svlCommonPage = getPageObject('svlCommonPage'); - // FLAKY: https://github.com/elastic/kibana/issues/168985 - describe.skip('Visualizations - Group 2', function () { + describe('Visualizations - Group 2', function () { before(async () => { await svlCommonPage.login(); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts index 01f655af00a1f..b67cbe95e1ba6 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts @@ -51,6 +51,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '140.05%', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: true, showingTrendline: false, }, @@ -78,6 +79,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '131,040,360.81%', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: true, showingTrendline: false, }, @@ -106,6 +108,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '14.37%', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: true, showingTrendline: false, }, @@ -134,6 +137,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,228,964,670.613', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, @@ -143,6 +147,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,186,695,551.251', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, @@ -152,6 +157,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,073,190,186.423', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, @@ -161,6 +167,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,031,579,645.108', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, @@ -170,6 +177,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,009,497,206.823', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, @@ -178,7 +186,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { subtitle: undefined, extraText: undefined, value: undefined, - color: 'rgba(0, 0, 0, 0)', + color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingTrendline: false, showingBar: true, }, diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts index 9bd990484cc81..c608c454e3039 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts @@ -47,6 +47,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '14,005', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -73,6 +74,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,104,036,080.615', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -100,6 +102,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '1,437', color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -131,6 +134,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,228,964,670.613', color: 'rgba(165, 0, 38, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -140,6 +144,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,186,695,551.251', color: 'rgba(253, 191, 111, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -149,6 +154,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,073,190,186.423', color: 'rgba(183, 224, 117, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -158,6 +164,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,031,579,645.108', color: 'rgba(183, 224, 117, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -167,6 +174,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { extraText: '', value: '13,009,497,206.823', color: 'rgba(183, 224, 117, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, @@ -175,7 +183,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { subtitle: undefined, extraText: undefined, value: undefined, - color: 'rgba(0, 0, 0, 0)', + color: 'rgba(255, 255, 255, 1)', + trendlineColor: undefined, showingBar: false, showingTrendline: false, }, diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts index 5b5d31a842607..4761bd22d9429 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts @@ -14,6 +14,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const panelActions = getService('dashboardPanelActions'); const kibanaServer = getService('kibanaServer'); + const comboBox = getService('comboBox'); describe('Table', function describeIndexTests() { const fixture = @@ -67,8 +68,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(await dimensions[0].getVisibleText()).to.be('Average machine.ram'); await lens.openDimensionEditor('lnsDatatable_metrics > lns-dimensionTrigger'); - const summaryRowFunction = await testSubjects.find('lnsDatatable_summaryrow_function'); - expect(await summaryRowFunction.getVisibleText()).to.be('Sum'); + expect(await comboBox.getComboBoxSelectedOptions('lnsDatatable_summaryrow_function')).to.eql([ + 'Sum', + ]); }); it('should convert sibling pipeline aggregation', async () => { @@ -132,8 +134,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const percentageColumnText = await lens.getDimensionTriggerText('lnsDatatable_metrics', 1); await lens.openDimensionEditor('lnsDatatable_metrics > lns-dimensionTrigger', 0, 1); - const format = await testSubjects.find('indexPattern-dimension-format'); - expect(await format.getVisibleText()).to.be('Percent'); + expect(await comboBox.getComboBoxSelectedOptions('indexPattern-dimension-format')).to.eql([ + 'Percent', + ]); const dimensions = await testSubjects.findAll('lns-dimensionTrigger'); expect(dimensions).to.have.length(2); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/table.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/table.ts index 864e205e3ff5f..e5b4174435e05 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/table.ts @@ -22,7 +22,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const retry = getService('retry'); const panelActions = getService('dashboardPanelActions'); const kibanaServer = getService('kibanaServer'); - const comboBox = getService('comboBox'); describe('Table', function describeIndexTests() { const fixture = @@ -84,9 +83,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await lens.openDimensionEditor('lnsDatatable_metrics > lns-dimensionTrigger'); await testSubjects.click('indexPattern-advanced-accordion'); - expect( - await comboBox.getComboBoxSelectedOptions('indexPattern-dimension-reducedTimeRange') - ).to.eql(['1 minute (1m)']); + const reducedTimeRange = await testSubjects.find( + 'indexPattern-dimension-reducedTimeRange > comboBoxSearchInput' + ); + expect(await reducedTimeRange.getAttribute('value')).to.be('1 minute (1m)'); await retry.try(async () => { const layerCount = await lens.getLayerCount(); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/top_n.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/top_n.ts index 4085e7faad08c..e9872a6b776d3 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/top_n.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/top_n.ts @@ -17,7 +17,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const queryBar = getService('queryBar'); const panelActions = getService('dashboardPanelActions'); const kibanaServer = getService('kibanaServer'); - const comboBox = getService('comboBox'); describe('Top N', function describeIndexTests() { const fixture = @@ -102,8 +101,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await lens.openDimensionEditor('lnsXY_yDimensionPanel > lns-dimensionTrigger'); await testSubjects.click('indexPattern-advanced-accordion'); - const reducedTimeRange = await testSubjects.find('indexPattern-dimension-reducedTimeRange'); - await comboBox.isOptionSelected(reducedTimeRange, '1 minute (1m)'); + const reducedTimeRange = await testSubjects.find( + 'indexPattern-dimension-reducedTimeRange > comboBoxSearchInput' + ); + expect(await reducedTimeRange.getAttribute('value')).to.be('1 minute (1m)'); await retry.try(async () => { const layerCount = await lens.getLayerCount(); expect(layerCount).to.be(1); From 3e4f1ed99dcaadd6539f198ddf4623a8e2a723bb Mon Sep 17 00:00:00 2001 From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:02:54 +0000 Subject: [PATCH 028/104] [ILM] Fix data allocation field (#176292) Fixes https://github.com/elastic/kibana/issues/173764 ## Summary This PR fixes the "Custom" data allocation field in the edit IL policy form by adding a default value for the field. Before, there was no default value, so no value would be added to the request until the user changes the initial selection to another option. This explains the bug described from https://github.com/elastic/kibana/issues/173764 (in v7.17) where there is only one option and the user is not able to change it to something else so the value of the only option cannot be added to the request. Now with these changes, if the user doesn't make any changes to the initially selected option, the default value would be added to the request. **How to test:** 1. Start Es with `yarn es snapshot` and Kibana with `yarn start`. 2. Go to Stack Management -> Index Lifecycle Policies and start creating a new policy. 3. Type in some name for the policy. Enable the Warm (or Cold) phase and type in some number in the "Move data into phase when" field. Click on "Advanced settings". 4. In the "Data allocation" field, select the "Custom" option. 5. Click on "Show request" and verify that the request correctly shows the `allocation` field (the "Any data node" option doesn't add anything to the request). 6. Select another option for the node attribution field and verify it is displayed in the request. Test the field on cloud by accessing the [CI cloud deployment](https://kibana-pr-176292.kb.us-west2.gcp.elastic-cloud.com:9243/) from this PR or by changing the if-condition in line 65 in `x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx` to `if (false)`. Now the "Any data node" option is not available. Follow the test instructions above and verify that the initially selected node attribute option is added to the request. --- .../data_tier_allocation_field/components/node_allocation.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx index a2bad060a5893..9de959e4d5e83 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/data_tier_allocation_field/components/node_allocation.tsx @@ -100,6 +100,9 @@ export const NodeAllocation: FunctionComponent = ({ Date: Thu, 8 Feb 2024 16:13:34 +0000 Subject: [PATCH 029/104] Update dependency @elastic/charts to v63 (main) (#175316) ## Note about `@elastic/charts` BREAKING CHANGE In version 62.0.0 we introduced a breaking change in time-series charts: the default "extra" legend value now represents the last data point in the passed data array. It doesn't try to reconcile anymore the data computed domain with a passed domain in `Settings.xDomain` but instead it renders directly the last element of the passed array. The reasons for this change can be found at https://github.com/elastic/elastic-charts/pull/2115 or can be asked directly to our `#charts` slack channel There are a couple of implementations in Kibana that use both the `showLegendExtra` in the chart configuration. I've commented them out so that the owner teams can help me fix this breaking change if necessary. In general, the fix requires that the data passed to the chart contains all the buckets, even empty buckets with null/zeros should be passed. To achieve this, your ES query you should provide the `extended_bounds` settings in the [data histogram agg](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html#search-aggregations-bucket-histogram-aggregation-extended-bounds) and use a `min_doc_count:0`. If that doesn't work, please ping me and we can find an alternative solution. This should not limit the query performance, generating empty date buckets on the server side has a similar or even less performance impact than what we were doing on the client side to calculate every missing bucket, to fillup the chart in particular situations. Please double-check your queries/data fetches and push a commit to this PR or ping me with the updated data fetch strategy. fix https://github.com/elastic/kibana/issues/153079 This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@elastic/charts](https://togithub.com/elastic/elastic-charts) | [`61.2.0` -> `63.0.0`](https://renovatebot.com/diffs/npm/@elastic%2fcharts/61.2.0/63.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@elastic%2fcharts/63.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@elastic%2fcharts/63.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@elastic%2fcharts/61.2.0/63.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@elastic%2fcharts/61.2.0/63.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
elastic/elastic-charts (@​elastic/charts) ### [`v63.0.0`](https://togithub.com/elastic/elastic-charts/blob/HEAD/CHANGELOG.md#6300-2024-01-24) [Compare Source](https://togithub.com/elastic/elastic-charts/compare/v62.0.0...v63.0.0) ##### Features - **legend:** expose extra raw values ([#​2308](https://togithub.com/elastic/elastic-charts/issues/2308)) ([85bfe06](https://togithub.com/elastic/elastic-charts/commit/85bfe0668d66fd24e78f2bba8be4570fa926e94c)) ##### BREAKING CHANGES - **legend:** The `CustomLegend.item` now exposes both the `raw` and the `formatted` version of the extra value. ### [`v62.0.0`](https://togithub.com/elastic/elastic-charts/blob/HEAD/CHANGELOG.md#6200-2024-01-23) [Compare Source](https://togithub.com/elastic/elastic-charts/compare/v61.2.0...v62.0.0) ##### Bug Fixes - **deps:** update dependency [@​elastic/eui](https://togithub.com/elastic/eui) to ^91.3.1 ([#​2286](https://togithub.com/elastic/elastic-charts/issues/2286)) ([d4d7b5d](https://togithub.com/elastic/elastic-charts/commit/d4d7b5db6681ec0c65ef8b7e576f1b5fc8b5433a)) - **deps:** update dependency [@​elastic/eui](https://togithub.com/elastic/eui) to v92 ([#​2290](https://togithub.com/elastic/elastic-charts/issues/2290)) ([cc537fa](https://togithub.com/elastic/elastic-charts/commit/cc537faf43d88acc9abab7e0dac9360bd460b574)) - **legend:** improve last value handling ([#​2115](https://togithub.com/elastic/elastic-charts/issues/2115)) ([9f99447](https://togithub.com/elastic/elastic-charts/commit/9f9944734c4a13bfe9e4ffc9f4c0f39da5f9931f)) ##### BREAKING CHANGES - **legend:** In cartesian charts, the default legend value now represents the data points that coincide with the latest datum in the X domain. Please consider passing every data point, even the empty ones (like empty buckets/bins/etc) if your x data domain doesn't fully cover a custom x domain passed to the chart configuration.
--- --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Marco Vettorello Co-authored-by: Stratoula Kalafateli Co-authored-by: Elena Stoeva --- package.json | 2 +- .../overview/components/sections/logs/logs_section.tsx | 6 +++++- .../common/__snapshots__/external_alert.test.ts.snap | 4 ++++ .../alerts/__snapshots__/alerts_histogram.test.ts.snap | 8 ++++++++ .../lens_attributes/common/alerts/alerts_histogram.ts | 2 ++ .../lens_attributes/common/events.ts | 2 ++ .../lens_attributes/common/external_alert.ts | 2 ++ .../network/__snapshots__/dns_top_domains.test.ts.snap | 4 ++++ .../lens_attributes/network/dns_top_domains.ts | 2 ++ .../public/rule_types/threshold/visualization.tsx | 6 +++++- .../components/common/charts/duration_chart.tsx | 6 +++++- .../models/watch/threshold_watch/build_visualize_query.js | 6 +++++- yarn.lock | 8 ++++---- 13 files changed, 49 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index ccd5182e04a55..4676515b4f889 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "@dnd-kit/utilities": "^2.0.0", "@elastic/apm-rum": "^5.16.0", "@elastic/apm-rum-react": "^2.0.2", - "@elastic/charts": "61.2.0", + "@elastic/charts": "63.0.0", "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.9.1-canary.1", "@elastic/ems-client": "8.5.1", diff --git a/x-pack/plugins/observability/public/pages/overview/components/sections/logs/logs_section.tsx b/x-pack/plugins/observability/public/pages/overview/components/sections/logs/logs_section.tsx index 63087aad6dd30..2651cef2191d0 100644 --- a/x-pack/plugins/observability/public/pages/overview/components/sections/logs/logs_section.tsx +++ b/x-pack/plugins/observability/public/pages/overview/components/sections/logs/logs_section.tsx @@ -142,7 +142,11 @@ export function LogsSection({ bucketSize }: Props) { showLegend legendPosition={Position.Right} xDomain={{ min, max }} - showLegendExtra + // Please double check if the data passed to the chart contains all the buckets, even the empty ones. + // the showLegendExtra will display the last element of the data array as the default legend value + // and if empty buckets are filtered out you can probably see a value that doesn't correspond + // to the value in the last time bucket visualized. + // showLegendExtra locale={i18n.getLocale()} /> {series && diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap index e8bdc77c7c460..4e26d269ed8ad 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap @@ -41,6 +41,9 @@ Object { "isBucketed": false, "label": "Count of records", "operationType": "count", + "params": Object { + "emptyAsNull": true, + }, "scale": "ratio", "sourceField": "___records___", }, @@ -50,6 +53,7 @@ Object { "label": "@timestamp", "operationType": "date_histogram", "params": Object { + "includeEmptyRows": true, "interval": "auto", }, "scale": "interval", diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/alerts_histogram.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/alerts_histogram.test.ts.snap index a48df2b2787e6..5e666cc63c3e9 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/alerts_histogram.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/alerts_histogram.test.ts.snap @@ -50,6 +50,7 @@ Object { "label": "@timestamp", "operationType": "date_histogram", "params": Object { + "includeEmptyRows": true, "interval": "auto", }, "scale": "interval", @@ -60,6 +61,9 @@ Object { "isBucketed": false, "label": "Count of records", "operationType": "count", + "params": Object { + "emptyAsNull": true, + }, "scale": "ratio", "sourceField": "___records___", }, @@ -233,6 +237,7 @@ Object { "label": "@timestamp", "operationType": "date_histogram", "params": Object { + "includeEmptyRows": true, "interval": "auto", }, "scale": "interval", @@ -243,6 +248,9 @@ Object { "isBucketed": false, "label": "Count of records", "operationType": "count", + "params": Object { + "emptyAsNull": true, + }, "scale": "ratio", "sourceField": "___records___", }, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts index 571040b33b378..5fb0630bcca80 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts @@ -70,6 +70,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( scale: 'interval', params: { interval: 'auto', + includeEmptyRows: true, }, }, 'e09e0380-0740-4105-becc-0a4ca12e3944': { @@ -79,6 +80,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( isBucketed: false, scale: 'ratio', sourceField: '___records___', + params: { emptyAsNull: true }, }, '34919782-4546-43a5-b668-06ac934d3acd': { label: `Top values of ${stackByField}`, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts index baa267b9f17b8..8e238ca11b1d7 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts @@ -71,6 +71,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( scale: 'interval', params: { interval: 'auto', + includeEmptyRows: true, }, }, 'e09e0380-0740-4105-becc-0a4ca12e3944': { @@ -80,6 +81,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( isBucketed: false, scale: 'ratio', sourceField: '___records___', + params: { emptyAsNull: true }, }, '34919782-4546-43a5-b668-06ac934d3acd': { label: `Top values of ${stackByField}`, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts index 2aa3eab25d105..3baec52d3b8fb 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts @@ -91,6 +91,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( scale: 'interval', params: { interval: 'auto', + includeEmptyRows: true, }, }, '0a923af2-c880-4aa3-aa93-a0b9c2801f6d': { @@ -100,6 +101,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( isBucketed: false, scale: 'ratio', sourceField: '___records___', + params: { emptyAsNull: true }, }, '42334c6e-98d9-47a2-b4cb-a445abb44c93': { label: TOP_VALUE(`${stackByField}`), // could be event.category diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap index 5d7a36ab09e20..19a5eb4f45b71 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap @@ -26,6 +26,9 @@ Object { "isBucketed": false, "label": "Unique count of dns.question.name", "operationType": "unique_count", + "params": Object { + "emptyAsNull": true, + }, "scale": "ratio", "sourceField": "dns.question.name", }, @@ -35,6 +38,7 @@ Object { "label": "@timestamp", "operationType": "date_histogram", "params": Object { + "includeEmptyRows": true, "interval": "auto", }, "scale": "interval", diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts index f39ad3c2ea30d..39f5d56a3d461 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts @@ -133,6 +133,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( scale: 'interval', params: { interval: 'auto', + includeEmptyRows: true, }, }, '2a4d5e20-f570-48e4-b9ab-ff3068919377': { @@ -142,6 +143,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( scale: 'ratio', sourceField: 'dns.question.name', isBucketed: false, + params: { emptyAsNull: true }, }, }, columnOrder: [ diff --git a/x-pack/plugins/stack_alerts/public/rule_types/threshold/visualization.tsx b/x-pack/plugins/stack_alerts/public/rule_types/threshold/visualization.tsx index c8996d9fcaa4b..918c87c5d13a8 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/threshold/visualization.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/threshold/visualization.tsx @@ -269,7 +269,11 @@ export const ThresholdVisualization: React.FunctionComponent = ({ baseTheme={chartsBaseTheme} xDomain={domain} showLegend={!!termField} - showLegendExtra + // Please double check if the data passed to the chart contains all the buckets, even the empty ones. + // the showLegendExtra will display the last element of the data array as the default legend value + // and if empty buckets are filtered out you can probably see a value that doesn't correspond + // to the value in the last time bucket visualized. + // showLegendExtra legendPosition={Position.Bottom} locale={i18n.getLocale()} /> diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/duration_chart.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/duration_chart.tsx index 8e5da4fa970ab..d85654b195c6d 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/duration_chart.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/duration_chart.tsx @@ -106,7 +106,11 @@ export const DurationChartComponent = ({ Date: Thu, 8 Feb 2024 17:15:42 +0100 Subject: [PATCH 030/104] Sort printed mappings and fields in update check CLI (#176493) ## Summary Close https://github.com/elastic/kibana/issues/168927 Adds a new utility to pretty print and sort JS objects and use this in the mappings update check CLI for both fields and mappings. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../current_fields.json | 1072 ++--- .../current_mappings.json | 4166 ++++++++--------- .../src/compatibility/current_mappings.ts | 13 +- .../run_mappings_compatibility_check.ts | 4 +- .../src/mappings_additions/current_fields.ts | 3 +- .../tsconfig.json | 1 + packages/kbn-utils/index.ts | 2 +- packages/kbn-utils/src/json/index.test.ts | 85 + packages/kbn-utils/src/json/index.ts | 20 + 9 files changed, 2739 insertions(+), 2627 deletions(-) create mode 100644 packages/kbn-utils/src/json/index.test.ts create mode 100644 packages/kbn-utils/src/json/index.ts diff --git a/packages/kbn-check-mappings-update-cli/current_fields.json b/packages/kbn-check-mappings-update-cli/current_fields.json index 56308a980cc56..4d8c775710f09 100644 --- a/packages/kbn-check-mappings-update-cli/current_fields.json +++ b/packages/kbn-check-mappings-update-cli/current_fields.json @@ -1,198 +1,9 @@ { - "core-usage-stats": [], - "legacy-url-alias": [ - "disabled", - "resolveCounter", - "sourceId", - "targetId", - "targetNamespace", - "targetType" - ], - "config": [ - "buildNum" - ], - "config-global": [ - "buildNum" - ], - "url": [ - "accessDate", - "createDate", - "slug" - ], - "usage-counters": [ - "domainId" - ], - "task": [ - "attempts", - "enabled", - "ownerId", - "retryAt", - "runAt", - "schedule", - "schedule.interval", - "scheduledAt", - "scope", - "status", - "taskType" - ], - "guided-onboarding-guide-state": [ - "guideId", - "isActive" - ], - "guided-onboarding-plugin-state": [], - "ui-metric": [ - "count" - ], - "application_usage_totals": [], - "application_usage_daily": [ - "timestamp" - ], - "event_loop_delays_daily": [ - "lastUpdatedAt" - ], - "index-pattern": [ - "name", - "title", - "type" - ], - "sample-data-telemetry": [ - "installCount", - "unInstallCount" - ], - "space": [ - "name" - ], - "spaces-usage-stats": [], - "exception-list-agnostic": [ - "_tags", - "comments", - "comments.comment", - "comments.created_at", - "comments.created_by", - "comments.id", - "comments.updated_at", - "comments.updated_by", - "created_at", - "created_by", - "description", - "entries", - "entries.entries", - "entries.entries.field", - "entries.entries.operator", - "entries.entries.type", - "entries.entries.value", - "entries.field", - "entries.list", - "entries.list.id", - "entries.list.type", - "entries.operator", - "entries.type", - "entries.value", - "expire_time", - "immutable", - "item_id", - "list_id", - "list_type", - "meta", - "name", - "os_types", - "tags", - "tie_breaker_id", - "type", - "updated_by", - "version" - ], - "exception-list": [ - "_tags", - "comments", - "comments.comment", - "comments.created_at", - "comments.created_by", - "comments.id", - "comments.updated_at", - "comments.updated_by", - "created_at", - "created_by", - "description", - "entries", - "entries.entries", - "entries.entries.field", - "entries.entries.operator", - "entries.entries.type", - "entries.entries.value", - "entries.field", - "entries.list", - "entries.list.id", - "entries.list.type", - "entries.operator", - "entries.type", - "entries.value", - "expire_time", - "immutable", - "item_id", - "list_id", - "list_type", - "meta", - "name", - "os_types", - "tags", - "tie_breaker_id", - "type", - "updated_by", - "version" - ], - "telemetry": [], - "file": [ - "FileKind", - "Meta", - "Status", - "Updated", - "created", - "extension", - "hash", - "mime_type", - "name", - "size", - "user" - ], - "fileShare": [ - "created", - "name", - "token", - "valid_until" - ], "action": [ "actionTypeId", "name" ], "action_task_params": [], - "connector_token": [ - "connectorId", - "tokenType" - ], - "query": [ - "description", - "title" - ], - "kql-telemetry": [], - "search-session": [ - "created", - "realmName", - "realmType", - "sessionId", - "username" - ], - "search-telemetry": [], - "file-upload-usage-collection-telemetry": [ - "file_upload", - "file_upload.index_creation_count" - ], - "apm-indices": [], - "tag": [ - "color", - "description", - "name" - ], "alert": [ "actions", "actions.actionRef", @@ -265,34 +76,28 @@ "apiKeyId", "createdAt" ], - "rules-settings": [ - "flapping" - ], - "maintenance-window": [ - "enabled", - "events" + "apm-custom-dashboards": [ + "dashboardSavedObjectId", + "kuery", + "serviceEnvironmentFilterEnabled", + "serviceNameFilterEnabled" ], - "graph-workspace": [ - "description", - "kibanaSavedObjectMeta", - "kibanaSavedObjectMeta.searchSourceJSON", - "legacyIndexPatternRef", - "numLinks", - "numVertices", - "title", - "version", - "wsState" + "apm-indices": [], + "apm-server-schema": [ + "schemaJson" ], - "search": [ + "apm-service-group": [ + "color", "description", - "title" + "groupName", + "kuery" ], - "visualization": [ - "description", - "kibanaSavedObjectMeta", - "title", - "version" + "apm-telemetry": [], + "app_search_telemetry": [], + "application_usage_daily": [ + "timestamp" ], + "application_usage_totals": [], "canvas-element": [ "@created", "@timestamp", @@ -312,9 +117,128 @@ "tags", "template_key" ], - "event-annotation-group": [ + "cases": [ + "assignees", + "assignees.uid", + "category", + "closed_at", + "closed_by", + "closed_by.email", + "closed_by.full_name", + "closed_by.profile_uid", + "closed_by.username", + "connector", + "connector.fields", + "connector.fields.key", + "connector.fields.value", + "connector.name", + "connector.type", + "created_at", + "created_by", + "created_by.email", + "created_by.full_name", + "created_by.profile_uid", + "created_by.username", + "customFields", + "customFields.key", + "customFields.type", + "customFields.value", "description", - "title" + "duration", + "external_service", + "external_service.connector_name", + "external_service.external_id", + "external_service.external_title", + "external_service.external_url", + "external_service.pushed_at", + "external_service.pushed_by", + "external_service.pushed_by.email", + "external_service.pushed_by.full_name", + "external_service.pushed_by.profile_uid", + "external_service.pushed_by.username", + "owner", + "settings", + "settings.syncAlerts", + "severity", + "status", + "tags", + "title", + "total_alerts", + "total_comments", + "updated_at", + "updated_by", + "updated_by.email", + "updated_by.full_name", + "updated_by.profile_uid", + "updated_by.username" + ], + "cases-comments": [ + "actions", + "actions.type", + "alertId", + "comment", + "created_at", + "created_by", + "created_by.username", + "externalReferenceAttachmentTypeId", + "owner", + "persistableStateAttachmentTypeId", + "pushed_at", + "type", + "updated_at" + ], + "cases-configure": [ + "closure_type", + "created_at", + "owner" + ], + "cases-connector-mappings": [ + "owner" + ], + "cases-telemetry": [], + "cases-user-actions": [ + "action", + "created_at", + "created_by", + "created_by.username", + "owner", + "payload", + "payload.assignees", + "payload.assignees.uid", + "payload.comment", + "payload.comment.externalReferenceAttachmentTypeId", + "payload.comment.persistableStateAttachmentTypeId", + "payload.comment.type", + "payload.connector", + "payload.connector.type", + "type" + ], + "cloud-security-posture-settings": [ + "rules" + ], + "config": [ + "buildNum" + ], + "config-global": [ + "buildNum" + ], + "connector_token": [ + "connectorId", + "tokenType" + ], + "core-usage-stats": [], + "csp-rule-template": [ + "metadata", + "metadata.benchmark", + "metadata.benchmark.id", + "metadata.benchmark.name", + "metadata.benchmark.posture_type", + "metadata.benchmark.rule_number", + "metadata.benchmark.version", + "metadata.id", + "metadata.name", + "metadata.section", + "metadata.version" ], "dashboard": [ "controlGroupInput", @@ -339,139 +263,206 @@ "title", "version" ], - "links": [ - "description", - "links", - "title" + "endpoint:user-artifact-manifest": [ + "artifacts", + "schemaVersion" ], - "lens": [ + "enterprise_search_telemetry": [], + "epm-packages": [ + "es_index_patterns", + "experimental_data_stream_features", + "experimental_data_stream_features.data_stream", + "experimental_data_stream_features.features", + "experimental_data_stream_features.features.synthetic_source", + "experimental_data_stream_features.features.tsdb", + "install_format_schema_version", + "install_source", + "install_started_at", + "install_status", + "install_version", + "installed_es", + "installed_es.deferred", + "installed_es.id", + "installed_es.type", + "installed_es.version", + "installed_kibana", + "installed_kibana_space_id", + "internal", + "keep_policies_up_to_date", + "latest_install_failed_attempts", + "name", + "package_assets", + "verification_key_id", + "verification_status", + "version" + ], + "epm-packages-assets": [ + "asset_path", + "data_base64", + "data_utf8", + "install_source", + "media_type", + "package_name", + "package_version" + ], + "event-annotation-group": [ "description", - "state", - "title", - "visualizationType" + "title" ], - "lens-ui-telemetry": [ - "count", - "date", - "name", - "type" + "event_loop_delays_daily": [ + "lastUpdatedAt" ], - "map": [ - "bounds", + "exception-list": [ + "_tags", + "comments", + "comments.comment", + "comments.created_at", + "comments.created_by", + "comments.id", + "comments.updated_at", + "comments.updated_by", + "created_at", + "created_by", "description", - "layerListJSON", - "mapStateJSON", - "title", - "uiStateJSON", + "entries", + "entries.entries", + "entries.entries.field", + "entries.entries.operator", + "entries.entries.type", + "entries.entries.value", + "entries.field", + "entries.list", + "entries.list.id", + "entries.list.type", + "entries.operator", + "entries.type", + "entries.value", + "expire_time", + "immutable", + "item_id", + "list_id", + "list_type", + "meta", + "name", + "os_types", + "tags", + "tie_breaker_id", + "type", + "updated_by", "version" ], - "cases-comments": [ - "actions", - "actions.type", - "alertId", - "comment", + "exception-list-agnostic": [ + "_tags", + "comments", + "comments.comment", + "comments.created_at", + "comments.created_by", + "comments.id", + "comments.updated_at", + "comments.updated_by", "created_at", "created_by", - "created_by.username", - "externalReferenceAttachmentTypeId", - "owner", - "persistableStateAttachmentTypeId", - "pushed_at", + "description", + "entries", + "entries.entries", + "entries.entries.field", + "entries.entries.operator", + "entries.entries.type", + "entries.entries.value", + "entries.field", + "entries.list", + "entries.list.id", + "entries.list.type", + "entries.operator", + "entries.type", + "entries.value", + "expire_time", + "immutable", + "item_id", + "list_id", + "list_type", + "meta", + "name", + "os_types", + "tags", + "tie_breaker_id", "type", - "updated_at" + "updated_by", + "version" ], - "cases-configure": [ - "closure_type", - "created_at", - "owner" + "file": [ + "FileKind", + "Meta", + "Status", + "Updated", + "created", + "extension", + "hash", + "mime_type", + "name", + "size", + "user" ], - "cases-connector-mappings": [ - "owner" + "file-upload-usage-collection-telemetry": [ + "file_upload", + "file_upload.index_creation_count" ], - "cases": [ - "assignees", - "assignees.uid", - "category", - "closed_at", - "closed_by", - "closed_by.email", - "closed_by.full_name", - "closed_by.profile_uid", - "closed_by.username", - "connector", - "connector.fields", - "connector.fields.key", - "connector.fields.value", - "connector.name", - "connector.type", - "created_at", - "created_by", - "created_by.email", - "created_by.full_name", - "created_by.profile_uid", - "created_by.username", - "customFields", - "customFields.key", - "customFields.type", - "customFields.value", + "fileShare": [ + "created", + "name", + "token", + "valid_until" + ], + "fleet-fleet-server-host": [ + "host_urls", + "is_default", + "is_internal", + "is_preconfigured", + "name", + "proxy_id" + ], + "fleet-message-signing-keys": [], + "fleet-preconfiguration-deletion-record": [ + "id" + ], + "fleet-proxy": [ + "certificate", + "certificate_authorities", + "certificate_key", + "is_preconfigured", + "name", + "proxy_headers", + "url" + ], + "fleet-uninstall-tokens": [ + "policy_id", + "token_plain" + ], + "graph-workspace": [ "description", - "duration", - "external_service", - "external_service.connector_name", - "external_service.external_id", - "external_service.external_title", - "external_service.external_url", - "external_service.pushed_at", - "external_service.pushed_by", - "external_service.pushed_by.email", - "external_service.pushed_by.full_name", - "external_service.pushed_by.profile_uid", - "external_service.pushed_by.username", - "owner", - "settings", - "settings.syncAlerts", - "severity", - "status", - "tags", + "kibanaSavedObjectMeta", + "kibanaSavedObjectMeta.searchSourceJSON", + "legacyIndexPatternRef", + "numLinks", + "numVertices", "title", - "total_alerts", - "total_comments", - "updated_at", - "updated_by", - "updated_by.email", - "updated_by.full_name", - "updated_by.profile_uid", - "updated_by.username" + "version", + "wsState" ], - "cases-user-actions": [ - "action", - "created_at", - "created_by", - "created_by.username", - "owner", - "payload", - "payload.assignees", - "payload.assignees.uid", - "payload.comment", - "payload.comment.externalReferenceAttachmentTypeId", - "payload.comment.persistableStateAttachmentTypeId", - "payload.comment.type", - "payload.connector", - "payload.connector.type", + "guided-onboarding-guide-state": [ + "guideId", + "isActive" + ], + "guided-onboarding-plugin-state": [], + "index-pattern": [ + "name", + "title", "type" ], - "cases-telemetry": [], "infrastructure-monitoring-log-view": [ "name" ], - "metrics-data-source": [], - "ingest_manager_settings": [ - "fleet_server_hosts", - "has_seen_add_data_notice", - "output_secret_storage_requirements_met", - "prerelease_integrations_enabled", - "secret_storage_requirements_met" - ], + "infrastructure-ui-source": [], "ingest-agent-policies": [ "agent_features", "agent_features.enabled", @@ -499,6 +490,13 @@ "updated_at", "updated_by" ], + "ingest-download-sources": [ + "host", + "is_default", + "name", + "proxy_id", + "source_id" + ], "ingest-outputs": [ "allow_edit", "auth_type", @@ -582,92 +580,89 @@ "updated_by", "vars" ], - "epm-packages": [ - "es_index_patterns", - "experimental_data_stream_features", - "experimental_data_stream_features.data_stream", - "experimental_data_stream_features.features", - "experimental_data_stream_features.features.synthetic_source", - "experimental_data_stream_features.features.tsdb", - "install_format_schema_version", - "install_source", - "install_started_at", - "install_status", - "install_version", - "installed_es", - "installed_es.deferred", - "installed_es.id", - "installed_es.type", - "installed_es.version", - "installed_kibana", - "installed_kibana_space_id", - "internal", - "keep_policies_up_to_date", - "latest_install_failed_attempts", - "name", - "package_assets", - "verification_key_id", - "verification_status", - "version" + "ingest_manager_settings": [ + "fleet_server_hosts", + "has_seen_add_data_notice", + "output_secret_storage_requirements_met", + "prerelease_integrations_enabled", + "secret_storage_requirements_met" ], - "epm-packages-assets": [ - "asset_path", - "data_base64", - "data_utf8", - "install_source", - "media_type", - "package_name", - "package_version" + "inventory-view": [], + "kql-telemetry": [], + "legacy-url-alias": [ + "disabled", + "resolveCounter", + "sourceId", + "targetId", + "targetNamespace", + "targetType" ], - "fleet-preconfiguration-deletion-record": [ - "id" + "lens": [ + "description", + "state", + "title", + "visualizationType" ], - "ingest-download-sources": [ - "host", - "is_default", + "lens-ui-telemetry": [ + "count", + "date", "name", - "proxy_id", - "source_id" + "type" ], - "fleet-fleet-server-host": [ - "host_urls", - "is_default", - "is_internal", - "is_preconfigured", - "name", - "proxy_id" + "links": [ + "description", + "links", + "title" ], - "fleet-proxy": [ - "certificate", - "certificate_authorities", - "certificate_key", - "is_preconfigured", - "name", - "proxy_headers", - "url" + "maintenance-window": [ + "enabled", + "events" ], - "fleet-message-signing-keys": [], - "fleet-uninstall-tokens": [ - "policy_id", - "token_plain" + "map": [ + "bounds", + "description", + "layerListJSON", + "mapStateJSON", + "title", + "uiStateJSON", + "version" ], - "osquery-manager-usage-metric": [ - "count", - "errors" + "metrics-data-source": [], + "metrics-explorer-view": [], + "ml-job": [ + "datafeed_id", + "job_id", + "type" ], - "osquery-saved-query": [ - "created_at", - "created_by", + "ml-module": [ + "datafeeds", + "defaultIndexPattern", "description", - "ecs_mapping", "id", - "interval", - "platform", + "jobs", + "logo", "query", - "timeout", - "updated_at", - "updated_by", - "version" + "tags", + "title", + "type" + ], + "ml-trained-model": [ + "job", + "job.create_time", + "job.job_id", + "model_id" + ], + "monitoring-telemetry": [ + "reportedClusterUuids" + ], + "observability-onboarding-state": [ + "progress", + "state", + "type" + ], + "osquery-manager-usage-metric": [ + "count", + "errors" ], "osquery-pack": [ "created_at", @@ -702,122 +697,65 @@ "shards", "version" ], - "csp-rule-template": [ - "metadata", - "metadata.benchmark", - "metadata.benchmark.id", - "metadata.benchmark.name", - "metadata.benchmark.posture_type", - "metadata.benchmark.rule_number", - "metadata.benchmark.version", - "metadata.id", - "metadata.name", - "metadata.section", - "metadata.version" - ], - "slo": [ - "budgetingMethod", + "osquery-saved-query": [ + "created_at", + "created_by", "description", - "enabled", + "ecs_mapping", "id", - "indicator", - "indicator.params", - "indicator.type", - "name", - "tags", + "interval", + "platform", + "query", + "timeout", + "updated_at", + "updated_by", "version" ], - "threshold-explorer-view": [], - "observability-onboarding-state": [ - "progress", - "state", - "type" - ], - "ml-job": [ - "datafeed_id", - "job_id", - "type" - ], - "ml-trained-model": [ - "job", - "job.create_time", - "job.job_id", - "model_id" + "policy-settings-protection-updates-note": [ + "note" ], - "ml-module": [ - "datafeeds", - "defaultIndexPattern", + "query": [ "description", - "id", - "jobs", - "logo", - "query", - "tags", - "title", - "type" + "title" ], - "uptime-dynamic-settings": [], - "synthetics-privates-locations": [], - "synthetics-monitor": [ - "alert", - "alert.status", - "alert.status.enabled", - "alert.tls", - "alert.tls.enabled", - "custom_heartbeat_id", + "risk-engine-configuration": [ + "dataViewId", "enabled", - "hash", - "hosts", - "id", - "journey_id", - "locations", - "locations.id", - "locations.label", - "name", - "origin", - "project_id", - "schedule", - "schedule.number", - "tags", - "throttling", - "throttling.label", - "type", - "urls" - ], - "uptime-synthetics-api-key": [ - "apiKey" + "filter", + "identifierType", + "interval", + "pageSize", + "range", + "range.end", + "range.start" ], - "synthetics-param": [], - "infrastructure-ui-source": [], - "inventory-view": [], - "metrics-explorer-view": [], - "upgrade-assistant-reindex-operation": [ - "indexName", - "status" + "rules-settings": [ + "flapping" ], - "upgrade-assistant-ml-upgrade-operation": [ - "snapshotId" + "sample-data-telemetry": [ + "installCount", + "unInstallCount" ], - "monitoring-telemetry": [ - "reportedClusterUuids" + "search": [ + "description", + "title" ], - "enterprise_search_telemetry": [], - "app_search_telemetry": [], - "workplace_search_telemetry": [], - "siem-ui-timeline-note": [ + "search-session": [ "created", - "createdBy", - "eventId", - "note", - "updated", - "updatedBy" + "realmName", + "realmType", + "sessionId", + "username" ], - "siem-ui-timeline-pinned-event": [ - "created", - "createdBy", - "eventId", + "search-telemetry": [], + "security-rule": [ + "rule_id", + "version" + ], + "security-solution-signals-migration": [ + "sourceIndex", "updated", - "updatedBy" + "version" ], "siem-detection-engine-rule-actions": [ "actions", @@ -830,10 +768,6 @@ "ruleAlertId", "ruleThrottle" ], - "security-rule": [ - "rule_id", - "version" - ], "siem-ui-timeline": [ "columns", "columns.aggregatable", @@ -933,46 +867,112 @@ "updated", "updatedBy" ], - "endpoint:user-artifact-manifest": [ - "artifacts", - "schemaVersion" + "siem-ui-timeline-note": [ + "created", + "createdBy", + "eventId", + "note", + "updated", + "updatedBy" ], - "security-solution-signals-migration": [ - "sourceIndex", + "siem-ui-timeline-pinned-event": [ + "created", + "createdBy", + "eventId", "updated", - "version" + "updatedBy" ], - "risk-engine-configuration": [ - "dataViewId", + "slo": [ + "budgetingMethod", + "description", "enabled", - "filter", - "identifierType", - "interval", - "pageSize", - "range", - "range.end", - "range.start" + "id", + "indicator", + "indicator.params", + "indicator.type", + "name", + "tags", + "version" ], - "policy-settings-protection-updates-note": [ - "note" + "space": [ + "name" ], - "apm-telemetry": [], - "apm-server-schema": [ - "schemaJson" + "spaces-usage-stats": [], + "synthetics-monitor": [ + "alert", + "alert.status", + "alert.status.enabled", + "alert.tls", + "alert.tls.enabled", + "custom_heartbeat_id", + "enabled", + "hash", + "hosts", + "id", + "journey_id", + "locations", + "locations.id", + "locations.label", + "name", + "origin", + "project_id", + "schedule", + "schedule.number", + "tags", + "throttling", + "throttling.label", + "type", + "urls" ], - "apm-service-group": [ + "synthetics-param": [], + "synthetics-privates-locations": [], + "tag": [ "color", "description", - "groupName", - "kuery" + "name" ], - "apm-custom-dashboards": [ - "dashboardSavedObjectId", - "kuery", - "serviceEnvironmentFilterEnabled", - "serviceNameFilterEnabled" + "task": [ + "attempts", + "enabled", + "ownerId", + "retryAt", + "runAt", + "schedule", + "schedule.interval", + "scheduledAt", + "scope", + "status", + "taskType" ], - "cloud-security-posture-settings": [ - "rules" - ] + "telemetry": [], + "threshold-explorer-view": [], + "ui-metric": [ + "count" + ], + "upgrade-assistant-ml-upgrade-operation": [ + "snapshotId" + ], + "upgrade-assistant-reindex-operation": [ + "indexName", + "status" + ], + "uptime-dynamic-settings": [], + "uptime-synthetics-api-key": [ + "apiKey" + ], + "url": [ + "accessDate", + "createDate", + "slug" + ], + "usage-counters": [ + "domainId" + ], + "visualization": [ + "description", + "kibanaSavedObjectMeta", + "title", + "version" + ], + "workplace_search_telemetry": [] } diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 4768e2605bb0b..758fde639d00f 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -1,1054 +1,907 @@ { - "core-usage-stats": { - "dynamic": false, - "properties": {} - }, - "legacy-url-alias": { + "action": { "dynamic": false, "properties": { - "sourceId": { - "type": "keyword" - }, - "targetNamespace": { - "type": "keyword" - }, - "targetType": { - "type": "keyword" - }, - "targetId": { + "actionTypeId": { "type": "keyword" }, - "resolveCounter": { - "type": "long" - }, - "disabled": { - "type": "boolean" - } - } - }, - "config": { - "dynamic": false, - "properties": { - "buildNum": { - "type": "keyword" - } - } - }, - "config-global": { - "dynamic": false, - "properties": { - "buildNum": { - "type": "keyword" - } - } - }, - "url": { - "dynamic": false, - "properties": { - "slug": { - "type": "text", + "name": { "fields": { "keyword": { "type": "keyword" } - } - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" + }, + "type": "text" } } }, - "usage-counters": { + "action_task_params": { "dynamic": false, - "properties": { - "domainId": { - "type": "keyword" - } - } + "properties": {} }, - "task": { + "alert": { "dynamic": false, "properties": { - "taskType": { - "type": "keyword" - }, - "scheduledAt": { - "type": "date" - }, - "runAt": { - "type": "date" - }, - "retryAt": { - "type": "date" - }, - "enabled": { - "type": "boolean" - }, - "schedule": { + "actions": { + "dynamic": false, "properties": { - "interval": { + "actionRef": { "type": "keyword" - } - } - }, - "attempts": { - "type": "integer" - }, - "status": { - "type": "keyword" - }, - "scope": { - "type": "keyword" - }, - "ownerId": { - "type": "keyword" - } - } - }, - "guided-onboarding-guide-state": { - "dynamic": false, - "properties": { - "guideId": { - "type": "keyword" - }, - "isActive": { - "type": "boolean" - } - } - }, - "guided-onboarding-plugin-state": { - "dynamic": false, - "properties": {} - }, - "ui-metric": { - "properties": { - "count": { - "type": "integer" - } - } - }, - "application_usage_totals": { - "dynamic": false, - "properties": {} - }, - "application_usage_daily": { - "dynamic": false, - "properties": { - "timestamp": { - "type": "date" - } - } - }, - "event_loop_delays_daily": { - "dynamic": false, - "properties": { - "lastUpdatedAt": { - "type": "date" - } - } - }, - "index-pattern": { - "dynamic": false, - "properties": { - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { + }, + "actionTypeId": { + "type": "keyword" + }, + "group": { "type": "keyword" - } - } - } - } - }, - "sample-data-telemetry": { - "properties": { - "installCount": { - "type": "long" - }, - "unInstallCount": { - "type": "long" - } - } - }, - "space": { - "dynamic": false, - "properties": { - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } - } - } - } - }, - "spaces-usage-stats": { - "dynamic": false, - "properties": {} - }, - "exception-list-agnostic": { - "properties": { - "_tags": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "immutable": { - "type": "boolean" - }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "type": "text" } }, - "type": "keyword" + "type": "nested" }, - "tags": { - "fields": { - "text": { - "type": "text" - } - }, + "alertTypeId": { "type": "keyword" }, - "tie_breaker_id": { + "consumer": { "type": "keyword" }, - "type": { - "type": "keyword" + "createdAt": { + "type": "date" }, - "updated_by": { + "createdBy": { "type": "keyword" }, - "version": { - "type": "keyword" + "enabled": { + "type": "boolean" }, - "comments": { + "executionStatus": { "properties": { - "comment": { - "type": "keyword" + "error": { + "properties": { + "message": { + "type": "keyword" + }, + "reason": { + "type": "keyword" + } + } }, - "created_at": { - "type": "keyword" + "lastDuration": { + "type": "long" }, - "created_by": { - "type": "keyword" + "lastExecutionDate": { + "type": "date" }, - "id": { - "type": "keyword" + "numberOfTriggeredActions": { + "type": "long" }, - "updated_at": { + "status": { "type": "keyword" }, - "updated_by": { - "type": "keyword" - } - } - }, - "entries": { - "properties": { - "entries": { + "warning": { "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { + "message": { "type": "keyword" }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, + "reason": { "type": "keyword" } } - }, - "field": { - "type": "keyword" - }, - "list": { + } + } + }, + "lastRun": { + "properties": { + "alertsCount": { "properties": { - "id": { - "type": "keyword" + "active": { + "type": "float" }, - "type": { - "type": "keyword" + "ignored": { + "type": "float" + }, + "new": { + "type": "float" + }, + "recovered": { + "type": "float" } } }, - "operator": { - "type": "keyword" - }, - "type": { + "outcome": { "type": "keyword" }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" + "outcomeOrder": { + "type": "float" } } }, - "expire_time": { - "type": "date" - }, - "item_id": { - "type": "keyword" - }, - "os_types": { - "type": "keyword" - } - } - }, - "exception-list": { - "properties": { - "_tags": { - "type": "keyword" - }, - "created_at": { + "legacyId": { "type": "keyword" }, - "created_by": { - "type": "keyword" + "mapped_params": { + "properties": { + "risk_score": { + "type": "float" + }, + "severity": { + "type": "keyword" + } + } }, - "description": { - "type": "keyword" + "monitoring": { + "properties": { + "run": { + "properties": { + "calculated_metrics": { + "properties": { + "p50": { + "type": "long" + }, + "p95": { + "type": "long" + }, + "p99": { + "type": "long" + }, + "success_ratio": { + "type": "float" + } + } + }, + "last_run": { + "properties": { + "metrics": { + "properties": { + "duration": { + "type": "long" + }, + "gap_duration_s": { + "type": "float" + }, + "total_alerts_created": { + "type": "float" + }, + "total_alerts_detected": { + "type": "float" + }, + "total_indexing_duration_ms": { + "type": "long" + }, + "total_search_duration_ms": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + } + } + } + } + } + } }, - "immutable": { + "muteAll": { "type": "boolean" }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { + "mutedInstanceIds": { "type": "keyword" }, "name": { "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - }, - "tags": { - "fields": { - "text": { - "type": "text" + "keyword": { + "normalizer": "lowercase", + "type": "keyword" } }, - "type": "keyword" + "type": "text" }, - "tie_breaker_id": { + "notifyWhen": { "type": "keyword" }, - "type": { - "type": "keyword" + "params": { + "ignore_above": 4096, + "type": "flattened" }, - "updated_by": { - "type": "keyword" + "revision": { + "type": "long" }, - "version": { - "type": "keyword" + "running": { + "type": "boolean" }, - "comments": { + "schedule": { "properties": { - "comment": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "updated_at": { - "type": "keyword" - }, - "updated_by": { + "interval": { "type": "keyword" } } }, - "entries": { + "scheduledTaskId": { + "type": "keyword" + }, + "snoozeSchedule": { "properties": { - "entries": { - "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "field": { - "type": "keyword" - }, - "list": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "operator": { - "type": "keyword" + "duration": { + "type": "long" }, - "type": { + "id": { "type": "keyword" }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" + "skipRecurrences": { + "format": "strict_date_time", + "type": "date" } - } - }, - "expire_time": { - "type": "date" + }, + "type": "nested" }, - "item_id": { + "tags": { "type": "keyword" }, - "os_types": { + "throttle": { "type": "keyword" - } - } - }, - "telemetry": { - "dynamic": false, - "properties": {} - }, - "file": { - "dynamic": false, - "properties": { - "created": { - "type": "date" }, - "Updated": { + "updatedAt": { "type": "date" }, - "name": { - "type": "text" - }, - "user": { - "type": "flattened" - }, - "Status": { - "type": "keyword" - }, - "mime_type": { - "type": "keyword" - }, - "extension": { - "type": "keyword" - }, - "size": { - "type": "long" - }, - "Meta": { - "type": "flattened" - }, - "FileKind": { + "updatedBy": { "type": "keyword" - }, - "hash": { - "dynamic": false, - "properties": {} } } }, - "fileShare": { - "dynamic": false, + "api_key_pending_invalidation": { "properties": { - "created": { - "type": "date" - }, - "valid_until": { - "type": "long" - }, - "token": { + "apiKeyId": { "type": "keyword" }, - "name": { - "type": "keyword" + "createdAt": { + "type": "date" } } }, - "action": { - "dynamic": false, + "apm-custom-dashboards": { "properties": { - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "actionTypeId": { + "dashboardSavedObjectId": { "type": "keyword" + }, + "kuery": { + "type": "text" + }, + "serviceEnvironmentFilterEnabled": { + "type": "boolean" + }, + "serviceNameFilterEnabled": { + "type": "boolean" } } }, - "action_task_params": { + "apm-indices": { "dynamic": false, "properties": {} }, - "connector_token": { - "dynamic": false, + "apm-server-schema": { "properties": { - "connectorId": { - "type": "keyword" - }, - "tokenType": { - "type": "keyword" + "schemaJson": { + "index": false, + "type": "text" } } }, - "query": { - "dynamic": false, + "apm-service-group": { "properties": { - "title": { + "color": { "type": "text" }, "description": { "type": "text" + }, + "groupName": { + "type": "keyword" + }, + "kuery": { + "type": "text" } } }, - "kql-telemetry": { + "apm-telemetry": { "dynamic": false, "properties": {} }, - "search-session": { + "app_search_telemetry": { "dynamic": false, - "properties": { - "sessionId": { - "type": "keyword" - }, - "created": { - "type": "date" - }, - "realmType": { - "type": "keyword" - }, - "realmName": { - "type": "keyword" - }, - "username": { - "type": "keyword" + "properties": {} + }, + "application_usage_daily": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" } } }, - "search-telemetry": { + "application_usage_totals": { "dynamic": false, "properties": {} }, - "file-upload-usage-collection-telemetry": { + "canvas-element": { + "dynamic": false, "properties": { - "file_upload": { - "properties": { - "index_creation_count": { - "type": "long" + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "content": { + "type": "text" + }, + "help": { + "type": "text" + }, + "image": { + "type": "text" + }, + "name": { + "fields": { + "keyword": { + "type": "keyword" } - } + }, + "type": "text" } } }, - "apm-indices": { + "canvas-workpad": { "dynamic": false, - "properties": {} - }, - "tag": { "properties": { - "name": { - "type": "text" + "@created": { + "type": "date" }, - "description": { - "type": "text" + "@timestamp": { + "type": "date" }, - "color": { + "name": { + "fields": { + "keyword": { + "type": "keyword" + } + }, "type": "text" } } }, - "alert": { + "canvas-workpad-template": { "dynamic": false, "properties": { - "enabled": { - "type": "boolean" + "help": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, "name": { - "type": "text", "fields": { "keyword": { - "type": "keyword", - "normalizer": "lowercase" + "type": "keyword" } - } + }, + "type": "text" }, "tags": { - "type": "keyword" + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "alertTypeId": { + "template_key": { "type": "keyword" - }, - "schedule": { + } + } + }, + "cases": { + "dynamic": false, + "properties": { + "assignees": { "properties": { - "interval": { + "uid": { "type": "keyword" } } }, - "consumer": { + "category": { "type": "keyword" }, - "legacyId": { - "type": "keyword" + "closed_at": { + "type": "date" }, - "actions": { - "dynamic": false, - "type": "nested", + "closed_by": { "properties": { - "group": { + "email": { "type": "keyword" }, - "actionRef": { + "full_name": { "type": "keyword" }, - "actionTypeId": { + "profile_uid": { "type": "keyword" - } - } - }, - "params": { - "type": "flattened", - "ignore_above": 4096 - }, - "mapped_params": { - "properties": { - "risk_score": { - "type": "float" }, - "severity": { + "username": { "type": "keyword" } } }, - "scheduledTaskId": { - "type": "keyword" - }, - "createdBy": { - "type": "keyword" - }, - "updatedBy": { - "type": "keyword" - }, - "createdAt": { - "type": "date" - }, - "updatedAt": { - "type": "date" - }, - "throttle": { - "type": "keyword" - }, - "notifyWhen": { - "type": "keyword" - }, - "muteAll": { - "type": "boolean" - }, - "mutedInstanceIds": { - "type": "keyword" - }, - "monitoring": { + "connector": { "properties": { - "run": { + "fields": { "properties": { - "calculated_metrics": { - "properties": { - "p50": { - "type": "long" - }, - "p95": { - "type": "long" - }, - "p99": { - "type": "long" - }, - "success_ratio": { - "type": "float" - } - } + "key": { + "type": "text" }, - "last_run": { - "properties": { - "timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "duration": { - "type": "long" - }, - "total_search_duration_ms": { - "type": "long" - }, - "total_indexing_duration_ms": { - "type": "long" - }, - "total_alerts_detected": { - "type": "float" - }, - "total_alerts_created": { - "type": "float" - }, - "gap_duration_s": { - "type": "float" - } - } - } - } + "value": { + "type": "text" } } + }, + "name": { + "type": "text" + }, + "type": { + "type": "keyword" } } }, - "revision": { - "type": "long" + "created_at": { + "type": "date" }, - "snoozeSchedule": { - "type": "nested", + "created_by": { "properties": { - "id": { + "email": { "type": "keyword" }, - "duration": { - "type": "long" + "full_name": { + "type": "keyword" }, - "skipRecurrences": { - "type": "date", - "format": "strict_date_time" + "profile_uid": { + "type": "keyword" + }, + "username": { + "type": "keyword" } } }, - "executionStatus": { + "customFields": { "properties": { - "numberOfTriggeredActions": { - "type": "long" + "key": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "value": { + "fields": { + "boolean": { + "ignore_malformed": true, + "type": "boolean" + }, + "date": { + "ignore_malformed": true, + "type": "date" + }, + "ip": { + "ignore_malformed": true, + "type": "ip" + }, + "number": { + "ignore_malformed": true, + "type": "long" + }, + "string": { + "type": "text" + } + }, + "type": "keyword" + } + }, + "type": "nested" + }, + "description": { + "type": "text" + }, + "duration": { + "type": "unsigned_long" + }, + "external_service": { + "properties": { + "connector_name": { + "type": "keyword" }, - "status": { + "external_id": { "type": "keyword" }, - "lastExecutionDate": { - "type": "date" + "external_title": { + "type": "text" }, - "lastDuration": { - "type": "long" + "external_url": { + "type": "text" }, - "error": { + "pushed_at": { + "type": "date" + }, + "pushed_by": { "properties": { - "reason": { + "email": { "type": "keyword" }, - "message": { + "full_name": { "type": "keyword" - } - } - }, - "warning": { - "properties": { - "reason": { + }, + "profile_uid": { "type": "keyword" }, - "message": { + "username": { "type": "keyword" } } } } }, - "lastRun": { + "owner": { + "type": "keyword" + }, + "settings": { "properties": { - "outcome": { + "syncAlerts": { + "type": "boolean" + } + } + }, + "severity": { + "type": "short" + }, + "status": { + "type": "short" + }, + "tags": { + "type": "keyword" + }, + "title": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + }, + "total_alerts": { + "type": "integer" + }, + "total_comments": { + "type": "integer" + }, + "updated_at": { + "type": "date" + }, + "updated_by": { + "properties": { + "email": { "type": "keyword" }, - "outcomeOrder": { - "type": "float" + "full_name": { + "type": "keyword" }, - "alertsCount": { - "properties": { - "active": { - "type": "float" - }, - "new": { - "type": "float" - }, - "recovered": { - "type": "float" - }, - "ignored": { - "type": "float" - } - } + "profile_uid": { + "type": "keyword" + }, + "username": { + "type": "keyword" } } - }, - "running": { - "type": "boolean" } } }, - "api_key_pending_invalidation": { + "cases-comments": { + "dynamic": false, "properties": { - "apiKeyId": { + "actions": { + "properties": { + "type": { + "type": "keyword" + } + } + }, + "alertId": { "type": "keyword" }, - "createdAt": { + "comment": { + "type": "text" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "properties": { + "username": { + "type": "keyword" + } + } + }, + "externalReferenceAttachmentTypeId": { + "type": "keyword" + }, + "owner": { + "type": "keyword" + }, + "persistableStateAttachmentTypeId": { + "type": "keyword" + }, + "pushed_at": { + "type": "date" + }, + "type": { + "type": "keyword" + }, + "updated_at": { "type": "date" } } }, - "rules-settings": { + "cases-configure": { "dynamic": false, "properties": { - "flapping": { - "properties": {} + "closure_type": { + "type": "keyword" + }, + "created_at": { + "type": "date" + }, + "owner": { + "type": "keyword" } } }, - "maintenance-window": { + "cases-connector-mappings": { "dynamic": false, "properties": { - "enabled": { - "type": "boolean" - }, - "events": { - "type": "date_range", - "format": "epoch_millis||strict_date_optional_time" + "owner": { + "type": "keyword" } } }, - "graph-workspace": { + "cases-telemetry": { + "dynamic": false, + "properties": {} + }, + "cases-user-actions": { + "dynamic": false, "properties": { - "description": { - "type": "text" + "action": { + "type": "keyword" }, - "kibanaSavedObjectMeta": { + "created_at": { + "type": "date" + }, + "created_by": { "properties": { - "searchSourceJSON": { - "type": "text" + "username": { + "type": "keyword" } } }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" + "owner": { + "type": "keyword" }, - "wsState": { - "type": "text" + "payload": { + "dynamic": false, + "properties": { + "assignees": { + "properties": { + "uid": { + "type": "keyword" + } + } + }, + "comment": { + "properties": { + "externalReferenceAttachmentTypeId": { + "type": "keyword" + }, + "persistableStateAttachmentTypeId": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "connector": { + "properties": { + "type": { + "type": "keyword" + } + } + } + } }, - "legacyIndexPatternRef": { - "type": "text", - "index": false + "type": { + "type": "keyword" } } }, - "search": { + "cloud-security-posture-settings": { + "dynamic": false, + "properties": {} + }, + "config": { "dynamic": false, "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" + "buildNum": { + "type": "keyword" } } }, - "visualization": { + "config-global": { "dynamic": false, "properties": { - "description": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": {} + "buildNum": { + "type": "keyword" } } }, - "event-annotation-group": { + "connector_token": { "dynamic": false, "properties": { - "title": { - "type": "text" + "connectorId": { + "type": "keyword" }, - "description": { - "type": "text" + "tokenType": { + "type": "keyword" + } + } + }, + "core-usage-stats": { + "dynamic": false, + "properties": {} + }, + "csp-rule-template": { + "dynamic": false, + "properties": { + "metadata": { + "properties": { + "benchmark": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "posture_type": { + "type": "keyword" + }, + "rule_number": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + }, + "type": "object" + }, + "id": { + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + }, + "section": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + }, + "version": { + "type": "keyword" + } + }, + "type": "object" } } }, "dashboard": { "properties": { + "controlGroupInput": { + "properties": { + "chainingSystem": { + "doc_values": false, + "index": false, + "type": "keyword" + }, + "controlStyle": { + "doc_values": false, + "index": false, + "type": "keyword" + }, + "ignoreParentSettingsJSON": { + "index": false, + "type": "text" + }, + "panelsJSON": { + "index": false, + "type": "text" + } + } + }, "description": { "type": "text" }, "hits": { - "type": "integer", + "doc_values": false, "index": false, - "doc_values": false + "type": "integer" }, "kibanaSavedObjectMeta": { "properties": { "searchSourceJSON": { - "type": "text", - "index": false + "index": false, + "type": "text" } } }, "optionsJSON": { - "type": "text", - "index": false + "index": false, + "type": "text" }, "panelsJSON": { - "type": "text", - "index": false + "index": false, + "type": "text" }, "refreshInterval": { "properties": { "display": { - "type": "keyword", + "doc_values": false, "index": false, - "doc_values": false + "type": "keyword" }, "pause": { - "type": "boolean", + "doc_values": false, "index": false, - "doc_values": false + "type": "boolean" }, "section": { - "type": "integer", + "doc_values": false, "index": false, - "doc_values": false + "type": "integer" }, "value": { - "type": "integer", - "index": false, - "doc_values": false - } - } - }, - "controlGroupInput": { - "properties": { - "controlStyle": { - "type": "keyword", - "index": false, - "doc_values": false - }, - "chainingSystem": { - "type": "keyword", + "doc_values": false, "index": false, - "doc_values": false - }, - "panelsJSON": { - "type": "text", - "index": false - }, - "ignoreParentSettingsJSON": { - "type": "text", - "index": false + "type": "integer" } } }, "timeFrom": { - "type": "keyword", + "doc_values": false, "index": false, - "doc_values": false + "type": "keyword" }, "timeRestore": { - "type": "boolean", + "doc_values": false, "index": false, - "doc_values": false + "type": "boolean" }, "timeTo": { - "type": "keyword", + "doc_values": false, "index": false, - "doc_values": false + "type": "keyword" }, "title": { "type": "text" @@ -1058,536 +911,686 @@ } } }, - "links": { + "endpoint:user-artifact-manifest": { "dynamic": false, "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" + "artifacts": { + "type": "nested" }, - "links": { - "dynamic": false, - "properties": {} + "schemaVersion": { + "type": "keyword" } } }, - "lens": { + "enterprise_search_telemetry": { + "dynamic": false, + "properties": {} + }, + "epm-packages": { "properties": { - "title": { - "type": "text" + "es_index_patterns": { + "dynamic": false, + "properties": {} }, - "description": { - "type": "text" + "experimental_data_stream_features": { + "properties": { + "data_stream": { + "type": "keyword" + }, + "features": { + "dynamic": false, + "properties": { + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "nested" + } + }, + "type": "nested" }, - "visualizationType": { + "install_format_schema_version": { + "type": "version" + }, + "install_source": { "type": "keyword" }, - "state": { - "dynamic": false, - "properties": {} - } - } - }, - "lens-ui-telemetry": { - "properties": { - "name": { + "install_started_at": { + "type": "date" + }, + "install_status": { "type": "keyword" }, - "type": { + "install_version": { "type": "keyword" }, - "date": { - "type": "date" + "installed_es": { + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + }, + "type": "nested" }, - "count": { - "type": "integer" - } - } - }, - "map": { - "properties": { - "description": { - "type": "text" + "installed_kibana": { + "dynamic": false, + "properties": {} }, - "title": { - "type": "text" + "installed_kibana_space_id": { + "type": "keyword" }, - "version": { - "type": "integer" + "internal": { + "type": "boolean" }, - "mapStateJSON": { - "type": "text" + "keep_policies_up_to_date": { + "index": false, + "type": "boolean" }, - "layerListJSON": { - "type": "text" + "latest_install_failed_attempts": { + "enabled": false, + "type": "object" }, - "uiStateJSON": { - "type": "text" + "name": { + "type": "keyword" }, - "bounds": { + "package_assets": { "dynamic": false, "properties": {} - } - } - }, - "cases-comments": { - "dynamic": false, - "properties": { - "comment": { - "type": "text" }, - "owner": { + "verification_key_id": { "type": "keyword" }, - "type": { + "verification_status": { "type": "keyword" }, - "actions": { - "properties": { - "type": { - "type": "keyword" - } - } - }, - "alertId": { + "version": { + "type": "keyword" + } + } + }, + "epm-packages-assets": { + "properties": { + "asset_path": { "type": "keyword" }, - "created_at": { - "type": "date" + "data_base64": { + "type": "binary" }, - "created_by": { - "properties": { - "username": { - "type": "keyword" - } - } + "data_utf8": { + "index": false, + "type": "text" }, - "externalReferenceAttachmentTypeId": { + "install_source": { "type": "keyword" }, - "persistableStateAttachmentTypeId": { + "media_type": { "type": "keyword" }, - "pushed_at": { - "type": "date" + "package_name": { + "type": "keyword" }, - "updated_at": { - "type": "date" + "package_version": { + "type": "keyword" } } }, - "cases-configure": { + "event-annotation-group": { "dynamic": false, "properties": { - "created_at": { - "type": "date" - }, - "closure_type": { - "type": "keyword" + "description": { + "type": "text" }, - "owner": { - "type": "keyword" + "title": { + "type": "text" } } }, - "cases-connector-mappings": { + "event_loop_delays_daily": { "dynamic": false, "properties": { - "owner": { - "type": "keyword" + "lastUpdatedAt": { + "type": "date" } } }, - "cases": { - "dynamic": false, + "exception-list": { "properties": { - "assignees": { - "properties": { - "uid": { - "type": "keyword" - } - } - }, - "closed_at": { - "type": "date" + "_tags": { + "type": "keyword" }, - "closed_by": { + "comments": { "properties": { - "username": { + "comment": { "type": "keyword" }, - "full_name": { + "created_at": { "type": "keyword" }, - "email": { + "created_by": { "type": "keyword" }, - "profile_uid": { + "id": { + "type": "keyword" + }, + "updated_at": { + "type": "keyword" + }, + "updated_by": { "type": "keyword" } } }, "created_at": { - "type": "date" + "type": "keyword" }, "created_by": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "entries": { "properties": { - "username": { + "entries": { + "properties": { + "field": { + "type": "keyword" + }, + "operator": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "value": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + } + } + }, + "field": { "type": "keyword" }, - "full_name": { + "list": { + "properties": { + "id": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "operator": { "type": "keyword" }, - "email": { + "type": { "type": "keyword" }, - "profile_uid": { + "value": { + "fields": { + "text": { + "type": "text" + } + }, "type": "keyword" } } }, - "duration": { - "type": "unsigned_long" + "expire_time": { + "type": "date" }, - "description": { - "type": "text" + "immutable": { + "type": "boolean" }, - "connector": { - "properties": { - "name": { + "item_id": { + "type": "keyword" + }, + "list_id": { + "type": "keyword" + }, + "list_type": { + "type": "keyword" + }, + "meta": { + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + }, + "os_types": { + "type": "keyword" + }, + "tags": { + "fields": { + "text": { "type": "text" + } + }, + "type": "keyword" + }, + "tie_breaker_id": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "updated_by": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "exception-list-agnostic": { + "properties": { + "_tags": { + "type": "keyword" + }, + "comments": { + "properties": { + "comment": { + "type": "keyword" }, - "type": { + "created_at": { "type": "keyword" }, - "fields": { - "properties": { - "key": { - "type": "text" - }, - "value": { - "type": "text" - } - } + "created_by": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "updated_at": { + "type": "keyword" + }, + "updated_by": { + "type": "keyword" } } }, - "external_service": { + "created_at": { + "type": "keyword" + }, + "created_by": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "entries": { "properties": { - "pushed_at": { - "type": "date" - }, - "pushed_by": { + "entries": { "properties": { - "username": { + "field": { "type": "keyword" }, - "full_name": { + "operator": { "type": "keyword" }, - "email": { + "type": { "type": "keyword" }, - "profile_uid": { + "value": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + } + } + }, + "field": { + "type": "keyword" + }, + "list": { + "properties": { + "id": { + "type": "keyword" + }, + "type": { "type": "keyword" } } }, - "connector_name": { + "operator": { "type": "keyword" }, - "external_id": { + "type": { "type": "keyword" }, - "external_title": { - "type": "text" - }, - "external_url": { - "type": "text" + "value": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" } } }, - "owner": { + "expire_time": { + "type": "date" + }, + "immutable": { + "type": "boolean" + }, + "item_id": { "type": "keyword" }, - "title": { - "type": "text", + "list_id": { + "type": "keyword" + }, + "list_type": { + "type": "keyword" + }, + "meta": { + "type": "keyword" + }, + "name": { "fields": { - "keyword": { - "type": "keyword" + "text": { + "type": "text" } - } + }, + "type": "keyword" }, - "status": { - "type": "short" + "os_types": { + "type": "keyword" }, "tags": { + "fields": { + "text": { + "type": "text" + } + }, "type": "keyword" }, - "updated_at": { - "type": "date" + "tie_breaker_id": { + "type": "keyword" + }, + "type": { + "type": "keyword" }, "updated_by": { - "properties": { - "username": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "email": { - "type": "keyword" - }, - "profile_uid": { - "type": "keyword" - } - } + "type": "keyword" }, - "settings": { - "properties": { - "syncAlerts": { - "type": "boolean" - } - } + "version": { + "type": "keyword" + } + } + }, + "file": { + "dynamic": false, + "properties": { + "FileKind": { + "type": "keyword" }, - "severity": { - "type": "short" + "Meta": { + "type": "flattened" }, - "total_alerts": { - "type": "integer" + "Status": { + "type": "keyword" }, - "total_comments": { - "type": "integer" + "Updated": { + "type": "date" }, - "category": { + "created": { + "type": "date" + }, + "extension": { "type": "keyword" }, - "customFields": { - "type": "nested", + "hash": { + "dynamic": false, + "properties": {} + }, + "mime_type": { + "type": "keyword" + }, + "name": { + "type": "text" + }, + "size": { + "type": "long" + }, + "user": { + "type": "flattened" + } + } + }, + "file-upload-usage-collection-telemetry": { + "properties": { + "file_upload": { "properties": { - "key": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "type": "keyword", - "fields": { - "number": { - "type": "long", - "ignore_malformed": true - }, - "boolean": { - "type": "boolean", - "ignore_malformed": true - }, - "string": { - "type": "text" - }, - "date": { - "type": "date", - "ignore_malformed": true - }, - "ip": { - "type": "ip", - "ignore_malformed": true - } - } + "index_creation_count": { + "type": "long" } } } } }, - "cases-user-actions": { + "fileShare": { "dynamic": false, "properties": { - "action": { + "created": { + "type": "date" + }, + "name": { "type": "keyword" }, - "created_at": { - "type": "date" + "token": { + "type": "keyword" }, - "created_by": { - "properties": { - "username": { - "type": "keyword" - } - } + "valid_until": { + "type": "long" + } + } + }, + "fleet-fleet-server-host": { + "properties": { + "host_urls": { + "index": false, + "type": "keyword" }, - "payload": { - "dynamic": false, - "properties": { - "connector": { - "properties": { - "type": { - "type": "keyword" - } - } - }, - "comment": { - "properties": { - "type": { - "type": "keyword" - }, - "externalReferenceAttachmentTypeId": { - "type": "keyword" - }, - "persistableStateAttachmentTypeId": { - "type": "keyword" - } - } - }, - "assignees": { - "properties": { - "uid": { - "type": "keyword" - } - } - } - } + "is_default": { + "type": "boolean" }, - "owner": { + "is_internal": { + "index": false, + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "keyword" + }, + "proxy_id": { + "type": "keyword" + } + } + }, + "fleet-message-signing-keys": { + "dynamic": false, + "properties": {} + }, + "fleet-preconfiguration-deletion-record": { + "properties": { + "id": { + "type": "keyword" + } + } + }, + "fleet-proxy": { + "properties": { + "certificate": { + "index": false, + "type": "keyword" + }, + "certificate_authorities": { + "index": false, + "type": "keyword" + }, + "certificate_key": { + "index": false, + "type": "keyword" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { "type": "keyword" }, - "type": { + "proxy_headers": { + "index": false, + "type": "text" + }, + "url": { + "index": false, "type": "keyword" } } }, - "cases-telemetry": { - "dynamic": false, - "properties": {} - }, - "infrastructure-monitoring-log-view": { + "fleet-uninstall-tokens": { "dynamic": false, "properties": { - "name": { - "type": "text" + "policy_id": { + "type": "keyword" + }, + "token_plain": { + "type": "keyword" } } }, - "metrics-data-source": { - "dynamic": false, - "properties": {} - }, - "canvas-element": { - "dynamic": false, + "graph-workspace": { "properties": { - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } } }, - "help": { + "legacyIndexPatternRef": { + "index": false, "type": "text" }, - "content": { - "type": "text" + "numLinks": { + "type": "integer" }, - "image": { + "numVertices": { + "type": "integer" + }, + "title": { "type": "text" }, - "@timestamp": { - "type": "date" + "version": { + "type": "integer" }, - "@created": { - "type": "date" + "wsState": { + "type": "text" } } }, - "canvas-workpad": { + "guided-onboarding-guide-state": { "dynamic": false, "properties": { - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "@timestamp": { - "type": "date" + "guideId": { + "type": "keyword" }, - "@created": { - "type": "date" + "isActive": { + "type": "boolean" } } }, - "canvas-workpad-template": { + "guided-onboarding-plugin-state": { + "dynamic": false, + "properties": {} + }, + "index-pattern": { "dynamic": false, "properties": { "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "help": { - "type": "text", "fields": { "keyword": { "type": "keyword" } - } + }, + "type": "text" }, - "tags": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "title": { + "type": "text" }, - "template_key": { + "type": { "type": "keyword" } } }, - "ingest_manager_settings": { + "infrastructure-monitoring-log-view": { + "dynamic": false, "properties": { - "fleet_server_hosts": { - "type": "keyword" - }, - "has_seen_add_data_notice": { - "type": "boolean", - "index": false - }, - "prerelease_integrations_enabled": { - "type": "boolean" - }, - "output_secret_storage_requirements_met": { - "type": "boolean" - }, - "secret_storage_requirements_met": { - "type": "boolean" + "name": { + "type": "text" } } }, + "infrastructure-ui-source": { + "dynamic": false, + "properties": {} + }, "ingest-agent-policies": { "properties": { - "name": { - "type": "keyword" + "agent_features": { + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "keyword" + } + } }, - "schema_version": { - "type": "version" + "data_output_id": { + "type": "keyword" }, "description": { "type": "text" }, - "namespace": { + "download_source_id": { "type": "keyword" }, - "is_managed": { - "type": "boolean" + "fleet_server_host_id": { + "type": "keyword" + }, + "inactivity_timeout": { + "type": "integer" }, "is_default": { "type": "boolean" @@ -1595,97 +1598,111 @@ "is_default_fleet_server": { "type": "boolean" }, - "status": { + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { "type": "keyword" }, - "unenroll_timeout": { - "type": "integer" + "is_protected": { + "type": "boolean" }, - "inactivity_timeout": { - "type": "integer" + "keep_monitoring_alive": { + "type": "boolean" }, - "updated_at": { - "type": "date" + "monitoring_enabled": { + "index": false, + "type": "keyword" }, - "updated_by": { + "monitoring_output_id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "namespace": { "type": "keyword" }, + "overrides": { + "index": false, + "type": "flattened" + }, "revision": { "type": "integer" }, - "monitoring_enabled": { - "type": "keyword", - "index": false + "schema_version": { + "type": "version" }, - "is_preconfigured": { + "status": { "type": "keyword" }, - "data_output_id": { - "type": "keyword" + "unenroll_timeout": { + "type": "integer" }, - "monitoring_output_id": { - "type": "keyword" + "updated_at": { + "type": "date" }, - "download_source_id": { + "updated_by": { "type": "keyword" - }, - "fleet_server_host_id": { + } + } + }, + "ingest-download-sources": { + "properties": { + "host": { "type": "keyword" }, - "agent_features": { - "properties": { - "name": { - "type": "keyword" - }, - "enabled": { - "type": "boolean" - } - } - }, - "is_protected": { + "is_default": { "type": "boolean" }, - "overrides": { - "type": "flattened", - "index": false + "name": { + "type": "keyword" }, - "keep_monitoring_alive": { - "type": "boolean" + "proxy_id": { + "type": "keyword" + }, + "source_id": { + "index": false, + "type": "keyword" } } }, "ingest-outputs": { "properties": { - "output_id": { - "type": "keyword", - "index": false - }, - "name": { - "type": "keyword" + "allow_edit": { + "enabled": false }, - "type": { + "auth_type": { "type": "keyword" }, - "is_default": { - "type": "boolean" + "broker_ack_reliability": { + "type": "text" }, - "is_default_monitoring": { - "type": "boolean" + "broker_buffer_size": { + "type": "integer" }, - "hosts": { - "type": "keyword" + "broker_timeout": { + "type": "integer" }, "ca_sha256": { - "type": "keyword", - "index": false + "index": false, + "type": "keyword" }, "ca_trusted_fingerprint": { - "type": "keyword", - "index": false + "index": false, + "type": "keyword" + }, + "channel_buffer_size": { + "type": "integer" + }, + "client_id": { + "type": "keyword" + }, + "compression": { + "type": "keyword" }, - "service_token": { - "type": "keyword", - "index": false + "compression_level": { + "type": "integer" }, "config": { "type": "flattened" @@ -1693,64 +1710,70 @@ "config_yaml": { "type": "text" }, - "is_preconfigured": { - "type": "boolean", - "index": false - }, - "is_internal": { - "type": "boolean", - "index": false - }, - "ssl": { - "type": "binary" - }, - "proxy_id": { + "connection_type": { "type": "keyword" }, - "shipper": { + "hash": { "dynamic": false, - "properties": {} + "properties": { + "hash": { + "type": "text" + }, + "random": { + "type": "boolean" + } + } }, - "allow_edit": { - "enabled": false + "headers": { + "dynamic": false, + "properties": { + "key": { + "type": "text" + }, + "value": { + "type": "text" + } + } }, - "version": { + "hosts": { "type": "keyword" }, - "key": { - "type": "keyword" + "is_default": { + "type": "boolean" }, - "compression": { - "type": "keyword" + "is_default_monitoring": { + "type": "boolean" }, - "compression_level": { - "type": "integer" + "is_internal": { + "index": false, + "type": "boolean" }, - "client_id": { + "is_preconfigured": { + "index": false, + "type": "boolean" + }, + "key": { "type": "keyword" }, - "auth_type": { + "name": { "type": "keyword" }, - "connection_type": { + "output_id": { + "index": false, "type": "keyword" }, - "username": { + "partition": { "type": "keyword" }, "password": { - "type": "text", - "index": false + "index": false, + "type": "text" }, - "sasl": { - "dynamic": false, - "properties": { - "mechanism": { - "type": "text" - } - } + "preset": { + "index": false, + "type": "keyword" }, - "partition": { + "proxy_id": { "type": "keyword" }, "random": { @@ -1761,6 +1784,9 @@ } } }, + "required_acks": { + "type": "integer" + }, "round_robin": { "dynamic": false, "properties": { @@ -1769,69 +1795,26 @@ } } }, - "hash": { + "sasl": { "dynamic": false, "properties": { - "hash": { + "mechanism": { "type": "text" - }, - "random": { - "type": "boolean" } } }, - "topics": { + "secrets": { "dynamic": false, "properties": { - "topic": { - "type": "keyword" - }, - "when": { + "password": { "dynamic": false, "properties": { - "type": { - "type": "text" - }, - "condition": { - "type": "text" + "id": { + "type": "keyword" } } - } - } - }, - "headers": { - "dynamic": false, - "properties": { - "key": { - "type": "text" }, - "value": { - "type": "text" - } - } - }, - "timeout": { - "type": "integer" - }, - "broker_timeout": { - "type": "integer" - }, - "broker_ack_reliability": { - "type": "text" - }, - "broker_buffer_size": { - "type": "integer" - }, - "required_acks": { - "type": "integer" - }, - "channel_buffer_size": { - "type": "integer" - }, - "secrets": { - "dynamic": false, - "properties": { - "password": { + "service_token": { "dynamic": false, "properties": { "id": { @@ -1851,41 +1834,82 @@ } } } + } + } + }, + "service_token": { + "index": false, + "type": "keyword" + }, + "shipper": { + "dynamic": false, + "properties": {} + }, + "ssl": { + "type": "binary" + }, + "timeout": { + "type": "integer" + }, + "topics": { + "dynamic": false, + "properties": { + "topic": { + "type": "keyword" }, - "service_token": { + "when": { "dynamic": false, "properties": { - "id": { - "type": "keyword" + "condition": { + "type": "text" + }, + "type": { + "type": "text" } } } } }, - "preset": { - "type": "keyword", - "index": false + "type": { + "type": "keyword" + }, + "username": { + "type": "keyword" + }, + "version": { + "type": "keyword" } } }, "ingest-package-policies": { "properties": { - "name": { + "created_at": { + "type": "date" + }, + "created_by": { "type": "keyword" }, "description": { "type": "text" }, - "namespace": { - "type": "keyword" + "elasticsearch": { + "dynamic": false, + "properties": {} }, "enabled": { "type": "boolean" }, + "inputs": { + "dynamic": false, + "properties": {} + }, "is_managed": { "type": "boolean" }, - "policy_id": { + "name": { + "type": "keyword" + }, + "namespace": { "type": "keyword" }, "package": { @@ -1901,16 +1925,11 @@ } } }, - "elasticsearch": { - "dynamic": false, - "properties": {} - }, - "vars": { - "type": "flattened" + "policy_id": { + "type": "keyword" }, - "inputs": { - "dynamic": false, - "properties": {} + "revision": { + "type": "integer" }, "secret_references": { "properties": { @@ -1919,235 +1938,295 @@ } } }, - "revision": { - "type": "integer" + "updated_at": { + "type": "date" + }, + "updated_by": { + "type": "keyword" + }, + "vars": { + "type": "flattened" + } + } + }, + "ingest_manager_settings": { + "properties": { + "fleet_server_hosts": { + "type": "keyword" + }, + "has_seen_add_data_notice": { + "index": false, + "type": "boolean" + }, + "output_secret_storage_requirements_met": { + "type": "boolean" + }, + "prerelease_integrations_enabled": { + "type": "boolean" + }, + "secret_storage_requirements_met": { + "type": "boolean" + } + } + }, + "inventory-view": { + "dynamic": false, + "properties": {} + }, + "kql-telemetry": { + "dynamic": false, + "properties": {} + }, + "legacy-url-alias": { + "dynamic": false, + "properties": { + "disabled": { + "type": "boolean" + }, + "resolveCounter": { + "type": "long" }, - "updated_at": { - "type": "date" + "sourceId": { + "type": "keyword" }, - "updated_by": { + "targetId": { "type": "keyword" }, - "created_at": { - "type": "date" + "targetNamespace": { + "type": "keyword" }, - "created_by": { + "targetType": { "type": "keyword" } } }, - "epm-packages": { + "lens": { "properties": { - "name": { - "type": "keyword" - }, - "version": { - "type": "keyword" - }, - "internal": { - "type": "boolean" - }, - "keep_policies_up_to_date": { - "type": "boolean", - "index": false + "description": { + "type": "text" }, - "es_index_patterns": { + "state": { "dynamic": false, "properties": {} }, - "verification_status": { - "type": "keyword" - }, - "verification_key_id": { - "type": "keyword" - }, - "installed_es": { - "type": "nested", - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "version": { - "type": "keyword" - }, - "deferred": { - "type": "boolean" - } - } - }, - "latest_install_failed_attempts": { - "type": "object", - "enabled": false - }, - "installed_kibana": { - "dynamic": false, - "properties": {} + "title": { + "type": "text" }, - "installed_kibana_space_id": { + "visualizationType": { "type": "keyword" + } + } + }, + "lens-ui-telemetry": { + "properties": { + "count": { + "type": "integer" }, - "package_assets": { - "dynamic": false, - "properties": {} - }, - "install_started_at": { + "date": { "type": "date" }, - "install_version": { + "name": { "type": "keyword" }, - "install_status": { + "type": { "type": "keyword" + } + } + }, + "links": { + "dynamic": false, + "properties": { + "description": { + "type": "text" }, - "install_source": { - "type": "keyword" + "links": { + "dynamic": false, + "properties": {} }, - "install_format_schema_version": { - "type": "version" + "title": { + "type": "text" + } + } + }, + "maintenance-window": { + "dynamic": false, + "properties": { + "enabled": { + "type": "boolean" }, - "experimental_data_stream_features": { - "type": "nested", - "properties": { - "data_stream": { - "type": "keyword" - }, - "features": { - "type": "nested", - "dynamic": false, - "properties": { - "synthetic_source": { - "type": "boolean" - }, - "tsdb": { - "type": "boolean" - } - } - } - } + "events": { + "format": "epoch_millis||strict_date_optional_time", + "type": "date_range" } } }, - "epm-packages-assets": { + "map": { "properties": { - "package_name": { - "type": "keyword" + "bounds": { + "dynamic": false, + "properties": {} }, - "package_version": { - "type": "keyword" + "description": { + "type": "text" }, - "install_source": { - "type": "keyword" + "layerListJSON": { + "type": "text" }, - "asset_path": { - "type": "keyword" + "mapStateJSON": { + "type": "text" }, - "media_type": { - "type": "keyword" + "title": { + "type": "text" }, - "data_utf8": { - "type": "text", - "index": false + "uiStateJSON": { + "type": "text" }, - "data_base64": { - "type": "binary" + "version": { + "type": "integer" } } }, - "fleet-preconfiguration-deletion-record": { + "metrics-data-source": { + "dynamic": false, + "properties": {} + }, + "metrics-explorer-view": { + "dynamic": false, + "properties": {} + }, + "ml-job": { "properties": { - "id": { + "datafeed_id": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + }, + "job_id": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + }, + "type": { "type": "keyword" } } }, - "ingest-download-sources": { + "ml-module": { + "dynamic": false, "properties": { - "source_id": { - "type": "keyword", - "index": false + "datafeeds": { + "type": "object" }, - "name": { - "type": "keyword" + "defaultIndexPattern": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "is_default": { - "type": "boolean" + "description": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "host": { - "type": "keyword" + "id": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "proxy_id": { - "type": "keyword" - } - } - }, - "fleet-fleet-server-host": { - "properties": { - "name": { - "type": "keyword" + "jobs": { + "type": "object" }, - "is_default": { - "type": "boolean" + "logo": { + "type": "object" }, - "is_internal": { - "type": "boolean", - "index": false + "query": { + "type": "object" }, - "host_urls": { - "type": "keyword", - "index": false + "tags": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "is_preconfigured": { - "type": "boolean" + "title": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" }, - "proxy_id": { - "type": "keyword" + "type": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" } } }, - "fleet-proxy": { + "ml-trained-model": { "properties": { - "name": { - "type": "keyword" - }, - "url": { - "type": "keyword", - "index": false - }, - "proxy_headers": { - "type": "text", - "index": false - }, - "certificate_authorities": { - "type": "keyword", - "index": false - }, - "certificate": { - "type": "keyword", - "index": false - }, - "certificate_key": { - "type": "keyword", - "index": false + "job": { + "properties": { + "create_time": { + "type": "date" + }, + "job_id": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + } + } }, - "is_preconfigured": { - "type": "boolean" + "model_id": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" } } }, - "fleet-message-signing-keys": { - "dynamic": false, - "properties": {} - }, - "fleet-uninstall-tokens": { - "dynamic": false, + "monitoring-telemetry": { "properties": { - "policy_id": { + "reportedClusterUuids": { "type": "keyword" + } + } + }, + "observability-onboarding-state": { + "properties": { + "progress": { + "dynamic": false, + "type": "object" }, - "token_plain": { + "state": { + "dynamic": false, + "type": "object" + }, + "type": { "type": "keyword" } } @@ -2162,237 +2241,58 @@ } } }, - "osquery-saved-query": { - "dynamic": false, + "osquery-pack": { "properties": { - "description": { - "type": "text" - }, - "id": { - "type": "keyword" - }, - "query": { - "type": "text" - }, "created_at": { "type": "date" }, "created_by": { - "type": "text" - }, - "platform": { - "type": "keyword" - }, - "version": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "text" - }, - "interval": { "type": "keyword" }, - "timeout": { - "type": "short" - }, - "ecs_mapping": { - "dynamic": false, - "properties": {} - } - } - }, - "osquery-pack": { - "properties": { "description": { "type": "text" }, - "name": { - "type": "text" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "keyword" - }, "enabled": { "type": "boolean" }, - "shards": { - "dynamic": false, - "properties": {} - }, - "version": { - "type": "long" + "name": { + "type": "text" }, "queries": { "dynamic": false, "properties": { + "ecs_mapping": { + "dynamic": false, + "properties": {} + }, "id": { "type": "keyword" }, - "query": { - "type": "text" - }, "interval": { "type": "text" }, - "timeout": { - "type": "short" - }, "platform": { "type": "keyword" }, - "version": { - "type": "keyword" - }, - "ecs_mapping": { - "dynamic": false, - "properties": {} - } - } - } - } - }, - "osquery-pack-asset": { - "dynamic": false, - "properties": { - "description": { - "type": "text" - }, - "name": { - "type": "text" - }, - "version": { - "type": "long" - }, - "shards": { - "dynamic": false, - "properties": {} - }, - "queries": { - "dynamic": false, - "properties": { - "id": { - "type": "keyword" - }, "query": { "type": "text" }, - "interval": { - "type": "text" - }, "timeout": { "type": "short" }, - "platform": { - "type": "keyword" - }, - "version": { - "type": "keyword" - }, - "ecs_mapping": { - "dynamic": false, - "properties": {} - } - } - } - } - }, - "csp-rule-template": { - "dynamic": false, - "properties": { - "metadata": { - "type": "object", - "properties": { - "name": { - "type": "keyword", - "fields": { - "text": { - "type": "text" - } - } - }, - "id": { - "type": "keyword" - }, - "section": { - "type": "keyword", - "fields": { - "text": { - "type": "text" - } - } - }, "version": { "type": "keyword" - }, - "benchmark": { - "type": "object", - "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "posture_type": { - "type": "keyword" - }, - "version": { - "type": "keyword" - }, - "rule_number": { - "type": "keyword" - } - } - } - } - } - } - }, - "cloud-security-posture-settings": { - "dynamic": false, - "properties": {} - }, - "slo": { - "dynamic": false, - "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "description": { - "type": "text" - }, - "indicator": { - "properties": { - "type": { - "type": "keyword" - }, - "params": { - "type": "flattened" } } }, - "budgetingMethod": { - "type": "keyword" + "shards": { + "dynamic": false, + "properties": {} }, - "enabled": { - "type": "boolean" + "updated_at": { + "type": "date" }, - "tags": { + "updated_by": { "type": "keyword" }, "version": { @@ -2400,404 +2300,238 @@ } } }, - "threshold-explorer-view": { + "osquery-pack-asset": { "dynamic": false, - "properties": {} - }, - "observability-onboarding-state": { "properties": { - "type": { - "type": "keyword" + "description": { + "type": "text" }, - "state": { - "type": "object", - "dynamic": false + "name": { + "type": "text" }, - "progress": { - "type": "object", - "dynamic": false - } - } - }, - "ml-job": { - "properties": { - "job_id": { - "type": "text", - "fields": { - "keyword": { + "queries": { + "dynamic": false, + "properties": { + "ecs_mapping": { + "dynamic": false, + "properties": {} + }, + "id": { "type": "keyword" - } - } - }, - "datafeed_id": { - "type": "text", - "fields": { - "keyword": { + }, + "interval": { + "type": "text" + }, + "platform": { "type": "keyword" - } - } - }, - "type": { - "type": "keyword" - } - } - }, - "ml-trained-model": { - "properties": { - "model_id": { - "type": "text", - "fields": { - "keyword": { + }, + "query": { + "type": "text" + }, + "timeout": { + "type": "short" + }, + "version": { "type": "keyword" } } }, - "job": { - "properties": { - "job_id": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "create_time": { - "type": "date" - } - } + "shards": { + "dynamic": false, + "properties": {} + }, + "version": { + "type": "long" } } }, - "ml-module": { + "osquery-saved-query": { "dynamic": false, "properties": { - "id": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "created_at": { + "type": "date" }, - "title": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "created_by": { + "type": "text" }, "description": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "type": "text" }, - "type": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "ecs_mapping": { + "dynamic": false, + "properties": {} }, - "logo": { - "type": "object" + "id": { + "type": "keyword" }, - "defaultIndexPattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "interval": { + "type": "keyword" + }, + "platform": { + "type": "keyword" }, "query": { - "type": "object" + "type": "text" }, - "jobs": { - "type": "object" + "timeout": { + "type": "short" }, - "datafeeds": { - "type": "object" + "updated_at": { + "type": "date" }, - "tags": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } + "updated_by": { + "type": "text" + }, + "version": { + "type": "keyword" } } }, - "uptime-dynamic-settings": { - "dynamic": false, - "properties": {} + "policy-settings-protection-updates-note": { + "properties": { + "note": { + "index": false, + "type": "text" + } + } }, - "synthetics-privates-locations": { + "query": { "dynamic": false, - "properties": {} + "properties": { + "description": { + "type": "text" + }, + "title": { + "type": "text" + } + } }, - "synthetics-monitor": { + "risk-engine-configuration": { "dynamic": false, "properties": { - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256, - "normalizer": "lowercase" - } - } - }, - "type": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "urls": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "hosts": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "journey_id": { - "type": "keyword" - }, - "project_id": { - "type": "keyword", - "fields": { - "text": { - "type": "text" - } - } - }, - "origin": { - "type": "keyword" - }, - "hash": { - "type": "keyword" - }, - "locations": { - "properties": { - "id": { - "type": "keyword", - "ignore_above": 256, - "fields": { - "text": { - "type": "text" - } - } - }, - "label": { - "type": "text" - } - } - }, - "custom_heartbeat_id": { + "dataViewId": { "type": "keyword" }, - "id": { - "type": "keyword" + "enabled": { + "type": "boolean" }, - "tags": { - "type": "keyword", - "fields": { - "text": { - "type": "text" - } - } + "filter": { + "dynamic": false, + "properties": {} }, - "schedule": { - "properties": { - "number": { - "type": "integer" - } - } + "identifierType": { + "type": "keyword" }, - "enabled": { - "type": "boolean" + "interval": { + "type": "keyword" }, - "alert": { - "properties": { - "status": { - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "tls": { - "properties": { - "enabled": { - "type": "boolean" - } - } - } - } + "pageSize": { + "type": "integer" }, - "throttling": { + "range": { "properties": { - "label": { + "end": { + "type": "keyword" + }, + "start": { "type": "keyword" } } } } }, - "uptime-synthetics-api-key": { + "rules-settings": { "dynamic": false, "properties": { - "apiKey": { - "type": "binary" + "flapping": { + "properties": {} } } }, - "synthetics-param": { - "dynamic": false, - "properties": {} - }, - "infrastructure-ui-source": { - "dynamic": false, - "properties": {} - }, - "inventory-view": { - "dynamic": false, - "properties": {} - }, - "metrics-explorer-view": { - "dynamic": false, - "properties": {} - }, - "upgrade-assistant-reindex-operation": { - "dynamic": false, + "sample-data-telemetry": { "properties": { - "indexName": { - "type": "keyword" + "installCount": { + "type": "long" }, - "status": { - "type": "integer" + "unInstallCount": { + "type": "long" } } }, - "upgrade-assistant-ml-upgrade-operation": { + "search": { "dynamic": false, "properties": { - "snapshotId": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } + "description": { + "type": "text" + }, + "title": { + "type": "text" } } }, - "monitoring-telemetry": { + "search-session": { + "dynamic": false, "properties": { - "reportedClusterUuids": { + "created": { + "type": "date" + }, + "realmName": { + "type": "keyword" + }, + "realmType": { + "type": "keyword" + }, + "sessionId": { + "type": "keyword" + }, + "username": { "type": "keyword" } } }, - "enterprise_search_telemetry": { - "dynamic": false, - "properties": {} - }, - "app_search_telemetry": { + "search-telemetry": { "dynamic": false, "properties": {} }, - "workplace_search_telemetry": { + "security-rule": { "dynamic": false, - "properties": {} - }, - "siem-ui-timeline-note": { "properties": { - "eventId": { + "rule_id": { "type": "keyword" }, - "note": { - "type": "text" - }, - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" + "version": { + "type": "long" } } }, - "siem-ui-timeline-pinned-event": { + "security-solution-signals-migration": { + "dynamic": false, "properties": { - "eventId": { + "sourceIndex": { "type": "keyword" }, - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, "updated": { "type": "date" }, - "updatedBy": { - "type": "text" + "version": { + "type": "long" } } }, "siem-detection-engine-rule-actions": { "properties": { - "alertThrottle": { - "type": "keyword" - }, - "ruleAlertId": { - "type": "keyword" - }, - "ruleThrottle": { - "type": "keyword" - }, "actions": { "properties": { "actionRef": { "type": "keyword" }, - "group": { + "action_type_id": { "type": "keyword" }, - "id": { + "group": { "type": "keyword" }, - "action_type_id": { + "id": { "type": "keyword" }, "params": { @@ -2805,17 +2539,15 @@ "properties": {} } } - } - } - }, - "security-rule": { - "dynamic": false, - "properties": { - "rule_id": { + }, + "alertThrottle": { "type": "keyword" }, - "version": { - "type": "long" + "ruleAlertId": { + "type": "keyword" + }, + "ruleThrottle": { + "type": "keyword" } } }, @@ -2838,10 +2570,10 @@ "example": { "type": "text" }, - "indexes": { + "id": { "type": "keyword" }, - "id": { + "indexes": { "type": "keyword" }, "name": { @@ -2858,13 +2590,54 @@ } } }, + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, "dataProviders": { "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "text" + "and": { + "properties": { + "enabled": { + "type": "boolean" + }, + "excluded": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "kqlQuery": { + "type": "text" + }, + "name": { + "type": "text" + }, + "queryMatch": { + "properties": { + "displayField": { + "type": "text" + }, + "displayValue": { + "type": "text" + }, + "field": { + "type": "text" + }, + "operator": { + "type": "text" + }, + "value": { + "type": "text" + } + } + }, + "type": { + "type": "text" + } + } }, "enabled": { "type": "boolean" @@ -2872,71 +2645,46 @@ "excluded": { "type": "boolean" }, + "id": { + "type": "keyword" + }, "kqlQuery": { "type": "text" }, - "type": { + "name": { "type": "text" }, "queryMatch": { "properties": { - "field": { - "type": "text" - }, "displayField": { "type": "text" }, - "value": { - "type": "text" - }, "displayValue": { "type": "text" }, - "operator": { - "type": "text" - } - } - }, - "and": { - "properties": { - "id": { - "type": "keyword" - }, - "name": { + "field": { "type": "text" }, - "enabled": { - "type": "boolean" - }, - "excluded": { - "type": "boolean" - }, - "kqlQuery": { + "operator": { "type": "text" }, - "type": { + "value": { "type": "text" - }, - "queryMatch": { - "properties": { - "field": { - "type": "text" - }, - "displayField": { - "type": "text" - }, - "value": { - "type": "text" - }, - "displayValue": { - "type": "text" - }, - "operator": { - "type": "text" - } - } } } + }, + "type": { + "type": "text" + } + } + }, + "dateRange": { + "properties": { + "end": { + "type": "date" + }, + "start": { + "type": "date" } } }, @@ -2948,16 +2696,16 @@ "eventCategoryField": { "type": "text" }, - "tiebreakerField": { + "query": { "type": "text" }, - "timestampField": { + "size": { "type": "text" }, - "query": { + "tiebreakerField": { "type": "text" }, - "size": { + "timestampField": { "type": "text" } } @@ -2970,22 +2718,28 @@ }, "favorite": { "properties": { - "keySearch": { - "type": "text" + "favoriteDate": { + "type": "date" }, "fullName": { "type": "text" }, - "userName": { + "keySearch": { "type": "text" }, - "favoriteDate": { - "type": "date" + "userName": { + "type": "text" } } }, "filters": { "properties": { + "exists": { + "type": "text" + }, + "match_all": { + "type": "text" + }, "meta": { "properties": { "alias": { @@ -3015,23 +2769,17 @@ "params": { "type": "text" }, + "relation": { + "type": "keyword" + }, "type": { "type": "keyword" }, "value": { "type": "text" - }, - "relation": { - "type": "keyword" } } }, - "exists": { - "type": "text" - }, - "match_all": { - "type": "text" - }, "missing": { "type": "text" }, @@ -3058,186 +2806,438 @@ "properties": { "kuery": { "properties": { - "kind": { - "type": "keyword" - }, "expression": { "type": "text" + }, + "kind": { + "type": "keyword" } } }, "serializedQuery": { "type": "text" } - } + } + } + } + }, + "savedSearchId": { + "type": "text" + }, + "sort": { + "dynamic": false, + "properties": { + "columnId": { + "type": "keyword" + }, + "columnType": { + "type": "keyword" + }, + "sortDirection": { + "type": "keyword" + } + } + }, + "status": { + "type": "keyword" + }, + "templateTimelineId": { + "type": "text" + }, + "templateTimelineVersion": { + "type": "integer" + }, + "timelineType": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "siem-ui-timeline-note": { + "properties": { + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, + "eventId": { + "type": "keyword" + }, + "note": { + "type": "text" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "siem-ui-timeline-pinned-event": { + "properties": { + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, + "eventId": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "slo": { + "dynamic": false, + "properties": { + "budgetingMethod": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "indicator": { + "properties": { + "params": { + "type": "flattened" + }, + "type": { + "type": "keyword" + } + } + }, + "name": { + "type": "text" + }, + "tags": { + "type": "keyword" + }, + "version": { + "type": "long" + } + } + }, + "space": { + "dynamic": false, + "properties": { + "name": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "spaces-usage-stats": { + "dynamic": false, + "properties": {} + }, + "synthetics-monitor": { + "dynamic": false, + "properties": { + "alert": { + "properties": { + "status": { + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "tls": { + "properties": { + "enabled": { + "type": "boolean" + } + } + } + } + }, + "custom_heartbeat_id": { + "type": "keyword" + }, + "enabled": { + "type": "boolean" + }, + "hash": { + "type": "keyword" + }, + "hosts": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "type": "keyword" + }, + "journey_id": { + "type": "keyword" + }, + "locations": { + "properties": { + "id": { + "fields": { + "text": { + "type": "text" + } + }, + "ignore_above": 256, + "type": "keyword" + }, + "label": { + "type": "text" } } }, - "title": { - "type": "text" - }, - "templateTimelineId": { + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "normalizer": "lowercase", + "type": "keyword" + } + }, "type": "text" }, - "templateTimelineVersion": { - "type": "integer" + "origin": { + "type": "keyword" }, - "timelineType": { + "project_id": { + "fields": { + "text": { + "type": "text" + } + }, "type": "keyword" }, - "dateRange": { + "schedule": { "properties": { - "start": { - "type": "date" - }, - "end": { - "type": "date" + "number": { + "type": "integer" } } }, - "sort": { - "dynamic": false, + "tags": { + "fields": { + "text": { + "type": "text" + } + }, + "type": "keyword" + }, + "throttling": { "properties": { - "columnId": { - "type": "keyword" - }, - "columnType": { - "type": "keyword" - }, - "sortDirection": { + "label": { "type": "keyword" } } }, - "status": { - "type": "keyword" - }, - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "updated": { - "type": "date" - }, - "updatedBy": { + "type": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, "type": "text" }, - "savedSearchId": { + "urls": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, "type": "text" } } }, - "endpoint:user-artifact-manifest": { + "synthetics-param": { "dynamic": false, - "properties": { - "schemaVersion": { - "type": "keyword" - }, - "artifacts": { - "type": "nested" - } - } + "properties": {} }, - "security-solution-signals-migration": { + "synthetics-privates-locations": { "dynamic": false, + "properties": {} + }, + "tag": { "properties": { - "sourceIndex": { - "type": "keyword" + "color": { + "type": "text" }, - "updated": { - "type": "date" + "description": { + "type": "text" }, - "version": { - "type": "long" + "name": { + "type": "text" } } }, - "risk-engine-configuration": { + "task": { "dynamic": false, "properties": { - "dataViewId": { - "type": "keyword" + "attempts": { + "type": "integer" }, "enabled": { "type": "boolean" }, - "filter": { - "dynamic": false, - "properties": {} - }, - "identifierType": { + "ownerId": { "type": "keyword" }, - "interval": { - "type": "keyword" + "retryAt": { + "type": "date" }, - "pageSize": { - "type": "integer" + "runAt": { + "type": "date" }, - "range": { + "schedule": { "properties": { - "start": { - "type": "keyword" - }, - "end": { + "interval": { "type": "keyword" } } + }, + "scheduledAt": { + "type": "date" + }, + "scope": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "taskType": { + "type": "keyword" } } }, - "policy-settings-protection-updates-note": { + "telemetry": { + "dynamic": false, + "properties": {} + }, + "threshold-explorer-view": { + "dynamic": false, + "properties": {} + }, + "ui-metric": { "properties": { - "note": { - "type": "text", - "index": false + "count": { + "type": "integer" } } }, - "apm-telemetry": { + "upgrade-assistant-ml-upgrade-operation": { "dynamic": false, - "properties": {} - }, - "apm-server-schema": { "properties": { - "schemaJson": { - "type": "text", - "index": false + "snapshotId": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" } } }, - "apm-service-group": { + "upgrade-assistant-reindex-operation": { + "dynamic": false, "properties": { - "groupName": { + "indexName": { "type": "keyword" }, - "kuery": { - "type": "text" + "status": { + "type": "integer" + } + } + }, + "uptime-dynamic-settings": { + "dynamic": false, + "properties": {} + }, + "uptime-synthetics-api-key": { + "dynamic": false, + "properties": { + "apiKey": { + "type": "binary" + } + } + }, + "url": { + "dynamic": false, + "properties": { + "accessDate": { + "type": "date" }, - "description": { - "type": "text" + "createDate": { + "type": "date" }, - "color": { + "slug": { + "fields": { + "keyword": { + "type": "keyword" + } + }, "type": "text" } } }, - "apm-custom-dashboards": { + "usage-counters": { + "dynamic": false, "properties": { - "dashboardSavedObjectId": { + "domainId": { "type": "keyword" - }, - "kuery": { + } + } + }, + "visualization": { + "dynamic": false, + "properties": { + "description": { "type": "text" }, - "serviceEnvironmentFilterEnabled": { - "type": "boolean" + "kibanaSavedObjectMeta": { + "properties": {} }, - "serviceNameFilterEnabled": { - "type": "boolean" + "title": { + "type": "text" + }, + "version": { + "type": "integer" } } + }, + "workplace_search_telemetry": { + "dynamic": false, + "properties": {} } } diff --git a/packages/kbn-check-mappings-update-cli/src/compatibility/current_mappings.ts b/packages/kbn-check-mappings-update-cli/src/compatibility/current_mappings.ts index 5632f3c479d18..30ff02a624a7f 100644 --- a/packages/kbn-check-mappings-update-cli/src/compatibility/current_mappings.ts +++ b/packages/kbn-check-mappings-update-cli/src/compatibility/current_mappings.ts @@ -10,13 +10,14 @@ import Fsp from 'fs/promises'; import Path from 'path'; import type { SavedObjectsTypeMappingDefinitions } from '@kbn/core-saved-objects-base-server-internal'; +import { prettyPrintAndSortKeys } from '@kbn/utils'; -export const CURRENT_MAPPINGS_FILE = Path.resolve(__dirname, '../../current_mappings.json'); +export const CURRENT_MAPPINGS_FILE_PATH = Path.resolve(__dirname, '../../current_mappings.json'); export async function readCurrentMappings(): Promise { let currentMappingsJson; try { - currentMappingsJson = await Fsp.readFile(CURRENT_MAPPINGS_FILE, 'utf8'); + currentMappingsJson = await Fsp.readFile(CURRENT_MAPPINGS_FILE_PATH, 'utf8'); } catch (error) { if (error.code === 'ENOENT') { return {}; @@ -28,6 +29,10 @@ export async function readCurrentMappings(): Promise => { }; export const writeCurrentFields = async (fieldMap: FieldListMap) => { - await writeFile(CURRENT_FIELDS_FILE_PATH, JSON.stringify(fieldMap, null, 2) + '\n', 'utf-8'); + await writeFile(CURRENT_FIELDS_FILE_PATH, prettyPrintAndSortKeys(fieldMap) + '\n', 'utf-8'); }; diff --git a/packages/kbn-check-mappings-update-cli/tsconfig.json b/packages/kbn-check-mappings-update-cli/tsconfig.json index 48973be21d219..b8ae7bad89ebc 100644 --- a/packages/kbn-check-mappings-update-cli/tsconfig.json +++ b/packages/kbn-check-mappings-update-cli/tsconfig.json @@ -28,5 +28,6 @@ "@kbn/safer-lodash-set", "@kbn/tooling-log", "@kbn/core-saved-objects-server", + "@kbn/utils", ] } diff --git a/packages/kbn-utils/index.ts b/packages/kbn-utils/index.ts index d23c71fad55bc..492f6d321ef0e 100644 --- a/packages/kbn-utils/index.ts +++ b/packages/kbn-utils/index.ts @@ -5,6 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - +export * from './src/json'; export * from './src/path'; export * from './src/streams'; diff --git a/packages/kbn-utils/src/json/index.test.ts b/packages/kbn-utils/src/json/index.test.ts new file mode 100644 index 0000000000000..d8a81883e3826 --- /dev/null +++ b/packages/kbn-utils/src/json/index.test.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { prettyPrintAndSortKeys } from '.'; + +describe('prettyPrintAndSortKeys', () => { + it('pretty prints JSON and consistently sorts the keys', () => { + const object1 = { + zap: { z: 1, b: 2 }, + foo: 'foo', + bar: 'bar', + }; + const object2 = { + foo: 'foo', + zap: { z: 1, b: 2 }, + bar: 'bar', + }; + expect(prettyPrintAndSortKeys(object1)).toMatchInlineSnapshot(` + "{ + \\"bar\\": \\"bar\\", + \\"foo\\": \\"foo\\", + \\"zap\\": { + \\"b\\": 2, + \\"z\\": 1 + } + }" + `); + + expect(prettyPrintAndSortKeys(object1)).toEqual(prettyPrintAndSortKeys(object2)); + }); + + it('pretty prints and sorts nested objects with arrays', () => { + const object = { + zap: { + a: { + b: 1, + a: 2, + }, + }, + foo: 'foo', + bar: 'bar', + baz: [ + { + c: 2, + b: 1, + }, + { + c: { + b: 1, + a: 2, + }, + }, + ], + }; + expect(prettyPrintAndSortKeys(object)).toMatchInlineSnapshot(` + "{ + \\"bar\\": \\"bar\\", + \\"baz\\": [ + { + \\"b\\": 1, + \\"c\\": 2 + }, + { + \\"c\\": { + \\"a\\": 2, + \\"b\\": 1 + } + } + ], + \\"foo\\": \\"foo\\", + \\"zap\\": { + \\"a\\": { + \\"a\\": 2, + \\"b\\": 1 + } + } + }" + `); + }); +}); diff --git a/packages/kbn-utils/src/json/index.ts b/packages/kbn-utils/src/json/index.ts new file mode 100644 index 0000000000000..7a8afd42283ae --- /dev/null +++ b/packages/kbn-utils/src/json/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Given a JS object, will return a JSON.stringified result with consistently + * sorted keys. + */ +export function prettyPrintAndSortKeys(object: object): string { + const keys = new Set(); + JSON.stringify(object, (key, value) => { + keys.add(key); + return value; + }); + return JSON.stringify(object, Array.from(keys).sort(), 2); +} From 95ef111e10a58741cb2e52e804034d1685bf033e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:21:52 +0000 Subject: [PATCH 031/104] [APM] Hide Table search on Service Inventory (#176504) Hide the Table search on the Service Inventory page and enable the feature by default. Screenshot 2024-02-08 at 13 22 06 Screenshot 2024-02-08 at 13 22 13 Screenshot 2024-02-08 at 13 22 20 --- .../cypress/e2e/service_inventory/service_inventory.cy.ts | 3 ++- .../components/app/service_inventory/service_list/index.tsx | 1 + .../apm/public/components/shared/managed_table/index.tsx | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_inventory/service_inventory.cy.ts b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_inventory/service_inventory.cy.ts index c0c3c032a0e61..5c50e79c145aa 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_inventory/service_inventory.cy.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_inventory/service_inventory.cy.ts @@ -115,7 +115,8 @@ describe('Service inventory', () => { }); }); - describe('Table search', () => { + // Skipping this until we enable the table search on the Service inventory view + describe.skip('Table search', () => { beforeEach(() => { cy.updateAdvancedSettings({ 'observability:apmEnableTableSearchBar': true, diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx index 08e7a840b5dfb..ba55defaaf4d7 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx @@ -357,6 +357,7 @@ export function ServiceList({ const tableSearchBar: TableSearchBar = useMemo(() => { return { + isEnabled: false, fieldsToSearch: ['serviceName'], maxCountExceeded, onChangeSearchQuery, diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx index 7d6307d32ffb8..ae14f63f8d72b 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx @@ -111,7 +111,7 @@ function UnoptimizedManagedTable(props: { const { core } = useApmPluginContext(); const isTableSearchBarEnabled = core.uiSettings.get( apmEnableTableSearchBar, - false + true ); const { From 5aa66564da5ff7af33107e2b6e5ca81665b51d30 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 16:26:53 +0000 Subject: [PATCH 032/104] skip flaky suite (#163263) --- x-pack/plugins/cases/public/components/app/routes.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/app/routes.test.tsx b/x-pack/plugins/cases/public/components/app/routes.test.tsx index 9c435e2b163ba..1127eb059fc8b 100644 --- a/x-pack/plugins/cases/public/components/app/routes.test.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.test.tsx @@ -60,7 +60,8 @@ describe('Cases routes', () => { }); }); - describe('Case view', () => { + // FLAKY: https://github.com/elastic/kibana/issues/163263 + describe.skip('Case view', () => { it.each(getCaseViewPaths())( 'navigates to the cases view page for path: %s', async (path: string) => { From fc58a0d3a71dd946fb24a75050930030c002d2a4 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Thu, 8 Feb 2024 17:27:24 +0100 Subject: [PATCH 033/104] [Obs AI Assistant] Improve recall speed (#176428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves recall speed by outputting as CSV with zero-indexed document "ids". Previously, it was a JSON object, with the real document ids. This causes the LLM to "think" for longer, for whatever reason. I didn't actually see a difference in completion speed, but emitting the first value took significantly less time when using the CSV output. I also tried sending a single document per request using the old format, and while that certainly improves things, the slowest request becomes the bottleneck. These are results from about 10 tries per strategy (I'd love to see others reproduce at least the `batch` vs `csv` strategy results): `batch`: 24.7s `chunk`: 10s `csv`: 4.9s --------- Co-authored-by: Søren Louv-Jansen Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/functions/recall.ts | 106 ++++++++---------- .../server/service/client/index.ts | 62 +++++++--- 2 files changed, 91 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts index ee0fae1f91ed1..909a823286cc6 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts @@ -9,7 +9,7 @@ import { decodeOrThrow, jsonRt } from '@kbn/io-ts-utils'; import type { Serializable } from '@kbn/utility-types'; import dedent from 'dedent'; import * as t from 'io-ts'; -import { last, omit } from 'lodash'; +import { compact, last, omit } from 'lodash'; import { lastValueFrom } from 'rxjs'; import { FunctionRegistrationParameters } from '.'; import { MessageRole, type Message } from '../../common/types'; @@ -88,12 +88,17 @@ export function registerRecallFunction({ messages.filter((message) => message.message.role === MessageRole.User) ); + const nonEmptyQueries = compact(queries); + + const queriesOrUserPrompt = nonEmptyQueries.length + ? nonEmptyQueries + : compact([userMessage?.message.content]); + const suggestions = await retrieveSuggestions({ userMessage, client, - signal, categories, - queries, + queries: queriesOrUserPrompt, }); if (suggestions.length === 0) { @@ -104,9 +109,8 @@ export function registerRecallFunction({ const relevantDocuments = await scoreSuggestions({ suggestions, - systemMessage, - userMessage, - queries, + queries: queriesOrUserPrompt, + messages, client, connectorId, signal, @@ -121,25 +125,17 @@ export function registerRecallFunction({ } async function retrieveSuggestions({ - userMessage, queries, client, categories, - signal, }: { userMessage?: Message; queries: string[]; client: ObservabilityAIAssistantClient; categories: Array<'apm' | 'lens'>; - signal: AbortSignal; }) { - const queriesWithUserPrompt = - userMessage && userMessage.message.content - ? [userMessage.message.content, ...queries] - : queries; - const recallResponse = await client.recall({ - queries: queriesWithUserPrompt, + queries, categories, }); @@ -156,18 +152,12 @@ const scoreFunctionRequestRt = t.type({ }); const scoreFunctionArgumentsRt = t.type({ - scores: t.array( - t.type({ - id: t.string, - score: t.number, - }) - ), + scores: t.string, }); async function scoreSuggestions({ suggestions, - systemMessage, - userMessage, + messages, queries, client, connectorId, @@ -175,35 +165,31 @@ async function scoreSuggestions({ resources, }: { suggestions: Awaited>; - systemMessage: Message; - userMessage?: Message; + messages: Message[]; queries: string[]; client: ObservabilityAIAssistantClient; connectorId: string; signal: AbortSignal; resources: RespondFunctionResources; }) { - resources.logger.debug(`Suggestions: ${JSON.stringify(suggestions, null, 2)}`); + const indexedSuggestions = suggestions.map((suggestion, index) => ({ ...suggestion, id: index })); - const systemMessageExtension = - dedent(`You have the function called score available to help you inform the user about how relevant you think a given document is to the conversation. - Please give a score between 1 and 7, fractions are allowed. - A higher score means it is more relevant.`); - const extendedSystemMessage = { - ...systemMessage, - message: { - ...systemMessage.message, - content: `${systemMessage.message.content}\n\n${systemMessageExtension}`, - }, - }; + const newUserMessageContent = + dedent(`Given the following question, score the documents that are relevant to the question. on a scale from 0 to 7, + 0 being completely relevant, and 7 being extremely relevant. Information is relevant to the question if it helps in + answering the question. Judge it according to the following criteria: - const userMessageOrQueries = - userMessage && userMessage.message.content ? userMessage.message.content : queries.join(','); + - The document is relevant to the question, and the rest of the conversation + - The document has information relevant to the question that is not mentioned, + or more detailed than what is available in the conversation + - The document has a high amount of information relevant to the question compared to other documents + - The document contains new information not mentioned before in the conversation - const newUserMessageContent = - dedent(`Given the question "${userMessageOrQueries}", can you give me a score for how relevant the following documents are? + Question: + ${queries.join('\n')} - ${JSON.stringify(suggestions, null, 2)}`); + Documents: + ${JSON.stringify(indexedSuggestions, null, 2)}`); const newUserMessage: Message = { '@timestamp': new Date().toISOString(), @@ -222,22 +208,13 @@ async function scoreSuggestions({ additionalProperties: false, properties: { scores: { - description: 'The document IDs and their scores', - type: 'array', - items: { - type: 'object', - additionalProperties: false, - properties: { - id: { - description: 'The ID of the document', - type: 'string', - }, - score: { - description: 'The score for the document', - type: 'number', - }, - }, - }, + description: `The document IDs and their scores, as CSV. Example: + + my_id,7 + my_other_id,3 + my_third_id,4 + `, + type: 'string', }, }, required: ['score'], @@ -249,7 +226,7 @@ async function scoreSuggestions({ ( await client.chat('score_suggestions', { connectorId, - messages: [extendedSystemMessage, newUserMessage], + messages: [...messages.slice(0, -1), newUserMessage], functions: [scoreFunction], functionCall: 'score', signal, @@ -257,11 +234,18 @@ async function scoreSuggestions({ ).pipe(concatenateChatCompletionChunks()) ); const scoreFunctionRequest = decodeOrThrow(scoreFunctionRequestRt)(response); - const { scores } = decodeOrThrow(jsonRt.pipe(scoreFunctionArgumentsRt))( + const { scores: scoresAsString } = decodeOrThrow(jsonRt.pipe(scoreFunctionArgumentsRt))( scoreFunctionRequest.message.function_call.arguments ); - resources.logger.debug(`Scores: ${JSON.stringify(scores, null, 2)}`); + const scores = scoresAsString.split('\n').map((line) => { + const [index, score] = line + .split(',') + .map((value) => value.trim()) + .map(Number); + + return { id: suggestions[index].id, score }; + }); if (scores.length === 0) { return []; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index f3ab3e917979b..afd34aa8ea966 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -14,7 +14,15 @@ import apm from 'elastic-apm-node'; import { decode, encode } from 'gpt-tokenizer'; import { compact, isEmpty, last, merge, noop, omit, pick, take } from 'lodash'; import type OpenAI from 'openai'; -import { filter, isObservable, lastValueFrom, Observable, shareReplay, toArray } from 'rxjs'; +import { + filter, + firstValueFrom, + isObservable, + lastValueFrom, + Observable, + shareReplay, + toArray, +} from 'rxjs'; import { Readable } from 'stream'; import { v4 } from 'uuid'; import { @@ -455,6 +463,8 @@ export class ObservabilityAIAssistantClient { ): Promise> => { const span = apm.startSpan(`chat ${name}`); + const spanId = (span?.ids['span.id'] || '').substring(0, 6); + const messagesForOpenAI: Array< Omit & { role: MessageRole; @@ -490,6 +500,8 @@ export class ObservabilityAIAssistantClient { this.dependencies.logger.debug(`Sending conversation to connector`); this.dependencies.logger.trace(JSON.stringify(request, null, 2)); + const now = performance.now(); + const executeResult = await this.dependencies.actionsClient.execute({ actionId: connectorId, params: { @@ -501,7 +513,11 @@ export class ObservabilityAIAssistantClient { }, }); - this.dependencies.logger.debug(`Received action client response: ${executeResult.status}`); + this.dependencies.logger.debug( + `Received action client response: ${executeResult.status} (took: ${Math.round( + performance.now() - now + )}ms)${spanId ? ` (${spanId})` : ''}` + ); if (executeResult.status === 'error' && executeResult?.serviceMessage) { const tokenLimitRegex = @@ -524,20 +540,34 @@ export class ObservabilityAIAssistantClient { const observable = streamIntoObservable(response).pipe(processOpenAiStream(), shareReplay()); - if (span) { - lastValueFrom(observable) - .then( - () => { - span.setOutcome('success'); - }, - () => { - span.setOutcome('failure'); - } - ) - .finally(() => { - span.end(); - }); - } + firstValueFrom(observable) + .catch(noop) + .finally(() => { + this.dependencies.logger.debug( + `Received first value after ${Math.round(performance.now() - now)}ms${ + spanId ? ` (${spanId})` : '' + }` + ); + }); + + lastValueFrom(observable) + .then( + () => { + span?.setOutcome('success'); + }, + () => { + span?.setOutcome('failure'); + } + ) + .finally(() => { + this.dependencies.logger.debug( + `Completed response in ${Math.round(performance.now() - now)}ms${ + spanId ? ` (${spanId})` : '' + }` + ); + + span?.end(); + }); return observable; }; From 03b57332b88a61926855af09e84cf82519782e6c Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 16:28:24 +0000 Subject: [PATCH 034/104] skip flaky suite (#175229) --- x-pack/plugins/cases/public/components/app/routes.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/app/routes.test.tsx b/x-pack/plugins/cases/public/components/app/routes.test.tsx index 1127eb059fc8b..71eeb495a1d8a 100644 --- a/x-pack/plugins/cases/public/components/app/routes.test.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.test.tsx @@ -85,7 +85,8 @@ describe('Cases routes', () => { ); }); - describe('Create case', () => { + // FLAKY: https://github.com/elastic/kibana/issues/175229 + describe.skip('Create case', () => { it('navigates to the create case page', () => { renderWithRouter(['/cases/create']); expect(screen.getByText('Create case')).toBeInTheDocument(); From a81a8cacdba972408cec14824fc9f1163489d19d Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 16:28:49 +0000 Subject: [PATCH 035/104] skip flaky suite (#175230) --- x-pack/plugins/cases/public/components/app/routes.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/cases/public/components/app/routes.test.tsx b/x-pack/plugins/cases/public/components/app/routes.test.tsx index 71eeb495a1d8a..4b94821d83bd3 100644 --- a/x-pack/plugins/cases/public/components/app/routes.test.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.test.tsx @@ -86,6 +86,7 @@ describe('Cases routes', () => { }); // FLAKY: https://github.com/elastic/kibana/issues/175229 + // FLAKY: https://github.com/elastic/kibana/issues/175230 describe.skip('Create case', () => { it('navigates to the create case page', () => { renderWithRouter(['/cases/create']); From 3ff578287919b731265090a8b9e68d5b8d883cf7 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 16:29:14 +0000 Subject: [PATCH 036/104] skip flaky suite (#175231) --- x-pack/plugins/cases/public/components/app/routes.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/app/routes.test.tsx b/x-pack/plugins/cases/public/components/app/routes.test.tsx index 4b94821d83bd3..0f51642670031 100644 --- a/x-pack/plugins/cases/public/components/app/routes.test.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.test.tsx @@ -99,7 +99,8 @@ describe('Cases routes', () => { }); }); - describe('Cases settings', () => { + // FLAKY: https://github.com/elastic/kibana/issues/175231 + describe.skip('Cases settings', () => { it('navigates to the cases settings page', () => { renderWithRouter(['/cases/configure']); expect(screen.getByText('Settings')).toBeInTheDocument(); From 6a9e18e131e8deb2b413068f1cafa947dc19cd1b Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 16:29:36 +0000 Subject: [PATCH 037/104] skip flaky suite (#175232) --- x-pack/plugins/cases/public/components/app/routes.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/cases/public/components/app/routes.test.tsx b/x-pack/plugins/cases/public/components/app/routes.test.tsx index 0f51642670031..91b4b1ef5227f 100644 --- a/x-pack/plugins/cases/public/components/app/routes.test.tsx +++ b/x-pack/plugins/cases/public/components/app/routes.test.tsx @@ -100,6 +100,7 @@ describe('Cases routes', () => { }); // FLAKY: https://github.com/elastic/kibana/issues/175231 + // FLAKY: https://github.com/elastic/kibana/issues/175232 describe.skip('Cases settings', () => { it('navigates to the cases settings page', () => { renderWithRouter(['/cases/configure']); From df273cd23e1ed78170b44d37418fbe65c2ce80d5 Mon Sep 17 00:00:00 2001 From: Ash <1849116+ashokaditya@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:49:55 +0100 Subject: [PATCH 038/104] [Security Solution][Endpoint] Gate responder action item for sentinel one alert with feature flag (#176405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Shows responder action item enabled for SentinelOne alerts if feature flag is enabled. **with `responseActionsSentinelOneV1Enabled` enabled** Screenshot 2024-02-08 at 9 21 54 AM Follow up of elastic/kibana/pull/173927 ### 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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --- .../use_responder_action_data.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts index 62772fa029e66..cfa004b7ce6b2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts +++ b/x-pack/plugins/security_solution/public/detections/components/endpoint_responder/use_responder_action_data.ts @@ -7,6 +7,7 @@ import type { ReactNode } from 'react'; import { useCallback, useMemo } from 'react'; import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { getSentinelOneAgentId } from '../../../common/utils/sentinelone_alert_check'; import type { ThirdPartyAgentInfo } from '../../../../common/types'; import type { ResponseActionAgentType } from '../../../../common/endpoint/service/response_actions/constants'; @@ -74,17 +75,22 @@ export const useResponderActionData = ({ tooltip: ReactNode; } => { const isEndpointHost = agentType === 'endpoint'; + const isSentinelOneHost = agentType === 'sentinel_one'; const showResponseActionsConsole = useWithShowResponder(); + const isSentinelOneV1Enabled = useIsExperimentalFeatureEnabled( + 'responseActionsSentinelOneV1Enabled' + ); const { data: hostInfo, isFetching, error, - } = useGetEndpointDetails(endpointId, { enabled: Boolean(endpointId) }); + } = useGetEndpointDetails(endpointId, { enabled: Boolean(endpointId && isEndpointHost) }); const [isDisabled, tooltip]: [disabled: boolean, tooltip: ReactNode] = useMemo(() => { + // v8.13 disabled for third-party agent alerts if the feature flag is not enabled if (!isEndpointHost) { - return [false, undefined]; + return [isSentinelOneHost ? !isSentinelOneV1Enabled : true, undefined]; } // Still loading host info @@ -114,7 +120,14 @@ export const useResponderActionData = ({ } return [false, undefined]; - }, [isEndpointHost, isFetching, error, hostInfo?.host_status]); + }, [ + isEndpointHost, + isSentinelOneHost, + isSentinelOneV1Enabled, + isFetching, + error, + hostInfo?.host_status, + ]); const handleResponseActionsClick = useCallback(() => { if (!isEndpointHost) { From 3cde1a5613cb862190022f338a211dc23c3f612a Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Fri, 9 Feb 2024 03:38:44 +1030 Subject: [PATCH 039/104] [main] Sync bundled packages with Package Storage (#176510) Automated by https://buildkite.com/elastic/package-storage-infra-kibana-discover-release-branches/builds/337 --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index 836e65d0e95aa..bfde442c20d22 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -56,6 +56,6 @@ }, { "name": "security_detection_engine", - "version": "8.12.3" + "version": "8.12.4" } ] \ No newline at end of file From b9ce46958255c17954f29fbb8cfefc65a7078407 Mon Sep 17 00:00:00 2001 From: acrewdson Date: Thu, 8 Feb 2024 09:37:24 -0800 Subject: [PATCH 040/104] [Search] Use more normative default ports for Postgres and MS SQL Server (#176020) ## Summary Related connectors issue: https://github.com/elastic/connectors/issues/1824 ------ We should use more normative default ports in the connectors UI for Postgres and MS SQL Server. See: * https://www.postgresql.org/docs/current/app-postgres.html * https://learn.microsoft.com/en-us/sql/sql-server/install/configure-the-windows-firewall-to-allow-sql-server-access?view=sql-server-ver16#ports-used-by-the-database-engine ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) Co-authored-by: Ioana Tagirta --- packages/kbn-search-connectors/types/native_connectors.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kbn-search-connectors/types/native_connectors.ts b/packages/kbn-search-connectors/types/native_connectors.ts index 62ac7445e8b06..849e669c4a810 100644 --- a/packages/kbn-search-connectors/types/native_connectors.ts +++ b/packages/kbn-search-connectors/types/native_connectors.ts @@ -1793,7 +1793,7 @@ export const NATIVE_CONNECTOR_DEFINITIONS: Record Date: Thu, 8 Feb 2024 18:39:01 +0100 Subject: [PATCH 041/104] [ES|QL] Canceling the async query from the Lens inline editing flyout (#176277) ## Summary adds support for canceling queries in lens side editor ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [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)) --------- Co-authored-by: Stratoula Kalafateli --- .../src/editor_footer.tsx | 16 +++-- .../src/fetch_fields_from_esql.ts | 11 +++- packages/kbn-text-based-editor/src/helpers.ts | 11 ++++ .../src/text_based_languages_editor.tsx | 64 +++++++++++++++---- .../query_string_input/query_bar_top_row.tsx | 2 +- .../index_data_visualizer_esql.tsx | 2 +- .../shared/edit_on_the_fly/helpers.ts | 18 ++++-- .../lens_configuration_flyout.tsx | 11 ++-- .../expression/esql_query_expression.tsx | 3 +- 9 files changed, 107 insertions(+), 31 deletions(-) diff --git a/packages/kbn-text-based-editor/src/editor_footer.tsx b/packages/kbn-text-based-editor/src/editor_footer.tsx index 351b7bbe251c1..210988ac94e42 100644 --- a/packages/kbn-text-based-editor/src/editor_footer.tsx +++ b/packages/kbn-text-based-editor/src/editor_footer.tsx @@ -201,6 +201,7 @@ interface EditorFooterProps { editorIsInline?: boolean; isSpaceReduced?: boolean; isLoading?: boolean; + allowQueryCancellation?: boolean; } export const EditorFooter = memo(function EditorFooter({ @@ -216,6 +217,7 @@ export const EditorFooter = memo(function EditorFooter({ editorIsInline, isSpaceReduced, isLoading, + allowQueryCancellation, }: EditorFooterProps) { const { euiTheme } = useEuiTheme(); const [isErrorPopoverOpen, setIsErrorPopoverOpen] = useState(false); @@ -333,8 +335,8 @@ export const EditorFooter = memo(function EditorFooter({ size="s" fill onClick={runQuery} - isLoading={isLoading} - isDisabled={Boolean(disableSubmitAction)} + isLoading={isLoading && !allowQueryCancellation} + isDisabled={Boolean(disableSubmitAction && !allowQueryCancellation)} data-test-subj="TextBasedLangEditor-run-query-button" minWidth={isSpaceReduced ? false : undefined} > @@ -345,7 +347,11 @@ export const EditorFooter = memo(function EditorFooter({ justifyContent="spaceBetween" > - {isSpaceReduced + {allowQueryCancellation && isLoading + ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.cancel', { + defaultMessage: 'Cancel', + }) + : isSpaceReduced ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.run', { defaultMessage: 'Run', }) @@ -361,7 +367,7 @@ export const EditorFooter = memo(function EditorFooter({ size="xs" css={css` border: 1px solid - ${Boolean(disableSubmitAction) + ${Boolean(disableSubmitAction && !allowQueryCancellation) ? euiTheme.colors.disabled : euiTheme.colors.emptyShade}; padding: 0 ${euiTheme.size.xs}; @@ -370,7 +376,7 @@ export const EditorFooter = memo(function EditorFooter({ border-radius: ${euiTheme.size.xs}; `} > - {COMMAND_KEY}⏎ + {allowQueryCancellation && isLoading ? 'X' : `${COMMAND_KEY}⏎`} diff --git a/packages/kbn-text-based-editor/src/fetch_fields_from_esql.ts b/packages/kbn-text-based-editor/src/fetch_fields_from_esql.ts index e1ef2a5d4a8b3..f1013f1a4b329 100644 --- a/packages/kbn-text-based-editor/src/fetch_fields_from_esql.ts +++ b/packages/kbn-text-based-editor/src/fetch_fields_from_esql.ts @@ -24,6 +24,7 @@ export function fetchFieldsFromESQL( query: Query | AggregateQuery, expressions: ExpressionsStart, time?: TimeRange, + abortController?: AbortController, dataView?: DataView ) { return textBasedQueryStateToAstWithValidation({ @@ -33,7 +34,15 @@ export function fetchFieldsFromESQL( }) .then((ast) => { if (ast) { - const execution = expressions.run(ast, null); + const executionContract = expressions.execute(ast, null); + + if (abortController) { + abortController.signal.onabort = () => { + executionContract.cancel(); + }; + } + + const execution = executionContract.getData(); let finalData: Datatable; let error: string | undefined; execution.pipe(pluck('result')).subscribe((resp) => { diff --git a/packages/kbn-text-based-editor/src/helpers.ts b/packages/kbn-text-based-editor/src/helpers.ts index 88df8ef6a75e4..dffddc9514449 100644 --- a/packages/kbn-text-based-editor/src/helpers.ts +++ b/packages/kbn-text-based-editor/src/helpers.ts @@ -116,6 +116,17 @@ export const parseErrors = (errors: Error[], code: string): MonacoMessage[] => { endLineNumber: Number(lineNumber), severity: monaco.MarkerSeverity.Error, }; + } else if (error.message.includes('expression was aborted')) { + return { + message: i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.aborted', { + defaultMessage: 'Request was aborted', + }), + startColumn: 1, + startLineNumber: 1, + endColumn: 10, + endLineNumber: 1, + severity: monaco.MarkerSeverity.Warning, + }; } else { // unknown error message return { diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 7bdfce427bc21..241679734e248 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -71,7 +71,10 @@ export interface TextBasedLanguagesEditorProps { /** Callback running everytime the query changes */ onTextLangQueryChange: (query: AggregateQuery) => void; /** Callback running when the user submits the query */ - onTextLangQuerySubmit: (query?: AggregateQuery) => void; + onTextLangQuerySubmit: ( + query?: AggregateQuery, + abortController?: AbortController + ) => Promise; /** Can be used to expand/minimize the editor */ expandCodeEditor: (status: boolean) => void; /** If it is true, the editor initializes with height EDITOR_INITIAL_HEIGHT_EXPANDED */ @@ -105,6 +108,9 @@ export interface TextBasedLanguagesEditorProps { editorIsInline?: boolean; /** Disables the submit query action*/ disableSubmitAction?: boolean; + + /** when set to true enables query cancellation **/ + allowQueryCancellation?: boolean; } interface TextBasedEditorDeps { @@ -158,6 +164,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ editorIsInline, disableSubmitAction, dataTestSubj, + allowQueryCancellation, }: TextBasedLanguagesEditorProps) { const { euiTheme } = useEuiTheme(); const language = getAggregateQueryMode(query); @@ -176,7 +183,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const [showLineNumbers, setShowLineNumbers] = useState(isCodeEditorExpanded); const [isCompactFocused, setIsCompactFocused] = useState(isCodeEditorExpanded); const [isCodeEditorExpandedFocused, setIsCodeEditorExpandedFocused] = useState(false); - + const [isQueryLoading, setIsQueryLoading] = useState(true); + const [abortController, setAbortController] = useState(new AbortController()); const [editorMessages, setEditorMessages] = useState<{ errors: MonacoMessage[]; warnings: MonacoMessage[]; @@ -186,12 +194,25 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ }); const onQuerySubmit = useCallback(() => { - const currentValue = editor1.current?.getValue(); - if (currentValue != null) { - setCodeStateOnSubmission(currentValue); + if (isQueryLoading && allowQueryCancellation) { + abortController?.abort(); + setIsQueryLoading(false); + } else { + setIsQueryLoading(true); + const abc = new AbortController(); + setAbortController(abc); + + const currentValue = editor1.current?.getValue(); + if (currentValue != null) { + setCodeStateOnSubmission(currentValue); + } + onTextLangQuerySubmit({ [language]: currentValue } as AggregateQuery, abc); } - onTextLangQuerySubmit({ [language]: currentValue } as AggregateQuery); - }, [language, onTextLangQuerySubmit]); + }, [language, onTextLangQuerySubmit, abortController, isQueryLoading, allowQueryCancellation]); + + useEffect(() => { + if (!isLoading) setIsQueryLoading(false); + }, [isLoading]); const [documentationSections, setDocumentationSections] = useState(); @@ -311,12 +332,13 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const { cache: esqlFieldsCache, memoizedFieldsFromESQL } = useMemo(() => { // need to store the timing of the first request so we can atomically clear the cache per query const fn = memoize( - (...args: [{ esql: string }, ExpressionsStart]) => ({ + (...args: [{ esql: string }, ExpressionsStart, undefined, AbortController?]) => ({ timestamp: Date.now(), result: fetchFieldsFromESQL(...args), }), ({ esql }) => esql ); + return { cache: fn.cache, memoizedFieldsFromESQL: fn }; }, []); @@ -334,7 +356,12 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ // Check if there's a stale entry and clear it clearCacheWhenOld(esqlFieldsCache, esqlQuery.esql); try { - const table = await memoizedFieldsFromESQL(esqlQuery, expressions).result; + const table = await memoizedFieldsFromESQL( + esqlQuery, + expressions, + undefined, + abortController + ).result; return table?.columns.map((c) => ({ name: c.name, type: c.meta.type })) || []; } catch (e) { // no action yet @@ -352,7 +379,14 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ return policies.map(({ type, query: policyQuery, ...rest }) => rest); }, }), - [dataViews, expressions, indexManagementApiService, esqlFieldsCache, memoizedFieldsFromESQL] + [ + dataViews, + expressions, + indexManagementApiService, + esqlFieldsCache, + memoizedFieldsFromESQL, + abortController, + ] ); const queryValidation = useCallback( @@ -867,7 +901,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ disableSubmitAction={disableSubmitAction} hideRunQueryText={hideRunQueryText} isSpaceReduced={isSpaceReduced} - isLoading={isLoading} + isLoading={isQueryLoading} + allowQueryCancellation={allowQueryCancellation} /> )}
@@ -954,13 +989,16 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ lines={lines} containerCSS={styles.bottomContainer} onErrorClick={onErrorClick} - runQuery={onQuerySubmit} + runQuery={() => { + onQuerySubmit(); + }} detectTimestamp={detectTimestamp} hideRunQueryText={hideRunQueryText} editorIsInline={editorIsInline} disableSubmitAction={disableSubmitAction} isSpaceReduced={isSpaceReduced} - isLoading={isLoading} + isLoading={isQueryLoading} + allowQueryCancellation={allowQueryCancellation} {...editorMessages} /> )} diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 0e4020f5c70fa..dd9fb37258ed3 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -717,7 +717,7 @@ export const QueryBarTopRow = React.memo( errors={props.textBasedLanguageModeErrors} warning={props.textBasedLanguageModeWarning} detectTimestamp={detectTimestamp} - onTextLangQuerySubmit={() => + onTextLangQuerySubmit={async () => onSubmit({ query: queryRef.current, dateRange: dateRangeRef.current, diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_esql.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_esql.tsx index 0faa236e30c6f..2f91dce01b456 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_esql.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_esql.tsx @@ -675,7 +675,7 @@ export const IndexDataVisualizerESQL: FC = (dataVi // Query that has been typed, but has not submitted with cmd + enter const [localQuery, setLocalQuery] = useState({ esql: '' }); - const onQueryUpdate = (q?: AggregateQuery) => { + const onQueryUpdate = async (q?: AggregateQuery) => { // When user submits a new query // resets all current requests and other data if (cancelOverallStatsRequest) { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts index 475862664c336..803fcbf169935 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts @@ -15,7 +15,11 @@ import type { LensPluginStartDependencies } from '../../../plugin'; import type { DatasourceMap, VisualizationMap } from '../../../types'; import { suggestionsApi } from '../../../lens_suggestions_api'; -export const getQueryColumns = async (query: AggregateQuery, deps: LensPluginStartDependencies) => { +export const getQueryColumns = async ( + query: AggregateQuery, + deps: LensPluginStartDependencies, + abortController?: AbortController +) => { // Fetching only columns for ES|QL for performance reasons with limit 0 // Important note: ES doesnt return the warnings for 0 limit, // I am skipping them in favor of performance now @@ -24,7 +28,12 @@ export const getQueryColumns = async (query: AggregateQuery, deps: LensPluginSta if ('esql' in performantQuery && performantQuery.esql) { performantQuery.esql = `${performantQuery.esql} | limit 0`; } - const table = await fetchFieldsFromESQL(performantQuery, deps.expressions); + const table = await fetchFieldsFromESQL( + performantQuery, + deps.expressions, + undefined, + abortController + ); return table?.columns; }; @@ -34,7 +43,8 @@ export const getSuggestions = async ( datasourceMap: DatasourceMap, visualizationMap: VisualizationMap, adHocDataViews: DataViewSpec[], - setErrors: (errors: Error[]) => void + setErrors: (errors: Error[]) => void, + abortController?: AbortController ) => { try { let indexPattern = ''; @@ -55,7 +65,7 @@ export const getSuggestions = async ( if (dataView.fields.getByName('@timestamp')?.type === 'date' && !dataViewSpec) { dataView.timeFieldName = '@timestamp'; } - const columns = await getQueryColumns(query, deps); + const columns = await getQueryColumns(query, deps, abortController); const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 834929d4ca2a5..3e2bf4f60aa2b 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -279,14 +279,15 @@ export function LensEditConfigurationFlyout({ const adHocDataViews = Object.values(attributes.state.adHocDataViews ?? {}); const runQuery = useCallback( - async (q) => { + async (q, abortController) => { const attrs = await getSuggestions( q, startDependencies, datasourceMap, visualizationMap, adHocDataViews, - setErrors + setErrors, + abortController ); if (attrs) { setCurrentAttributes?.(attrs); @@ -442,13 +443,13 @@ export function LensEditConfigurationFlyout({ hideMinimizeButton editorIsInline hideRunQueryText - disableSubmitAction={isEqual(query, prevQuery.current)} - onTextLangQuerySubmit={(q) => { + onTextLangQuerySubmit={async (q, a) => { if (q) { - runQuery(q); + await runQuery(q, a); } }} isDisabled={false} + allowQueryCancellation={true} /> )} diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx index 7e3aa104f5a60..fd9a63f5547e0 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx @@ -116,6 +116,7 @@ export const EsqlQueryExpression: React.FC< from: new Date(now - timeWindow).toISOString(), to: new Date(now).toISOString(), }, + undefined, // create a data view with the timefield to pass into the query new DataView({ spec: { timeFieldName: timeField }, @@ -219,7 +220,7 @@ export const EsqlQueryExpression: React.FC< }, 1000)} expandCodeEditor={() => true} isCodeEditorExpanded={true} - onTextLangQuerySubmit={() => {}} + onTextLangQuerySubmit={async () => {}} detectTimestamp={detectTimestamp} hideMinimizeButton={true} hideRunQueryText={true} From c094f611bbe152f8db1617ab5a11b24546951d45 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 17:49:48 +0000 Subject: [PATCH 042/104] skip flaky suite (#176336) --- .../cases/public/components/all_cases/severity_filter.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx b/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx index 6924cbd13f1c7..8d9f1f948cdc2 100644 --- a/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx @@ -14,7 +14,8 @@ import { screen, waitFor } from '@testing-library/react'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { SeverityFilter } from './severity_filter'; -describe('Severity form field', () => { +// FLAKY: https://github.com/elastic/kibana/issues/176336 +describe.skip('Severity form field', () => { const onChange = jest.fn(); let appMockRender: AppMockRenderer; const props = { From 82eb8e3dcbcb90eb9719d5d84fd2146f887c265e Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 8 Feb 2024 17:50:11 +0000 Subject: [PATCH 043/104] skip flaky suite (#176337) --- .../cases/public/components/all_cases/severity_filter.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx b/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx index 8d9f1f948cdc2..28be7c63f22b3 100644 --- a/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/severity_filter.test.tsx @@ -15,6 +15,7 @@ import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { SeverityFilter } from './severity_filter'; // FLAKY: https://github.com/elastic/kibana/issues/176336 +// FLAKY: https://github.com/elastic/kibana/issues/176337 describe.skip('Severity form field', () => { const onChange = jest.fn(); let appMockRender: AppMockRenderer; From 2d15f36edf76c536094a82f4a8020d66401ca411 Mon Sep 17 00:00:00 2001 From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:51:40 +0000 Subject: [PATCH 044/104] [IM] Improve index template tests (#176418) Closes https://github.com/elastic/kibana/issues/176308 ## Summary This PR improves the `beforeEach` hook in the index template tests which navigates to the Mappings step by using the data test subject of the Mappings step instead of clicking the "Next" button until we reach this step. Flaky test runner build: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5081 --- .../apps/index_management/index_template_wizard.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/x-pack/test/functional/apps/index_management/index_template_wizard.ts b/x-pack/test/functional/apps/index_management/index_template_wizard.ts index 8776c6de06e40..2a16849f2f5de 100644 --- a/x-pack/test/functional/apps/index_management/index_template_wizard.ts +++ b/x-pack/test/functional/apps/index_management/index_template_wizard.ts @@ -117,13 +117,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.setValue('indexPatternsField', 'test-index-pattern'); // Go to Mappings step - await pageObjects.indexManagement.clickNextButton(); - expect(await testSubjects.getVisibleText('stepTitle')).to.be( - 'Component templates (optional)' - ); - await pageObjects.indexManagement.clickNextButton(); - expect(await testSubjects.getVisibleText('stepTitle')).to.be('Index settings (optional)'); - await pageObjects.indexManagement.clickNextButton(); + await testSubjects.click('formWizardStep-3'); expect(await testSubjects.getVisibleText('stepTitle')).to.be('Mappings (optional)'); }); From d404ea46e3476761f409c34628841272dfedee74 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Feb 2024 10:58:55 -0700 Subject: [PATCH 045/104] [maps] fix map application is broken if you open a map with layers or sources that do not exist (#176419) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/elastic/kibana/issues/176318 PR adds try/catch blocks around all usages of `createInstanceError`. ### Test steps 1) start kibana with `yarn start --run-examples` 2) create new map, add new layer `Weather data provided by NOAA` 3) save map 4) re-start kibana with `yarn start` 5) open map saved in step 3. Map should open and layer shoould display error in legend Screenshot 2024-02-07 at 8 13 01 PM --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/classes/layers/invalid_layer.ts | 89 +++++++++++++++++ .../maps/public/classes/layers/layer.tsx | 2 +- .../maps/public/selectors/map_selectors.ts | 99 ++++++++++--------- .../apis/maps/maps_telemetry.ts | 14 +-- .../apps/maps/group4/layer_errors.js | 14 +++ .../fixtures/kbn_archiver/maps.json | 2 +- 6 files changed, 164 insertions(+), 56 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/invalid_layer.ts diff --git a/x-pack/plugins/maps/public/classes/layers/invalid_layer.ts b/x-pack/plugins/maps/public/classes/layers/invalid_layer.ts new file mode 100644 index 0000000000000..eed2ab37b32e0 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/invalid_layer.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable max-classes-per-file */ + +import { i18n } from '@kbn/i18n'; +import { LayerDescriptor } from '../../../common/descriptor_types'; +import { AbstractLayer } from './layer'; +import { AbstractSource } from '../sources/source'; +import { IStyle } from '../styles/style'; + +class InvalidSource extends AbstractSource { + constructor(id?: string) { + super({ + id, + type: 'INVALID', + }); + } +} + +export class InvalidLayer extends AbstractLayer { + private readonly _error: Error; + private readonly _style: IStyle; + + constructor(layerDescriptor: LayerDescriptor, error: Error) { + super({ + layerDescriptor, + source: new InvalidSource(layerDescriptor.sourceDescriptor?.id), + }); + this._error = error; + this._style = { + getType() { + return 'INVALID'; + }, + renderEditor() { + return null; + }, + }; + } + + hasErrors() { + return true; + } + + getErrors() { + return [ + { + title: i18n.translate('xpack.maps.invalidLayer.errorTitle', { + defaultMessage: `Unable to create layer`, + }), + body: this._error.message, + }, + ]; + } + + getStyleForEditing() { + return this._style; + } + + getStyle() { + return this._style; + } + + getCurrentStyle() { + return this._style; + } + + getMbLayerIds() { + return []; + } + + ownsMbLayerId() { + return false; + } + + ownsMbSourceId() { + return false; + } + + syncLayerWithMB() {} + + getLayerTypeIconName() { + return 'error'; + } +} diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 1fccaf7f6d0a5..aa39cf017eb0d 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -245,7 +245,7 @@ export class AbstractLayer implements ILayer { const sourceDisplayName = source ? await source.getDisplayName() : await this.getSource().getDisplayName(); - return sourceDisplayName || `Layer ${this._descriptor.id}`; + return sourceDisplayName || this._descriptor.id; } async getAttributions(): Promise { diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index ec035ac1c5623..78950c1ab2e7f 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -23,6 +23,7 @@ import { import { VectorStyle } from '../classes/styles/vector/vector_style'; import { isLayerGroup, LayerGroup } from '../classes/layers/layer_group'; import { HeatmapLayer } from '../classes/layers/heatmap_layer'; +import { InvalidLayer } from '../classes/layers/invalid_layer'; import { getTimeFilter } from '../kibana_services'; import { getChartsPaletteServiceGetColor } from '../reducers/non_serializable_instances'; import { copyPersistentState, TRACKED_LAYER_DESCRIPTOR } from '../reducers/copy_persistent_state'; @@ -76,54 +77,58 @@ export function createLayerInstance( customIcons: CustomIcon[], chartsPaletteServiceGetColor?: (value: string) => string | null ): ILayer { - if (layerDescriptor.type === LAYER_TYPE.LAYER_GROUP) { - return new LayerGroup({ layerDescriptor: layerDescriptor as LayerGroupDescriptor }); - } + try { + if (layerDescriptor.type === LAYER_TYPE.LAYER_GROUP) { + return new LayerGroup({ layerDescriptor: layerDescriptor as LayerGroupDescriptor }); + } - const source: ISource = createSourceInstance(layerDescriptor.sourceDescriptor); - switch (layerDescriptor.type) { - case LAYER_TYPE.RASTER_TILE: - return new RasterTileLayer({ layerDescriptor, source: source as IRasterSource }); - case LAYER_TYPE.EMS_VECTOR_TILE: - return new EmsVectorTileLayer({ - layerDescriptor: layerDescriptor as EMSVectorTileLayerDescriptor, - source: source as EMSTMSSource, - }); - case LAYER_TYPE.HEATMAP: - return new HeatmapLayer({ - layerDescriptor: layerDescriptor as HeatmapLayerDescriptor, - source: source as ESGeoGridSource, - }); - case LAYER_TYPE.GEOJSON_VECTOR: - return new GeoJsonVectorLayer({ - layerDescriptor: layerDescriptor as VectorLayerDescriptor, - source: source as IVectorSource, - joins: createJoinInstances( - layerDescriptor as VectorLayerDescriptor, - source as IVectorSource - ), - customIcons, - chartsPaletteServiceGetColor, - }); - case LAYER_TYPE.BLENDED_VECTOR: - return new BlendedVectorLayer({ - layerDescriptor: layerDescriptor as VectorLayerDescriptor, - source: source as IVectorSource, - customIcons, - chartsPaletteServiceGetColor, - }); - case LAYER_TYPE.MVT_VECTOR: - return new MvtVectorLayer({ - layerDescriptor: layerDescriptor as VectorLayerDescriptor, - source: source as IVectorSource, - joins: createJoinInstances( - layerDescriptor as VectorLayerDescriptor, - source as IVectorSource - ), - customIcons, - }); - default: - throw new Error(`Unrecognized layerType ${layerDescriptor.type}`); + const source: ISource = createSourceInstance(layerDescriptor.sourceDescriptor); + switch (layerDescriptor.type) { + case LAYER_TYPE.RASTER_TILE: + return new RasterTileLayer({ layerDescriptor, source: source as IRasterSource }); + case LAYER_TYPE.EMS_VECTOR_TILE: + return new EmsVectorTileLayer({ + layerDescriptor: layerDescriptor as EMSVectorTileLayerDescriptor, + source: source as EMSTMSSource, + }); + case LAYER_TYPE.HEATMAP: + return new HeatmapLayer({ + layerDescriptor: layerDescriptor as HeatmapLayerDescriptor, + source: source as ESGeoGridSource, + }); + case LAYER_TYPE.GEOJSON_VECTOR: + return new GeoJsonVectorLayer({ + layerDescriptor: layerDescriptor as VectorLayerDescriptor, + source: source as IVectorSource, + joins: createJoinInstances( + layerDescriptor as VectorLayerDescriptor, + source as IVectorSource + ), + customIcons, + chartsPaletteServiceGetColor, + }); + case LAYER_TYPE.BLENDED_VECTOR: + return new BlendedVectorLayer({ + layerDescriptor: layerDescriptor as VectorLayerDescriptor, + source: source as IVectorSource, + customIcons, + chartsPaletteServiceGetColor, + }); + case LAYER_TYPE.MVT_VECTOR: + return new MvtVectorLayer({ + layerDescriptor: layerDescriptor as VectorLayerDescriptor, + source: source as IVectorSource, + joins: createJoinInstances( + layerDescriptor as VectorLayerDescriptor, + source as IVectorSource + ), + customIcons, + }); + default: + throw new Error(`Unrecognized layerType ${layerDescriptor.type}`); + } + } catch (error) { + return new InvalidLayer(layerDescriptor, error); } } diff --git a/x-pack/test/api_integration/apis/maps/maps_telemetry.ts b/x-pack/test/api_integration/apis/maps/maps_telemetry.ts index 92ae21c7c09c0..8f5c9ae95f8af 100644 --- a/x-pack/test/api_integration/apis/maps/maps_telemetry.ts +++ b/x-pack/test/api_integration/apis/maps/maps_telemetry.ts @@ -60,7 +60,7 @@ export default function ({ getService }: FtrProviderContext) { es_point_to_point: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, es_top_hits: { min: 1, max: 1, total: 2, avg: 0.07142857142857142 }, es_agg_heatmap: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, - esql: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, + esql: { min: 1, max: 1, total: 2, avg: 0.07142857142857142 }, kbn_tms_raster: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, ems_basemap: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, ems_region: { min: 1, max: 1, total: 1, avg: 0.03571428571428571 }, @@ -81,8 +81,8 @@ export default function ({ getService }: FtrProviderContext) { min: 0, }, dataSourcesCount: { - avg: 1.1785714285714286, - max: 6, + avg: 1.2142857142857142, + max: 7, min: 1, }, emsVectorLayersCount: { @@ -104,8 +104,8 @@ export default function ({ getService }: FtrProviderContext) { min: 1, }, GEOJSON_VECTOR: { - avg: 0.8214285714285714, - max: 5, + avg: 0.8571428571428571, + max: 6, min: 1, }, HEATMAP: { @@ -125,8 +125,8 @@ export default function ({ getService }: FtrProviderContext) { }, }, layersCount: { - avg: 1.2142857142857142, - max: 7, + avg: 1.25, + max: 8, min: 1, }, }, diff --git a/x-pack/test/functional/apps/maps/group4/layer_errors.js b/x-pack/test/functional/apps/maps/group4/layer_errors.js index e47c0e582c8f4..9f8a570a46d96 100644 --- a/x-pack/test/functional/apps/maps/group4/layer_errors.js +++ b/x-pack/test/functional/apps/maps/group4/layer_errors.js @@ -18,6 +18,20 @@ export default function ({ getPageObjects, getService }) { await PageObjects.maps.loadSavedMap('layer with errors'); }); + describe('Layer with invalid descriptor', () => { + const INVALID_LAYER_NAME = 'fff76ebb-57a6-4067-a373-1d191b9bd1a3'; + + it('should diplay error icon in legend', async () => { + await PageObjects.maps.hasErrorIconExistsOrFail(INVALID_LAYER_NAME); + }); + + it('should allow deletion of layer', async () => { + await PageObjects.maps.removeLayer(INVALID_LAYER_NAME); + const exists = await PageObjects.maps.doesLayerExist(INVALID_LAYER_NAME); + expect(exists).to.be(false); + }); + }); + describe('Layer with EsError', () => { after(async () => { await inspector.close(); diff --git a/x-pack/test/functional/fixtures/kbn_archiver/maps.json b/x-pack/test/functional/fixtures/kbn_archiver/maps.json index 74f27e360cfa1..1ce5bc3fd6aa1 100644 --- a/x-pack/test/functional/fixtures/kbn_archiver/maps.json +++ b/x-pack/test/functional/fixtures/kbn_archiver/maps.json @@ -747,7 +747,7 @@ "version": "WzU1LDFd", "attributes": { "description": "", - "layerListJSON": "[{\"sourceDescriptor\":{\"type\":\"KIBANA_TILEMAP\"},\"id\":\"ap0ys\",\"label\":\"Custom_TMS\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"RASTER_TILE\"},{\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"idThatDoesNotExitForEMSTile\",\"lightModeDefault\":\"road_map\"},\"temporary\":false,\"id\":\"plw9l\",\"label\":\"EMS_tiles\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"EMS_VECTOR_TILE\"},{\"sourceDescriptor\":{\"type\":\"EMS_FILE\",\"id\":\"idThatDoesNotExitForEMSFileSource\"},\"temporary\":false,\"id\":\"2gro0\",\"label\":\"EMS_vector_shapes\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"id\":\"f67fe707-95dd-46d6-89b8-82617b251b61\",\"geoField\":\"geo.coordinates\",\"requestType\":\"grid\",\"resolution\":\"COARSE\",\"applyGlobalQuery\":true,\"indexPatternRefName\":\"layer_3_source_index_pattern\"},\"temporary\":false,\"id\":\"pl5qd\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"color\":\"Blues\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"minSize\":4,\"maxSize\":32,\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"sourceDescriptor\":{\"id\":\"a07072bb-3a92-4320-bd37-250ef6d04db7\",\"type\":\"ES_SEARCH\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"tooltipProperties\":[],\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\",\"indexPatternRefName\":\"layer_4_source_index_pattern\"},\"temporary\":false,\"id\":\"9bw8h\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"id\":\"n1t6f\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"62eca1fc-fe42-11e8-8eb2-f2801f1b9fd1\",\"type\":\"ES_SEARCH\",\"geoField\":\"geometry\",\"limit\":2048,\"filterByMapBounds\":false,\"showTooltip\":true,\"tooltipProperties\":[],\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\",\"indexPatternRefName\":\"layer_5_source_index_pattern\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"max(prop1) group by meta_for_geo_shapes*.shape_name\",\"name\":\"__kbnjoin__max_of_prop1__855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"origin\":\"join\"},\"color\":\"Blues\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"temporary\":true,\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\",\"joins\":[{\"leftField\":\"name\",\"right\":{\"id\":\"855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"indexPatternTitle\":\"meta_for_geo_shapes*\",\"term\":\"shape_name\",\"metrics\":[{\"type\":\"max\",\"field\":\"prop1\"}],\"applyGlobalQuery\":true,\"type\":\"ES_TERM_SOURCE\",\"indexPatternRefName\":\"layer_5_join_0_index_pattern\"}}]},{\"sourceDescriptor\":{\"geoField\":\"destination\",\"scalingType\":\"LIMIT\",\"id\":\"ed01aac3-c0be-491e-98c9-f1cb6e37f185\",\"type\":\"ES_SEARCH\",\"applyGlobalQuery\":true,\"applyGlobalTime\":true,\"applyForceRefresh\":true,\"filterByMapBounds\":true,\"tooltipProperties\":[],\"sortField\":\"\",\"sortOrder\":\"desc\",\"topHitsGroupByTimeseries\":false,\"topHitsSplitField\":\"\",\"topHitsSize\":1,\"indexPatternRefName\":\"layer_6_source_index_pattern\"},\"id\":\"1cfaa7fa-dc73-419d-b362-7238e2270a1c\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}},\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#54B399\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#41937c\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":0}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":6}},\"iconOrientation\":{\"type\":\"STATIC\",\"options\":{\"orientation\":0}},\"labelText\":{\"type\":\"STATIC\",\"options\":{\"value\":\"\"}},\"labelColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#000000\"}},\"labelSize\":{\"type\":\"STATIC\",\"options\":{\"size\":14}},\"labelZoomRange\":{\"options\":{\"useLayerZoomRange\":true,\"minZoom\":0,\"maxZoom\":24}},\"labelBorderColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"labelBorderSize\":{\"options\":{\"size\":\"SMALL\"}},\"labelPosition\":{\"options\":{\"position\":\"CENTER\"}}},\"isTimeAware\":true},\"includeInFitToBounds\":true,\"type\":\"GEOJSON_VECTOR\",\"joins\":[],\"disableTooltips\":false}]", + "layerListJSON": "[{\"sourceDescriptor\":{\"type\":\"KIBANA_TILEMAP\"},\"id\":\"ap0ys\",\"label\":\"Custom_TMS\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"RASTER_TILE\"},{\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"idThatDoesNotExitForEMSTile\",\"lightModeDefault\":\"road_map\"},\"temporary\":false,\"id\":\"plw9l\",\"label\":\"EMS_tiles\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"EMS_VECTOR_TILE\"},{\"sourceDescriptor\":{\"type\":\"EMS_FILE\",\"id\":\"idThatDoesNotExitForEMSFileSource\"},\"temporary\":false,\"id\":\"2gro0\",\"label\":\"EMS_vector_shapes\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"id\":\"f67fe707-95dd-46d6-89b8-82617b251b61\",\"geoField\":\"geo.coordinates\",\"requestType\":\"grid\",\"resolution\":\"COARSE\",\"applyGlobalQuery\":true,\"indexPatternRefName\":\"layer_3_source_index_pattern\"},\"temporary\":false,\"id\":\"pl5qd\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"color\":\"Blues\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"minSize\":4,\"maxSize\":32,\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"sourceDescriptor\":{\"id\":\"a07072bb-3a92-4320-bd37-250ef6d04db7\",\"type\":\"ES_SEARCH\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"tooltipProperties\":[],\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\",\"indexPatternRefName\":\"layer_4_source_index_pattern\"},\"temporary\":false,\"id\":\"9bw8h\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\"},{\"id\":\"n1t6f\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"62eca1fc-fe42-11e8-8eb2-f2801f1b9fd1\",\"type\":\"ES_SEARCH\",\"geoField\":\"geometry\",\"limit\":2048,\"filterByMapBounds\":false,\"showTooltip\":true,\"tooltipProperties\":[],\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\",\"indexPatternRefName\":\"layer_5_source_index_pattern\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"max(prop1) group by meta_for_geo_shapes*.shape_name\",\"name\":\"__kbnjoin__max_of_prop1__855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"origin\":\"join\"},\"color\":\"Blues\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"temporary\":true,\"previousStyle\":null},\"type\":\"GEOJSON_VECTOR\",\"joins\":[{\"leftField\":\"name\",\"right\":{\"id\":\"855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"indexPatternTitle\":\"meta_for_geo_shapes*\",\"term\":\"shape_name\",\"metrics\":[{\"type\":\"max\",\"field\":\"prop1\"}],\"applyGlobalQuery\":true,\"type\":\"ES_TERM_SOURCE\",\"indexPatternRefName\":\"layer_5_join_0_index_pattern\"}}]},{\"sourceDescriptor\":{\"geoField\":\"destination\",\"scalingType\":\"LIMIT\",\"id\":\"ed01aac3-c0be-491e-98c9-f1cb6e37f185\",\"type\":\"ES_SEARCH\",\"applyGlobalQuery\":true,\"applyGlobalTime\":true,\"applyForceRefresh\":true,\"filterByMapBounds\":true,\"tooltipProperties\":[],\"sortField\":\"\",\"sortOrder\":\"desc\",\"topHitsGroupByTimeseries\":false,\"topHitsSplitField\":\"\",\"topHitsSize\":1,\"indexPatternRefName\":\"layer_6_source_index_pattern\"},\"id\":\"1cfaa7fa-dc73-419d-b362-7238e2270a1c\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}},\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#54B399\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#41937c\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":0}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":6}},\"iconOrientation\":{\"type\":\"STATIC\",\"options\":{\"orientation\":0}},\"labelText\":{\"type\":\"STATIC\",\"options\":{\"value\":\"\"}},\"labelColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#000000\"}},\"labelSize\":{\"type\":\"STATIC\",\"options\":{\"size\":14}},\"labelZoomRange\":{\"options\":{\"useLayerZoomRange\":true,\"minZoom\":0,\"maxZoom\":24}},\"labelBorderColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"labelBorderSize\":{\"options\":{\"size\":\"SMALL\"}},\"labelPosition\":{\"options\":{\"position\":\"CENTER\"}}},\"isTimeAware\":true},\"includeInFitToBounds\":true,\"type\":\"GEOJSON_VECTOR\",\"joins\":[],\"disableTooltips\":false},{\"sourceDescriptor\":{\"id\":\"d4d6d4cf-58ee-4a0d-a792-532c0711fa2a\",\"type\":\"ESQL\"},\"id\":\"fff76ebb-57a6-4067-a373-1d191b9bd1a3\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}},\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#6092C0\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#4379aa\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":6}},\"iconOrientation\":{\"type\":\"STATIC\",\"options\":{\"orientation\":0}},\"labelText\":{\"type\":\"STATIC\",\"options\":{\"value\":\"\"}},\"labelColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#000000\"}},\"labelSize\":{\"type\":\"STATIC\",\"options\":{\"size\":14}},\"labelZoomRange\":{\"options\":{\"useLayerZoomRange\":true,\"minZoom\":0,\"maxZoom\":24}},\"labelBorderColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"labelBorderSize\":{\"options\":{\"size\":\"SMALL\"}},\"labelPosition\":{\"options\":{\"position\":\"CENTER\"}}},\"isTimeAware\":true},\"includeInFitToBounds\":true,\"type\":\"GEOJSON_VECTOR\",\"joins\":[],\"disableTooltips\":false}]", "mapStateJSON": "{\"adHocDataViews\":[],\"zoom\":3.38,\"center\":{\"lon\":76.34937,\"lat\":-77.25604},\"timeFilters\":{\"from\":\"now-7d\",\"to\":\"now\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":0},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[{\"meta\":{\"index\":\"561253e0-f731-11e8-8487-11b9dd924f96\",\"type\":\"custom\",\"disabled\":false,\"negate\":false,\"alias\":\"connections shard failure\",\"key\":\"query\",\"value\":\"{\\\"error_query\\\":{\\\"indices\\\":[{\\\"error_type\\\":\\\"exception\\\",\\\"message\\\":\\\"simulated shard failure\\\",\\\"name\\\":\\\"connections\\\"}]}}\"},\"$state\":{\"store\":\"appState\"},\"query\":{\"error_query\":{\"indices\":[{\"error_type\":\"exception\",\"message\":\"simulated shard failure\",\"name\":\"connections\"}]}}}],\"settings\":{\"autoFitToDataBounds\":false,\"backgroundColor\":\"#ffffff\",\"customIcons\":[],\"disableInteractive\":false,\"disableTooltipControl\":false,\"hideToolbarOverlay\":false,\"hideLayerControl\":false,\"hideViewControl\":false,\"initialLocation\":\"LAST_SAVED_LOCATION\",\"fixedLocation\":{\"lat\":0,\"lon\":0,\"zoom\":2},\"browserLocation\":{\"zoom\":2},\"keydownScrollZoom\":false,\"maxZoom\":24,\"minZoom\":0,\"showScaleControl\":false,\"showSpatialFilters\":true,\"showTimesliderToggleButton\":true,\"spatialFiltersAlpa\":0.3,\"spatialFiltersFillColor\":\"#DA8B45\",\"spatialFiltersLineColor\":\"#DA8B45\"}}", "title": "layer with errors", "uiStateJSON": "{\"isLayerTOCOpen\":true,\"openTOCDetails\":[\"1cfaa7fa-dc73-419d-b362-7238e2270a1c\"]}" From fa98e5871ce2f42954bfed0f32501e97fbacd069 Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:49:04 -0600 Subject: [PATCH 046/104] [ML] Fix multi match query overriding filters in Data visualizer and Data Drift (#176347) This PR removes usage of `createMergedEsQuery` in favor of buildEsQuery. It also fixes an intermittent issue with filters https://github.com/elastic/kibana/issues/170472 not being honored when query is partial/of multi match type. Screenshot 2024-02-07 at 10 20 26 It also improves adding/removing filter for empty values ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] 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)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] 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)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/top_values/top_values.tsx | 16 +-- .../application/common/hooks/use_data.ts | 22 ++-- .../data_drift/use_data_drift_result.ts | 21 ++-- .../index_data_visualizer_view.tsx | 10 +- .../components/search_panel/search_bar.tsx | 13 ++- .../hooks/use_data_visualizer_grid_data.ts | 6 +- .../utils/saved_search_utils.test.ts | 82 +------------- .../utils/saved_search_utils.ts | 104 +++++------------- 8 files changed, 76 insertions(+), 198 deletions(-) diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/top_values/top_values.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/top_values/top_values.tsx index 111b0a2113403..9ea517d45eea1 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/top_values/top_values.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/top_values/top_values.tsx @@ -116,10 +116,10 @@ export const TopValues: FC = ({ stats, fieldFormat, barColor, compressed, > {Array.isArray(topValues) ? topValues.map((value) => { - const fieldValue = - value.key_as_string ?? (value.key ? value.key.toString() : EMPTY_EXAMPLE); + const fieldValue = value.key_as_string ?? (value.key ? value.key.toString() : ''); + const displayValue = fieldValue ?? EMPTY_EXAMPLE; return ( - + = ({ stats, fieldFormat, barColor, compressed, /> {fieldName !== undefined && - fieldValue !== undefined && + displayValue !== undefined && onAddFilter !== undefined ? (
= ({ stats, fieldFormat, barColor, compressed, 'xpack.dataVisualizer.dataGrid.field.addFilterAriaLabel', { defaultMessage: 'Filter for {fieldName}: "{value}"', - values: { fieldName, value: fieldValue }, + values: { fieldName, value: displayValue }, } )} - data-test-subj={`dvFieldDataTopValuesAddFilterButton-${fieldName}-${fieldValue}`} + data-test-subj={`dvFieldDataTopValuesAddFilterButton-${fieldName}-${displayValue}`} style={{ minHeight: 'auto', minWidth: 'auto', @@ -172,10 +172,10 @@ export const TopValues: FC = ({ stats, fieldFormat, barColor, compressed, 'xpack.dataVisualizer.dataGrid.field.removeFilterAriaLabel', { defaultMessage: 'Filter out {fieldName}: "{value}"', - values: { fieldName, value: fieldValue }, + values: { fieldName, value: displayValue }, } )} - data-test-subj={`dvFieldDataTopValuesExcludeFilterButton-${fieldName}-${fieldValue}`} + data-test-subj={`dvFieldDataTopValuesExcludeFilterButton-${fieldName}-${displayValue}`} style={{ minHeight: 'auto', minWidth: 'auto', diff --git a/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts b/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts index 65c882ba551d9..9b85720fc1df4 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts @@ -14,9 +14,9 @@ import { mlTimefilterRefresh$, useTimefilter } from '@kbn/ml-date-picker'; import { merge } from 'rxjs'; import { RandomSampler } from '@kbn/ml-random-sampler-utils'; import { mapAndFlattenFilters } from '@kbn/data-plugin/public'; -import { Query } from '@kbn/es-query'; +import { buildEsQuery, Query } from '@kbn/es-query'; import { SearchQueryLanguage } from '@kbn/ml-query-utils'; -import { createMergedEsQuery } from '../../index_data_visualizer/utils/saved_search_utils'; +import { getEsQueryConfig } from '@kbn/data-plugin/common'; import { useDataDriftStateManagerContext } from '../../data_drift/use_state_manager'; import type { InitialSettings } from '../../data_drift/use_data_drift_result'; import { @@ -74,7 +74,7 @@ export const useData = ( () => { const searchQuery = searchString !== undefined && searchQueryLanguage !== undefined - ? { query: searchString, language: searchQueryLanguage } + ? ({ query: searchString, language: searchQueryLanguage } as Query) : undefined; const timefilterActiveBounds = timeRange ?? timefilter.getActiveBounds(); @@ -90,24 +90,24 @@ export const useData = ( runtimeFieldMap: selectedDataView.getRuntimeMappings(), }; - const refQuery = createMergedEsQuery( - searchQuery, + const refQuery = buildEsQuery( + selectedDataView, + searchQuery ?? [], mapAndFlattenFilters([ ...queryManager.filterManager.getFilters(), ...(referenceStateManager.filters ?? []), ]), - selectedDataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); - const compQuery = createMergedEsQuery( - searchQuery, + const compQuery = buildEsQuery( + selectedDataView, + searchQuery ?? [], mapAndFlattenFilters([ ...queryManager.filterManager.getFilters(), ...(comparisonStateManager.filters ?? []), ]), - selectedDataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); return { diff --git a/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts b/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts index 07b74677e8ea9..05f24bdcb7b68 100644 --- a/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts +++ b/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts @@ -8,6 +8,7 @@ import { chunk, cloneDeep, flatten } from 'lodash'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { lastValueFrom } from 'rxjs'; +import { getEsQueryConfig } from '@kbn/data-plugin/common'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { @@ -30,7 +31,7 @@ import { computeChi2PValue, type Histogram } from '@kbn/ml-chi2test'; import { mapAndFlattenFilters } from '@kbn/data-plugin/public'; import type { AggregationsMultiTermsBucketKeys } from '@elastic/elasticsearch/lib/api/types'; -import { createMergedEsQuery } from '../index_data_visualizer/utils/saved_search_utils'; +import { buildEsQuery } from '@kbn/es-query'; import { useDataVisualizerKibana } from '../kibana_context'; import { useDataDriftStateManagerContext } from './use_state_manager'; @@ -758,18 +759,18 @@ export const useFetchDataComparisonResult = ( const kqlQuery = searchString !== undefined && searchQueryLanguage !== undefined - ? { query: searchString, language: searchQueryLanguage } + ? ({ query: searchString, language: searchQueryLanguage } as Query) : undefined; const refDataQuery = getDataComparisonQuery({ - searchQuery: createMergedEsQuery( - kqlQuery, + searchQuery: buildEsQuery( + currentDataView, + kqlQuery ?? [], mapAndFlattenFilters([ ...queryManager.filterManager.getFilters(), ...(referenceStateManager.filters ?? []), ]), - currentDataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ), datetimeField: currentDataView?.timeFieldName, runtimeFields, @@ -827,14 +828,14 @@ export const useFetchDataComparisonResult = ( setLoaded(0.25); const prodDataQuery = getDataComparisonQuery({ - searchQuery: createMergedEsQuery( - kqlQuery, + searchQuery: buildEsQuery( + currentDataView, + kqlQuery ?? [], mapAndFlattenFilters([ ...queryManager.filterManager.getFilters(), ...(comparisonStateManager.filters ?? []), ]), - currentDataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ), datetimeField: currentDataView?.timeFieldName, runtimeFields, diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx index cc17387886071..5d8ebe9e44d57 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx @@ -8,6 +8,7 @@ import { css } from '@emotion/react'; import React, { FC, useEffect, useMemo, useState, useCallback, useRef } from 'react'; import type { Required } from 'utility-types'; +import { getEsQueryConfig } from '@kbn/data-plugin/common'; import { useEuiBreakpoint, @@ -21,7 +22,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { type Filter, FilterStateStore, type Query } from '@kbn/es-query'; +import { type Filter, FilterStateStore, type Query, buildEsQuery } from '@kbn/es-query'; import { generateFilters } from '@kbn/data-plugin/public'; import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; import { usePageUrlState, useUrlState } from '@kbn/ml-url-state'; @@ -62,7 +63,6 @@ import { DocumentCountContent } from '../../../common/components/document_count_ import { OMIT_FIELDS } from '../../../../../common/constants'; import { SearchPanel } from '../search_panel'; import { ActionsPanel } from '../actions_panel'; -import { createMergedEsQuery } from '../../utils/saved_search_utils'; import { DataVisualizerDataViewManagement } from '../data_view_management'; import type { GetAdditionalLinks } from '../../../common/components/results_links'; import { useDataVisualizerGridData } from '../../hooks/use_data_visualizer_grid_data'; @@ -389,14 +389,14 @@ export const IndexDataVisualizerView: FC = (dataVi language: searchQueryLanguage, }; - const combinedQuery = createMergedEsQuery( + const combinedQuery = buildEsQuery( + currentDataView, { query: searchString || '', language: searchQueryLanguage, }, data.query.filterManager.getFilters() ?? [], - currentDataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); setSearchParams({ diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx index 3ad691bbe11ce..d0f6812c4e253 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import type { Filter, Query, TimeRange } from '@kbn/es-query'; +import { buildEsQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useState } from 'react'; import { isDefined } from '@kbn/ml-is-defined'; import { DataView } from '@kbn/data-views-plugin/common'; import type { SearchQueryLanguage } from '@kbn/ml-query-utils'; -import { createMergedEsQuery } from '../../utils/saved_search_utils'; +import { getEsQueryConfig } from '@kbn/data-plugin/common'; import { useDataVisualizerKibana } from '../../../kibana_context'; export const SearchPanelContent = ({ @@ -63,16 +63,17 @@ export const SearchPanelContent = ({ const searchHandler = ({ query, filters }: { query?: Query; filters?: Filter[] }) => { const mergedQuery = isDefined(query) ? query : searchInput; const mergedFilters = isDefined(filters) ? filters : queryManager.filterManager.getFilters(); + try { if (mergedFilters) { queryManager.filterManager.setFilters(mergedFilters); } - const combinedQuery = createMergedEsQuery( - mergedQuery, - queryManager.filterManager.getFilters() ?? [], + const combinedQuery = buildEsQuery( dataView, - uiSettings + mergedQuery ? [mergedQuery] : [], + queryManager.filterManager.getFilters() ?? [], + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); setSearchParams({ diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts index b012d049ae04f..4570a2019af26 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts @@ -137,10 +137,11 @@ export const useDataVisualizerGridData = ( }); if (searchData === undefined || dataVisualizerListState.searchString !== '') { - if (dataVisualizerListState.filters) { + if (filterManager) { const globalFilters = filterManager?.getGlobalFilters(); - if (filterManager) filterManager.setFilters(dataVisualizerListState.filters); + if (dataVisualizerListState.filters) + filterManager.setFilters(dataVisualizerListState.filters); if (globalFilters) filterManager?.addFilters(globalFilters); } return { @@ -169,6 +170,7 @@ export const useDataVisualizerGridData = ( currentFilters, }), lastRefresh, + data.query.filterManager, ]); const _timeBuckets = useTimeBuckets(); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts index c43483a34e34c..2b25a5e8d2b8c 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts @@ -5,14 +5,10 @@ * 2.0. */ -import { - getQueryFromSavedSearchObject, - createMergedEsQuery, - getEsQueryFromSavedSearch, -} from './saved_search_utils'; +import { getQueryFromSavedSearchObject, getEsQueryFromSavedSearch } from './saved_search_utils'; import type { SavedSearchSavedObject } from '../../../../common/types'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { type Filter, FilterStateStore } from '@kbn/es-query'; +import { FilterStateStore } from '@kbn/es-query'; import { stubbedSavedObjectIndexPattern } from '@kbn/data-views-plugin/common/data_view.stub'; import { DataView } from '@kbn/data-views-plugin/public'; import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; @@ -217,80 +213,6 @@ describe('getQueryFromSavedSearchObject()', () => { }); }); -describe('createMergedEsQuery()', () => { - const luceneQuery = { - query: 'responsetime:>50', - language: 'lucene', - }; - const kqlQuery = { - query: 'responsetime > 49', - language: 'kuery', - }; - const mockFilters: Filter[] = [ - { - meta: { - index: '90a978e0-1c80-11ec-b1d7-f7e5cf21b9e0', - negate: false, - disabled: false, - alias: null, - type: 'phrase', - key: 'airline', - params: { - query: 'ASA', - }, - }, - query: { - match: { - airline: { - query: 'ASA', - type: 'phrase', - }, - }, - }, - $state: { - store: 'appState' as FilterStateStore, - }, - }, - ]; - - it('return formatted ES bool query with both the original query and filters combined', () => { - expect(createMergedEsQuery(luceneQuery, mockFilters)).toEqual({ - bool: { - filter: [{ match_phrase: { airline: { query: 'ASA' } } }], - must: [{ query_string: { query: 'responsetime:>50' } }], - must_not: [], - should: [], - }, - }); - expect(createMergedEsQuery(kqlQuery, mockFilters)).toEqual({ - bool: { - filter: [{ match_phrase: { airline: { query: 'ASA' } } }], - minimum_should_match: 1, - must_not: [], - should: [{ range: { responsetime: { gt: '49' } } }], - }, - }); - }); - it('return formatted ES bool query without filters ', () => { - expect(createMergedEsQuery(luceneQuery)).toEqual({ - bool: { - filter: [], - must: [{ query_string: { query: 'responsetime:>50' } }], - must_not: [], - should: [], - }, - }); - expect(createMergedEsQuery(kqlQuery)).toEqual({ - bool: { - filter: [], - minimum_should_match: 1, - must_not: [], - should: [{ range: { responsetime: { gt: '49' } } }], - }, - }); - }); -}); - describe('getEsQueryFromSavedSearch()', () => { it('return undefined if saved search is not provided', () => { expect( diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts index 04bc52bf08057..3ecc8a3a7a3d8 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts @@ -9,22 +9,15 @@ // `x-pack/plugins/apm/public/components/app/correlations/progress_controls.tsx` import { cloneDeep } from 'lodash'; import { IUiSettingsClient } from '@kbn/core/public'; -import { - fromKueryExpression, - toElasticsearchQuery, - buildQueryFromFilters, - buildEsQuery, - Query, - Filter, - AggregateQuery, -} from '@kbn/es-query'; +import { buildEsQuery, Query, Filter } from '@kbn/es-query'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { DataView } from '@kbn/data-views-plugin/public'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { getEsQueryConfig, isQuery, SearchSource } from '@kbn/data-plugin/common'; +import { getEsQueryConfig, SearchSource } from '@kbn/data-plugin/common'; import { FilterManager, mapAndFlattenFilters } from '@kbn/data-plugin/public'; import { getDefaultDSLQuery } from '@kbn/ml-query-utils'; -import { SEARCH_QUERY_LANGUAGE, SearchQueryLanguage } from '@kbn/ml-query-utils'; +import { SearchQueryLanguage } from '@kbn/ml-query-utils'; +import { isDefined } from '@kbn/ml-is-defined'; import { isSavedSearchSavedObject, SavedSearchSavedObject } from '../../../../common/types'; /** @@ -59,53 +52,8 @@ export function getQueryFromSavedSearchObject(savedSearch: SavedSearchSavedObjec return parsed; } -/** - * Create an Elasticsearch query that combines both lucene/kql query string and filters - * Should also form a valid query if only the query or filters is provided - */ -export function createMergedEsQuery( - query?: Query | AggregateQuery | undefined, - filters?: Filter[], - dataView?: DataView, - uiSettings?: IUiSettingsClient -) { - let combinedQuery = getDefaultDSLQuery() as QueryDslQueryContainer; - - if (isQuery(query) && query.language === SEARCH_QUERY_LANGUAGE.KUERY) { - const ast = fromKueryExpression(query.query); - if (query.query !== '') { - combinedQuery = toElasticsearchQuery(ast, dataView); - } - if (combinedQuery.bool !== undefined) { - const filterQuery = buildQueryFromFilters(filters, dataView); - - if (!Array.isArray(combinedQuery.bool.filter)) { - combinedQuery.bool.filter = - combinedQuery.bool.filter === undefined ? [] : [combinedQuery.bool.filter]; - } - - if (!Array.isArray(combinedQuery.bool.must_not)) { - combinedQuery.bool.must_not = - combinedQuery.bool.must_not === undefined ? [] : [combinedQuery.bool.must_not]; - } - - combinedQuery.bool.filter = [...combinedQuery.bool.filter, ...filterQuery.filter]; - combinedQuery.bool.must_not = [...combinedQuery.bool.must_not, ...filterQuery.must_not]; - } - } else { - combinedQuery = buildEsQuery( - dataView, - query ? [query] : [], - filters ? filters : [], - uiSettings ? getEsQueryConfig(uiSettings) : undefined - ); - } - - return combinedQuery; -} - -function getSavedSearchSource(savedSearch: SavedSearch) { - return savedSearch && +function getSavedSearchSource(savedSearch?: SavedSearch | null) { + return isDefined(savedSearch) && 'searchSource' in savedSearch && savedSearch?.searchSource instanceof SearchSource ? savedSearch.searchSource @@ -131,11 +79,15 @@ export function getEsQueryFromSavedSearch({ filters?: Filter[]; filterManager?: FilterManager; }) { - if (!dataView || !savedSearch) return; + if (!dataView && !savedSearch) return; const userQuery = query; const userFilters = filters; + if (filterManager && userFilters) { + filterManager.addFilters(userFilters); + } + const savedSearchSource = getSavedSearchSource(savedSearch); // If saved search has a search source with nested parent @@ -146,8 +98,8 @@ export function getEsQueryFromSavedSearch({ // Flattened query from search source may contain a clause that narrows the time range // which might interfere with global time pickers so we need to remove const savedQuery = - cloneDeep(savedSearch.searchSource.getSearchRequestBody()?.query) ?? getDefaultDSLQuery(); - const timeField = savedSearch.searchSource.getField('index')?.timeFieldName; + cloneDeep(savedSearchSource.getSearchRequestBody()?.query) ?? getDefaultDSLQuery(); + const timeField = savedSearchSource.getField('index')?.timeFieldName; if (Array.isArray(savedQuery.bool.filter) && timeField !== undefined) { savedQuery.bool.filter = savedQuery.bool.filter.filter( @@ -155,6 +107,7 @@ export function getEsQueryFromSavedSearch({ !(c.hasOwnProperty('range') && c.range?.hasOwnProperty(timeField)) ); } + return { searchQuery: savedQuery, searchString: userQuery.query, @@ -163,39 +116,38 @@ export function getEsQueryFromSavedSearch({ } // If no saved search available, use user's query and filters - if (!savedSearch && userQuery) { - if (filterManager && userFilters) filterManager.addFilters(userFilters); - - const combinedQuery = createMergedEsQuery( - userQuery, - Array.isArray(userFilters) ? userFilters : [], + if ( + !savedSearch && + (userQuery || userFilters || (filterManager && filterManager.getGlobalFilters()?.length > 0)) + ) { + const combinedQuery = buildEsQuery( dataView, - uiSettings + userQuery ?? [], + filterManager?.getFilters() ?? [], + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); return { searchQuery: combinedQuery, - searchString: userQuery.query, - queryLanguage: userQuery.language as SearchQueryLanguage, + searchString: userQuery?.query ?? '', + queryLanguage: (userQuery?.language ?? 'kuery') as SearchQueryLanguage, }; } // If saved search available, merge saved search with the latest user query or filters // which might differ from extracted saved search data if (savedSearchSource) { - const globalFilters = filterManager?.getGlobalFilters(); // FIXME: Add support for AggregateQuery type #150091 const currentQuery = userQuery ?? (savedSearchSource.getField('query') as Query); const currentFilters = userFilters ?? mapAndFlattenFilters(savedSearchSource.getField('filter') as Filter[]); - if (filterManager) filterManager.setFilters(currentFilters); - if (globalFilters) filterManager?.addFilters(globalFilters); + if (filterManager) filterManager.addFilters(currentFilters); - const combinedQuery = createMergedEsQuery( + const combinedQuery = buildEsQuery( + dataView, currentQuery, filterManager ? filterManager?.getFilters() : currentFilters, - dataView, - uiSettings + uiSettings ? getEsQueryConfig(uiSettings) : undefined ); return { From ee34012cd9accce9f2b6bcb39cf4f342cff0f1ef Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Thu, 8 Feb 2024 12:32:25 -0700 Subject: [PATCH 047/104] [ML] Anomaly Detection: Add single metric viewer embeddable for dashboards (#175857) ## Summary Related issue to [add ability to insert "Single Metric Viewer" into a dashboard](https://github.com/elastic/kibana/issues/173555) This PR adds the single metric viewer as an embeddable that can be added to dashboards. ### NOTE FOR TESTING: This PR relies on the SMV fix for 'metric' jobs https://github.com/elastic/kibana/pull/176354 If that fix has not been merged, you will need to find `getAnomalyRecordsSchema` definition and add `functionDescription: schema.maybe(schema.nullable(schema.string())),` to it for local testing. ### Screenshots of feature image image image image ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] 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)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] 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)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../ml/anomaly_utils/anomaly_utils.ts | 4 + .../services/field_format_service.ts | 80 +- .../services/field_format_service_factory.ts | 17 + .../services/forecast_service.d.ts | 2 + .../services/forecast_service_provider.ts | 395 ++++++++ .../services/results_service/index.ts | 13 + .../plot_function_controls.tsx | 12 +- .../series_controls/series_controls.tsx | 38 +- .../timeseries_chart/timeseries_chart.js | 62 +- .../timeseries_chart_with_tooltip.tsx | 13 +- .../get_controls_for_detector.ts | 7 +- .../get_function_description.ts | 5 +- .../timeseriesexplorer/timeseriesexplorer.js | 45 +- .../timeseriesexplorer_constants.ts | 4 +- .../index.ts | 8 + .../timeseriesexplorer_checkbox.tsx | 25 + .../timeseriesexplorer_embeddable_chart.js | 897 ++++++++++++++++++ .../timeseriesexplorer_help_popover.tsx | 20 +- .../get_focus_data.ts | 14 +- .../get_timeseriesexplorer_default_state.ts | 46 + .../timeseriesexplorer_utils/index.ts | 1 + .../time_series_search_service.ts | 187 ++++ .../public/application/util/index_service.ts | 55 ++ .../public/application/util/time_buckets.d.ts | 1 + .../application/util/time_buckets_service.ts | 57 ++ .../util/time_series_explorer_service.ts | 648 +++++++++++++ .../common/resolve_job_selection.tsx | 5 +- .../ml/public/embeddables/constants.ts | 1 + x-pack/plugins/ml/public/embeddables/index.ts | 5 +- .../single_metric_viewer/_index.scss | 6 + ...eddable_single_metric_viewer_container.tsx | 204 ++++ ...le_single_metric_viewer_container_lazy.tsx | 12 + .../embeddables/single_metric_viewer/index.ts | 8 + .../single_metric_viewer_embeddable.tsx | 136 +++ ...single_metric_viewer_embeddable_factory.ts | 131 +++ .../single_metric_viewer_initializer.tsx | 157 +++ .../single_metric_viewer_setup_flyout.tsx | 75 ++ ...use_single_metric_viewer_input_resolver.ts | 46 + x-pack/plugins/ml/public/embeddables/types.ts | 35 + 39 files changed, 3341 insertions(+), 136 deletions(-) create mode 100644 x-pack/plugins/ml/public/application/services/field_format_service_factory.ts create mode 100644 x-pack/plugins/ml/public/application/services/forecast_service_provider.ts create mode 100644 x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/index.ts create mode 100644 x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_checkbox.tsx create mode 100644 x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js create mode 100644 x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_timeseriesexplorer_default_state.ts create mode 100644 x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service.ts create mode 100644 x-pack/plugins/ml/public/application/util/index_service.ts create mode 100644 x-pack/plugins/ml/public/application/util/time_buckets_service.ts create mode 100644 x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/_index.scss create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container.tsx create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container_lazy.tsx create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/index.ts create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.ts create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx create mode 100644 x-pack/plugins/ml/public/embeddables/single_metric_viewer/use_single_metric_viewer_input_resolver.ts diff --git a/x-pack/packages/ml/anomaly_utils/anomaly_utils.ts b/x-pack/packages/ml/anomaly_utils/anomaly_utils.ts index 4865aed1e4e97..8ef9fee14a273 100644 --- a/x-pack/packages/ml/anomaly_utils/anomaly_utils.ts +++ b/x-pack/packages/ml/anomaly_utils/anomaly_utils.ts @@ -59,6 +59,10 @@ export interface MlEntityField { * Optional entity field operation */ operation?: MlEntityFieldOperation; + /** + * Optional cardinality of field + */ + cardinality?: number; } // List of function descriptions for which actual values from record level results should be displayed. diff --git a/x-pack/plugins/ml/public/application/services/field_format_service.ts b/x-pack/plugins/ml/public/application/services/field_format_service.ts index a43e134f84cfb..8519a13e7d7bc 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service.ts @@ -8,16 +8,20 @@ import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; import { getDataViewById, getDataViewIdFromName } from '../util/index_utils'; import { mlJobService } from './job_service'; +import type { MlIndexUtils } from '../util/index_service'; +import type { MlApiServices } from './ml_api_service'; type FormatsByJobId = Record; type IndexPatternIdsByJob = Record; // Service for accessing FieldFormat objects configured for a Kibana data view // for use in formatting the actual and typical values from anomalies. -class FieldFormatService { +export class FieldFormatService { indexPatternIdsByJob: IndexPatternIdsByJob = {}; formatsByJob: FormatsByJobId = {}; + constructor(private mlApiServices?: MlApiServices, private mlIndexUtils?: MlIndexUtils) {} + // Populate the service with the FieldFormats for the list of jobs with the // specified IDs. List of Kibana data views is passed, with a title // attribute set in each pattern which will be compared to the indices @@ -32,10 +36,17 @@ class FieldFormatService { ( await Promise.all( jobIds.map(async (jobId) => { - const jobObj = mlJobService.getJob(jobId); + const getDataViewId = this.mlIndexUtils?.getDataViewIdFromName ?? getDataViewIdFromName; + let jobObj; + if (this.mlApiServices) { + const { jobs } = await this.mlApiServices.getJobs({ jobId }); + jobObj = jobs[0]; + } else { + jobObj = mlJobService.getJob(jobId); + } return { jobId, - dataViewId: await getDataViewIdFromName(jobObj.datafeed_config.indices.join(',')), + dataViewId: await getDataViewId(jobObj.datafeed_config!.indices.join(',')), }; }) ) @@ -68,41 +79,40 @@ class FieldFormatService { } } - getFormatsForJob(jobId: string): Promise { - return new Promise((resolve, reject) => { - const jobObj = mlJobService.getJob(jobId); - const detectors = jobObj.analysis_config.detectors || []; - const formatsByDetector: any[] = []; + async getFormatsForJob(jobId: string): Promise { + let jobObj; + const getDataView = this.mlIndexUtils?.getDataViewById ?? getDataViewById; + if (this.mlApiServices) { + const { jobs } = await this.mlApiServices.getJobs({ jobId }); + jobObj = jobs[0]; + } else { + jobObj = mlJobService.getJob(jobId); + } + const detectors = jobObj.analysis_config.detectors || []; + const formatsByDetector: any[] = []; - const dataViewId = this.indexPatternIdsByJob[jobId]; - if (dataViewId !== undefined) { - // Load the full data view configuration to obtain the formats of each field. - getDataViewById(dataViewId) - .then((dataView) => { - // Store the FieldFormat for each job by detector_index. - const fieldList = dataView.fields; - detectors.forEach((dtr) => { - const esAgg = mlFunctionToESAggregation(dtr.function); - // distinct_count detectors should fall back to the default - // formatter as the values are just counts. - if (dtr.field_name !== undefined && esAgg !== 'cardinality') { - const field = fieldList.getByName(dtr.field_name); - if (field !== undefined) { - formatsByDetector[dtr.detector_index!] = dataView.getFormatterForField(field); - } - } - }); + const dataViewId = this.indexPatternIdsByJob[jobId]; + if (dataViewId !== undefined) { + // Load the full data view configuration to obtain the formats of each field. + const dataView = await getDataView(dataViewId); + // Store the FieldFormat for each job by detector_index. + const fieldList = dataView.fields; + detectors.forEach((dtr) => { + const esAgg = mlFunctionToESAggregation(dtr.function); + // distinct_count detectors should fall back to the default + // formatter as the values are just counts. + if (dtr.field_name !== undefined && esAgg !== 'cardinality') { + const field = fieldList.getByName(dtr.field_name); + if (field !== undefined) { + formatsByDetector[dtr.detector_index!] = dataView.getFormatterForField(field); + } + } + }); + } - resolve(formatsByDetector); - }) - .catch((err) => { - reject(err); - }); - } else { - resolve(formatsByDetector); - } - }); + return formatsByDetector; } } export const mlFieldFormatService = new FieldFormatService(); +export type MlFieldFormatService = typeof mlFieldFormatService; diff --git a/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts b/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts new file mode 100644 index 0000000000000..daefab69154c5 --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/field_format_service_factory.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 { type MlFieldFormatService, FieldFormatService } from './field_format_service'; +import type { MlIndexUtils } from '../util/index_service'; +import type { MlApiServices } from './ml_api_service'; + +export function fieldFormatServiceFactory( + mlApiServices: MlApiServices, + mlIndexUtils: MlIndexUtils +): MlFieldFormatService { + return new FieldFormatService(mlApiServices, mlIndexUtils); +} diff --git a/x-pack/plugins/ml/public/application/services/forecast_service.d.ts b/x-pack/plugins/ml/public/application/services/forecast_service.d.ts index 0bfd8f56385d6..55df37b2307da 100644 --- a/x-pack/plugins/ml/public/application/services/forecast_service.d.ts +++ b/x-pack/plugins/ml/public/application/services/forecast_service.d.ts @@ -32,3 +32,5 @@ export const mlForecastService: { getForecastDateRange: (job: Job, forecastId: string) => Promise; }; + +export type MlForecastService = typeof mlForecastService; diff --git a/x-pack/plugins/ml/public/application/services/forecast_service_provider.ts b/x-pack/plugins/ml/public/application/services/forecast_service_provider.ts new file mode 100644 index 0000000000000..c776a79a6f475 --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/forecast_service_provider.ts @@ -0,0 +1,395 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// Service for carrying out requests to run ML forecasts and to obtain +// data on forecasts that have been performed. +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { get, find, each } from 'lodash'; +import { map } from 'rxjs/operators'; +import type { MlApiServices } from './ml_api_service'; +import type { Job } from '../../../common/types/anomaly_detection_jobs'; + +export interface AggType { + avg: string; + max: string; + min: string; +} + +// TODO Consolidate with legacy code in +// `x-pack/plugins/ml/public/application/services/forecast_service.js` and +// `x-pack/plugins/ml/public/application/services/forecast_service.d.ts`. +export function forecastServiceProvider(mlApiServices: MlApiServices) { + return { + // Gets a basic summary of the most recently run forecasts for the specified + // job, with results at or later than the supplied timestamp. + // Extra query object can be supplied, or pass null if no additional query. + // Returned response contains a forecasts property, which is an array of objects + // containing id, earliest and latest keys. + getForecastsSummary(job: Job, query: any, earliestMs: number, maxResults: any) { + return new Promise((resolve, reject) => { + const obj: { success: boolean; forecasts: Record } = { + success: true, + forecasts: [], + }; + + // Build the criteria to use in the bool filter part of the request. + // Add criteria for the job ID, result type and earliest time, plus + // the additional query if supplied. + const filterCriteria = [ + { + term: { result_type: 'model_forecast_request_stats' }, + }, + { + term: { job_id: job.job_id }, + }, + { + range: { + timestamp: { + gte: earliestMs, + format: 'epoch_millis', + }, + }, + }, + ]; + + if (query) { + filterCriteria.push(query); + } + + mlApiServices.results + .anomalySearch( + { + // @ts-expect-error SearchRequest type has not been updated to include size + size: maxResults, + body: { + query: { + bool: { + filter: filterCriteria, + }, + }, + sort: [{ forecast_create_timestamp: { order: 'desc' } }], + }, + }, + [job.job_id] + ) + .then((resp) => { + if (resp.hits.total.value > 0) { + obj.forecasts = resp.hits.hits.map((hit) => hit._source); + } + + resolve(obj); + }) + .catch((resp) => { + reject(resp); + }); + }); + }, + // Obtains the earliest and latest timestamps for the forecast data from + // the forecast with the specified ID. + // Returned response contains earliest and latest properties which are the + // timestamps of the first and last model_forecast results. + getForecastDateRange(job: Job, forecastId: string) { + return new Promise((resolve, reject) => { + const obj = { + success: true, + earliest: null, + latest: null, + }; + + // Build the criteria to use in the bool filter part of the request. + // Add criteria for the job ID, forecast ID, result type and time range. + const filterCriteria = [ + { + query_string: { + query: 'result_type:model_forecast', + analyze_wildcard: true, + }, + }, + { + term: { job_id: job.job_id }, + }, + { + term: { forecast_id: forecastId }, + }, + ]; + + // TODO - add in criteria for detector index and entity fields (by, over, partition) + // once forecasting with these parameters is supported. + + mlApiServices.results + .anomalySearch( + { + // @ts-expect-error SearchRequest type has not been updated to include size + size: 0, + body: { + query: { + bool: { + filter: filterCriteria, + }, + }, + aggs: { + earliest: { + min: { + field: 'timestamp', + }, + }, + latest: { + max: { + field: 'timestamp', + }, + }, + }, + }, + }, + [job.job_id] + ) + .then((resp) => { + obj.earliest = get(resp, 'aggregations.earliest.value', null); + obj.latest = get(resp, 'aggregations.latest.value', null); + if (obj.earliest === null || obj.latest === null) { + reject(resp); + } else { + resolve(obj); + } + }) + .catch((resp) => { + reject(resp); + }); + }); + }, + // Obtains the requested forecast model data for the forecast with the specified ID. + getForecastData( + job: Job, + detectorIndex: number, + forecastId: string, + entityFields: any, + earliestMs: number, + latestMs: number, + intervalMs: number, + aggType?: AggType + ) { + // Extract the partition, by, over fields on which to filter. + const criteriaFields = []; + const detector = job.analysis_config.detectors[detectorIndex]; + if (detector.partition_field_name !== undefined) { + const partitionEntity = find(entityFields, { fieldName: detector.partition_field_name }); + if (partitionEntity !== undefined) { + criteriaFields.push( + { fieldName: 'partition_field_name', fieldValue: partitionEntity.fieldName }, + { fieldName: 'partition_field_value', fieldValue: partitionEntity.fieldValue } + ); + } + } + + if (detector.over_field_name !== undefined) { + const overEntity = find(entityFields, { fieldName: detector.over_field_name }); + if (overEntity !== undefined) { + criteriaFields.push( + { fieldName: 'over_field_name', fieldValue: overEntity.fieldName }, + { fieldName: 'over_field_value', fieldValue: overEntity.fieldValue } + ); + } + } + + if (detector.by_field_name !== undefined) { + const byEntity = find(entityFields, { fieldName: detector.by_field_name }); + if (byEntity !== undefined) { + criteriaFields.push( + { fieldName: 'by_field_name', fieldValue: byEntity.fieldName }, + { fieldName: 'by_field_value', fieldValue: byEntity.fieldValue } + ); + } + } + + const obj: { success: boolean; results: Record } = { + success: true, + results: {}, + }; + + // Build the criteria to use in the bool filter part of the request. + // Add criteria for the job ID, forecast ID, detector index, result type and time range. + const filterCriteria: estypes.QueryDslQueryContainer[] = [ + { + query_string: { + query: 'result_type:model_forecast', + analyze_wildcard: true, + }, + }, + { + term: { job_id: job.job_id }, + }, + { + term: { forecast_id: forecastId }, + }, + { + term: { detector_index: detectorIndex }, + }, + { + range: { + timestamp: { + gte: earliestMs, + lte: latestMs, + format: 'epoch_millis', + }, + }, + }, + ]; + + // Add in term queries for each of the specified criteria. + each(criteriaFields, (criteria) => { + filterCriteria.push({ + term: { + [criteria.fieldName]: criteria.fieldValue, + }, + }); + }); + + // If an aggType object has been passed in, use it. + // Otherwise default to avg, min and max aggs for the + // forecast prediction, upper and lower + const forecastAggs = + aggType === undefined + ? { avg: 'avg', max: 'max', min: 'min' } + : { + avg: aggType.avg, + max: aggType.max, + min: aggType.min, + }; + + return mlApiServices.results + .anomalySearch$( + { + // @ts-expect-error SearchRequest type has not been updated to include size + size: 0, + body: { + query: { + bool: { + filter: filterCriteria, + }, + }, + aggs: { + times: { + date_histogram: { + field: 'timestamp', + fixed_interval: `${intervalMs}ms`, + min_doc_count: 1, + }, + aggs: { + prediction: { + [forecastAggs.avg]: { + field: 'forecast_prediction', + }, + }, + forecastUpper: { + [forecastAggs.max]: { + field: 'forecast_upper', + }, + }, + forecastLower: { + [forecastAggs.min]: { + field: 'forecast_lower', + }, + }, + }, + }, + }, + }, + }, + [job.job_id] + ) + .pipe( + map((resp) => { + const aggregationsByTime = get(resp, ['aggregations', 'times', 'buckets'], []); + each(aggregationsByTime, (dataForTime) => { + const time = dataForTime.key; + obj.results[time] = { + prediction: get(dataForTime, ['prediction', 'value']), + forecastUpper: get(dataForTime, ['forecastUpper', 'value']), + forecastLower: get(dataForTime, ['forecastLower', 'value']), + }; + }); + + return obj; + }) + ); + }, + // Runs a forecast + runForecast(jobId: string, duration?: string) { + // eslint-disable-next-line no-console + console.log('ML forecast service run forecast with duration:', duration); + return new Promise((resolve, reject) => { + mlApiServices + .forecast({ + jobId, + duration, + }) + .then((resp) => { + resolve(resp); + }) + .catch((err) => { + reject(err); + }); + }); + }, + // Gets stats for a forecast that has been run on the specified job. + // Returned response contains a stats property, including + // forecast_progress (a value from 0 to 1), + // and forecast_status ('finished' when complete) properties. + getForecastRequestStats(job: Job, forecastId: string) { + return new Promise((resolve, reject) => { + const obj = { + success: true, + stats: {}, + }; + + // Build the criteria to use in the bool filter part of the request. + // Add criteria for the job ID, result type and earliest time. + const filterCriteria = [ + { + query_string: { + query: 'result_type:model_forecast_request_stats', + analyze_wildcard: true, + }, + }, + { + term: { job_id: job.job_id }, + }, + { + term: { forecast_id: forecastId }, + }, + ]; + + mlApiServices.results + .anomalySearch( + { + // @ts-expect-error SearchRequest type has not been updated to include size + size: 1, + body: { + query: { + bool: { + filter: filterCriteria, + }, + }, + }, + }, + [job.job_id] + ) + .then((resp) => { + if (resp.hits.total.value > 0) { + obj.stats = resp.hits.hits[0]._source; + } + resolve(obj); + }) + .catch((resp) => { + reject(resp); + }); + }); + }, + }; +} + +export type MlForecastService = ReturnType; diff --git a/x-pack/plugins/ml/public/application/services/results_service/index.ts b/x-pack/plugins/ml/public/application/services/results_service/index.ts index 4fe6b7add2a6b..883b54dd73e72 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/index.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/index.ts @@ -5,9 +5,11 @@ * 2.0. */ +import { useMemo } from 'react'; import { resultsServiceRxProvider } from './result_service_rx'; import { resultsServiceProvider } from './results_service'; import { ml, MlApiServices } from '../ml_api_service'; +import { useMlKibana } from '../../contexts/kibana'; export type MlResultsService = typeof mlResultsService; @@ -29,3 +31,14 @@ export function mlResultsServiceProvider(mlApiServices: MlApiServices) { ...resultsServiceRxProvider(mlApiServices), }; } + +export function useMlResultsService(): MlResultsService { + const { + services: { + mlServices: { mlApiServices }, + }, + } = useMlKibana(); + + const resultsService = useMemo(() => mlResultsServiceProvider(mlApiServices), [mlApiServices]); + return resultsService; +} diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/plot_function_controls/plot_function_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/plot_function_controls/plot_function_controls.tsx index c707bbee2c5b9..493e74755588b 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/plot_function_controls/plot_function_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/plot_function_controls/plot_function_controls.tsx @@ -9,9 +9,11 @@ import React, { useCallback, useEffect } from 'react'; import { EuiFlexItem, EuiFormRow, EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ML_JOB_AGGREGATION } from '@kbn/ml-anomaly-utils'; +import { MlJob } from '@elastic/elasticsearch/lib/api/types'; import { mlJobService } from '../../../services/job_service'; import { getFunctionDescription, isMetricDetector } from '../../get_function_description'; import { useToastNotificationService } from '../../../services/toast_notification_service'; +import { useMlResultsService } from '../../../services/results_service'; import type { CombinedJob } from '../../../../../common/types/anomaly_detection_jobs'; const plotByFunctionOptions = [ @@ -36,6 +38,7 @@ const plotByFunctionOptions = [ ]; export const PlotByFunctionControls = ({ functionDescription, + job, setFunctionDescription, selectedDetectorIndex, selectedJobId, @@ -43,6 +46,7 @@ export const PlotByFunctionControls = ({ entityControlsCount, }: { functionDescription: undefined | string; + job?: CombinedJob | MlJob; setFunctionDescription: (func: string) => void; selectedDetectorIndex: number; selectedJobId: string; @@ -50,6 +54,7 @@ export const PlotByFunctionControls = ({ entityControlsCount: number; }) => { const toastNotificationService = useToastNotificationService(); + const mlResultsService = useMlResultsService(); const getFunctionDescriptionToPlot = useCallback( async ( @@ -65,18 +70,19 @@ export const PlotByFunctionControls = ({ selectedJobId: _selectedJobId, selectedJob: _selectedJob, }, - toastNotificationService + toastNotificationService, + mlResultsService ); setFunctionDescription(functionToPlot); }, - [setFunctionDescription, toastNotificationService] + [setFunctionDescription, toastNotificationService, mlResultsService] ); useEffect(() => { if (functionDescription !== undefined) { return; } - const selectedJob = mlJobService.getJob(selectedJobId); + const selectedJob = (job ?? mlJobService.getJob(selectedJobId)) as CombinedJob; // if no controls, it's okay to fetch // if there are series controls, only fetch if user has selected something const validEntities = diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx index 23bc2f80eb1a8..666d56f15fbc8 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx @@ -12,9 +12,10 @@ import { debounce } from 'lodash'; import { lastValueFrom } from 'rxjs'; import { useStorage } from '@kbn/ml-local-storage'; import type { MlEntityFieldType } from '@kbn/ml-anomaly-utils'; +import { MlJob } from '@elastic/elasticsearch/lib/api/types'; import { EntityControl } from '../entity_control'; import { mlJobService } from '../../../services/job_service'; -import { Detector, JobId } from '../../../../../common/types/anomaly_detection_jobs'; +import { CombinedJob, Detector, JobId } from '../../../../../common/types/anomaly_detection_jobs'; import { useMlKibana } from '../../../contexts/kibana'; import { APP_STATE_ACTION } from '../../timeseriesexplorer_constants'; import { @@ -67,12 +68,13 @@ const getDefaultFieldConfig = ( }; interface SeriesControlsProps { - selectedDetectorIndex: number; - selectedJobId: JobId; - bounds: any; appStateHandler: Function; + bounds: any; + functionDescription?: string; + job?: CombinedJob | MlJob; + selectedDetectorIndex: number; selectedEntities: Record; - functionDescription: string; + selectedJobId: JobId; setFunctionDescription: (func: string) => void; } @@ -80,13 +82,14 @@ interface SeriesControlsProps { * Component for handling the detector and entities controls. */ export const SeriesControls: FC = ({ - bounds, - selectedDetectorIndex, - selectedJobId, appStateHandler, + bounds, children, - selectedEntities, functionDescription, + job, + selectedDetectorIndex, + selectedEntities, + selectedJobId, setFunctionDescription, }) => { const { @@ -97,7 +100,11 @@ export const SeriesControls: FC = ({ }, } = useMlKibana(); - const selectedJob = useMemo(() => mlJobService.getJob(selectedJobId), [selectedJobId]); + const selectedJob: CombinedJob | MlJob = useMemo( + () => job ?? mlJobService.getJob(selectedJobId), + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedJobId] + ); const isModelPlotEnabled = !!selectedJob.model_plot_config?.enabled; @@ -108,11 +115,17 @@ export const SeriesControls: FC = ({ index: number; detector_description: Detector['detector_description']; }> = useMemo(() => { - return getViewableDetectors(selectedJob); + return getViewableDetectors(selectedJob as CombinedJob); }, [selectedJob]); const entityControls = useMemo(() => { - return getControlsForDetector(selectedDetectorIndex, selectedEntities, selectedJobId); + return getControlsForDetector( + selectedDetectorIndex, + selectedEntities, + selectedJobId, + selectedJob as CombinedJob + ); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedDetectorIndex, selectedEntities, selectedJobId]); const [storageFieldsConfig, setStorageFieldsConfig] = useStorage< @@ -318,6 +331,7 @@ export const SeriesControls: FC = ({ ); })} `anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore).id}`); // Add rectangular markers for any scheduled events. - const scheduledEventMarkers = d3 + const scheduledEventMarkers = chartElement .select('.focus-chart-markers') .selectAll('.scheduled-event-marker') .data(data.filter((d) => d.scheduledEvents !== undefined)); @@ -898,7 +915,7 @@ class TimeseriesChartIntl extends Component { .attr('d', this.focusValuesLine(focusForecastData)) .classed('hidden', !showForecast); - const forecastDots = d3 + const forecastDots = chartElement .select('.focus-chart-markers.forecast') .selectAll('.metric-value') .data(focusForecastData); @@ -1007,7 +1024,7 @@ class TimeseriesChartIntl extends Component { const chartElement = d3.select(this.rootNode); chartElement.selectAll('.focus-zoom a').on('click', function () { d3.event.preventDefault(); - setZoomInterval(d3.select(this).attr('data-ms')); + setZoomInterval(this.getAttribute('data-ms')); }); } @@ -1129,7 +1146,7 @@ class TimeseriesChartIntl extends Component { .attr('y2', brushChartHeight); // Add x axis. - const timeBuckets = getTimeBucketsFromCache(); + const timeBuckets = this.getTimeBuckets(); timeBuckets.setInterval('auto'); timeBuckets.setBounds(bounds); const xAxisTickFormat = timeBuckets.getScaledDateFormat(); @@ -1328,6 +1345,7 @@ class TimeseriesChartIntl extends Component {
`); + const that = this; function brushing() { const brushExtent = brush.extent(); mask.reveal(brushExtent); @@ -1345,11 +1363,11 @@ class TimeseriesChartIntl extends Component { topBorder.attr('width', topBorderWidth); const isEmpty = brush.empty(); - d3.selectAll('.brush-handle').style('visibility', isEmpty ? 'hidden' : 'visible'); + const chartElement = d3.select(that.rootNode); + chartElement.selectAll('.brush-handle').style('visibility', isEmpty ? 'hidden' : 'visible'); } brushing(); - const that = this; function brushed() { const isEmpty = brush.empty(); const selectedBounds = isEmpty ? contextXScale.domain() : brush.extent(); @@ -1478,18 +1496,19 @@ class TimeseriesChartIntl extends Component { // Sets the extent of the brush on the context chart to the // supplied from and to Date objects. setContextBrushExtent = (from, to) => { + const chartElement = d3.select(this.rootNode); const brush = this.brush; const brushExtent = brush.extent(); const newExtent = [from, to]; brush.extent(newExtent); - brush(d3.select('.brush')); + brush(chartElement.select('.brush')); if ( newExtent[0].getTime() !== brushExtent[0].getTime() || newExtent[1].getTime() !== brushExtent[1].getTime() ) { - brush.event(d3.select('.brush')); + brush.event(chartElement.select('.brush')); } }; @@ -1867,12 +1886,13 @@ class TimeseriesChartIntl extends Component { anomalyTime, focusAggregationInterval ); + const chartElement = d3.select(this.rootNode); // Render an additional highlighted anomaly marker on the focus chart. // TODO - plot anomaly markers for cases where there is an anomaly due // to the absence of data and model plot is enabled. if (markerToSelect !== undefined) { - const selectedMarker = d3 + const selectedMarker = chartElement .select('.focus-chart-markers') .selectAll('.focus-chart-highlighted-marker') .data([markerToSelect]); @@ -1905,7 +1925,6 @@ class TimeseriesChartIntl extends Component { // Display the chart tooltip for this marker. // Note the values of the record and marker may differ depending on the levels of aggregation. - const chartElement = d3.select(this.rootNode); const anomalyMarker = chartElement.selectAll( '.focus-chart-markers .anomaly-marker.highlighted' ); @@ -1916,7 +1935,8 @@ class TimeseriesChartIntl extends Component { } unhighlightFocusChartAnomaly() { - d3.select('.focus-chart-markers').selectAll('.anomaly-marker.highlighted').remove(); + const chartElement = d3.select(this.rootNode); + chartElement.select('.focus-chart-markers').selectAll('.anomaly-marker.highlighted').remove(); this.props.tooltipService.hide(); } diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx index 66da1e4222887..b9e09158bf280 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx @@ -15,7 +15,7 @@ import { CombinedJob } from '../../../../../common/types/anomaly_detection_jobs' import { ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE } from '../../../../../common/constants/search'; import { Annotation } from '../../../../../common/types/annotations'; import { useMlKibana, useNotifications } from '../../../contexts/kibana'; -import { getBoundsRoundedToInterval } from '../../../util/time_buckets'; +import { useTimeBucketsService } from '../../../util/time_buckets_service'; import { getControlsForDetector } from '../../get_controls_for_detector'; import { MlAnnotationUpdatesContext } from '../../../contexts/ml/ml_annotation_updates_context'; import { SourceIndicesWithGeoFields } from '../../../explorer/explorer_utils'; @@ -23,6 +23,7 @@ import { SourceIndicesWithGeoFields } from '../../../explorer/explorer_utils'; interface TimeSeriesChartWithTooltipsProps { bounds: any; detectorIndex: number; + embeddableMode?: boolean; renderFocusChartOnly: boolean; selectedJob: CombinedJob; selectedEntities: Record; @@ -41,6 +42,7 @@ interface TimeSeriesChartWithTooltipsProps { export const TimeSeriesChartWithTooltips: FC = ({ bounds, detectorIndex, + embeddableMode, renderFocusChartOnly, selectedJob, selectedEntities, @@ -80,13 +82,19 @@ export const TimeSeriesChartWithTooltips: FC = // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const mlTimeBucketsService = useTimeBucketsService(); + useEffect(() => { let unmounted = false; const entities = getControlsForDetector(detectorIndex, selectedEntities, selectedJob.job_id); const nonBlankEntities = Array.isArray(entities) ? entities.filter((entity) => entity.fieldValue !== null) : undefined; - const searchBounds = getBoundsRoundedToInterval(bounds, contextAggregationInterval, false); + const searchBounds = mlTimeBucketsService.getBoundsRoundedToInterval( + bounds, + contextAggregationInterval, + false + ); /** * Loads the full list of annotations for job without any aggs or time boundaries @@ -138,6 +146,7 @@ export const TimeSeriesChartWithTooltips: FC = annotationData={annotationData} bounds={bounds} detectorIndex={detectorIndex} + embeddableMode={embeddableMode} renderFocusChartOnly={renderFocusChartOnly} selectedJob={selectedJob} showAnnotations={showAnnotations} diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/get_controls_for_detector.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/get_controls_for_detector.ts index cf8e1f0aa989c..30f097dabb8ab 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/get_controls_for_detector.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/get_controls_for_detector.ts @@ -7,7 +7,7 @@ import { mlJobService } from '../services/job_service'; import { Entity } from './components/entity_control/entity_control'; -import { JobId } from '../../../common/types/anomaly_detection_jobs'; +import type { JobId, CombinedJob } from '../../../common/types/anomaly_detection_jobs'; /** * Extracts entities from the detector configuration @@ -15,9 +15,10 @@ import { JobId } from '../../../common/types/anomaly_detection_jobs'; export function getControlsForDetector( selectedDetectorIndex: number, selectedEntities: Record, - selectedJobId: JobId + selectedJobId: JobId, + job?: CombinedJob ): Entity[] { - const selectedJob = mlJobService.getJob(selectedJobId); + const selectedJob = job ?? mlJobService.getJob(selectedJobId); const entities: Entity[] = []; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/get_function_description.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/get_function_description.ts index d0dfdc9ed372b..e6f1a2ec65afd 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/get_function_description.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/get_function_description.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { lastValueFrom } from 'rxjs'; import { ES_AGGREGATION, ML_JOB_AGGREGATION } from '@kbn/ml-anomaly-utils'; -import { mlResultsService } from '../services/results_service'; +import { type MlResultsService } from '../services/results_service'; import { ToastNotificationService } from '../services/toast_notification_service'; import { getControlsForDetector } from './get_controls_for_detector'; import { getCriteriaFields } from './get_criteria_fields'; @@ -41,7 +41,8 @@ export const getFunctionDescription = async ( selectedJobId: string; selectedJob: CombinedJob; }, - toastNotificationService: ToastNotificationService + toastNotificationService: ToastNotificationService, + mlResultsService: MlResultsService ) => { // if the detector's function is metric, fetch the highest scoring anomaly record // and set to plot the function_description (avg/min/max) of that record by default diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index 757f4cb06543e..ad3f71e5df22d 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -77,6 +77,7 @@ import { processMetricPlotResults, processRecordScoreResults, getFocusData, + getTimeseriesexplorerDefaultState, } from './timeseriesexplorer_utils'; import { ANOMALY_DETECTION_DEFAULT_TIME_RANGE } from '../../../common/constants/settings'; import { getControlsForDetector } from './get_controls_for_detector'; @@ -96,46 +97,6 @@ const allValuesLabel = i18n.translate('xpack.ml.timeSeriesExplorer.allPartitionV defaultMessage: 'all', }); -function getTimeseriesexplorerDefaultState() { - return { - chartDetails: undefined, - contextAggregationInterval: undefined, - contextChartData: undefined, - contextForecastData: undefined, - // Not chartable if e.g. model plot with terms for a varp detector - dataNotChartable: false, - entitiesLoading: false, - entityValues: {}, - focusAnnotationData: [], - focusAggregationInterval: {}, - focusChartData: undefined, - focusForecastData: undefined, - fullRefresh: true, - hasResults: false, - // Counter to keep track of what data sets have been loaded. - loadCounter: 0, - loading: false, - modelPlotEnabled: false, - // Toggles display of annotations in the focus chart - showAnnotations: true, - showAnnotationsCheckbox: true, - // Toggles display of forecast data in the focus chart - showForecast: true, - showForecastCheckbox: false, - // Toggles display of model bounds in the focus chart - showModelBounds: true, - showModelBoundsCheckbox: false, - svgWidth: 0, - tableData: undefined, - zoomFrom: undefined, - zoomTo: undefined, - zoomFromFocusLoaded: undefined, - zoomToFocusLoaded: undefined, - chartDataError: undefined, - sourceIndicesWithGeoFields: {}, - }; -} - const containerPadding = 34; export class TimeSeriesExplorer extends React.Component { @@ -265,7 +226,7 @@ export class TimeSeriesExplorer extends React.Component { } /** - * Gets focus data for the current component state/ + * Gets focus data for the current component state */ getFocusData(selection) { const { selectedJobId, selectedForecastId, selectedDetectorIndex, functionDescription } = @@ -745,7 +706,6 @@ export class TimeSeriesExplorer extends React.Component { ); } } - // Required to redraw the time series chart when the container is resized. this.resizeChecker = new ResizeChecker(this.resizeRef.current); this.resizeChecker.on('resize', () => { @@ -1091,7 +1051,6 @@ export class TimeSeriesExplorer extends React.Component { entities={entityControls} /> )} - {arePartitioningFieldsProvided && jobs.length > 0 && (fullRefresh === false || loading === false) && diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_constants.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_constants.ts index d66dca5f565d7..5d13c73f8401f 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_constants.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_constants.ts @@ -17,7 +17,9 @@ export const APP_STATE_ACTION = { SET_ZOOM: 'SET_ZOOM', UNSET_ZOOM: 'UNSET_ZOOM', SET_FUNCTION_DESCRIPTION: 'SET_FUNCTION_DESCRIPTION', -}; +} as const; + +export type TimeseriesexplorerActionType = typeof APP_STATE_ACTION[keyof typeof APP_STATE_ACTION]; export const CHARTS_POINT_TARGET = 500; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/index.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/index.ts new file mode 100644 index 0000000000000..b81b4bc96a434 --- /dev/null +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/index.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 { TimeSeriesExplorerEmbeddableChart } from './timeseriesexplorer_embeddable_chart'; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_checkbox.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_checkbox.tsx new file mode 100644 index 0000000000000..e1136e54180ac --- /dev/null +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_checkbox.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, { FC, useMemo } from 'react'; +import { EuiCheckbox, EuiFlexItem, htmlIdGenerator } from '@elastic/eui'; + +interface Props { + id: string; + label: string; + checked: boolean; + onChange: (e: React.ChangeEvent) => void; +} + +export const TimeseriesExplorerCheckbox: FC = ({ id, label, checked, onChange }) => { + const checkboxId = useMemo(() => `id-${htmlIdGenerator()()}`, []); + return ( + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js new file mode 100644 index 0000000000000..fd6b0239199bc --- /dev/null +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js @@ -0,0 +1,897 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * React component for rendering Single Metric Viewer. + */ + +import { isEqual } from 'lodash'; +import moment from 'moment-timezone'; +import { Subject, Subscription, forkJoin } from 'rxjs'; +import { debounceTime, switchMap, tap, withLatestFrom } from 'rxjs/operators'; + +import PropTypes from 'prop-types'; +import React, { Fragment } from 'react'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { context } from '@kbn/kibana-react-plugin/public'; + +import { + EuiCallOut, + EuiCheckbox, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, + EuiTextColor, +} from '@elastic/eui'; +import { TimeSeriesExplorerHelpPopover } from '../timeseriesexplorer_help_popover'; + +import { + isModelPlotEnabled, + isModelPlotChartableForDetector, + isSourceDataChartableForDetector, +} from '../../../../common/util/job_utils'; + +import { LoadingIndicator } from '../../components/loading_indicator/loading_indicator'; +import { TimeseriesexplorerNoChartData } from '../components/timeseriesexplorer_no_chart_data'; + +import { + APP_STATE_ACTION, + CHARTS_POINT_TARGET, + TIME_FIELD_NAME, +} from '../timeseriesexplorer_constants'; +import { getControlsForDetector } from '../get_controls_for_detector'; +import { TimeSeriesChartWithTooltips } from '../components/timeseries_chart/timeseries_chart_with_tooltip'; +import { aggregationTypeTransform } from '@kbn/ml-anomaly-utils'; +import { isMetricDetector } from '../get_function_description'; +import { TimeseriesexplorerChartDataError } from '../components/timeseriesexplorer_chart_data_error'; +import { TimeseriesExplorerCheckbox } from './timeseriesexplorer_checkbox'; +import { timeBucketsServiceFactory } from '../../util/time_buckets_service'; +import { timeSeriesExplorerServiceFactory } from '../../util/time_series_explorer_service'; +import { getTimeseriesexplorerDefaultState } from '../timeseriesexplorer_utils'; + +// Used to indicate the chart is being plotted across +// all partition field values, where the cardinality of the field cannot be +// obtained as it is not aggregatable e.g. 'all distinct kpi_indicator values' +const allValuesLabel = i18n.translate('xpack.ml.timeSeriesExplorer.allPartitionValuesLabel', { + defaultMessage: 'all', +}); + +export class TimeSeriesExplorerEmbeddableChart extends React.Component { + static propTypes = { + appStateHandler: PropTypes.func.isRequired, + autoZoomDuration: PropTypes.number.isRequired, + bounds: PropTypes.object.isRequired, + chartWidth: PropTypes.number.isRequired, + lastRefresh: PropTypes.number.isRequired, + previousRefresh: PropTypes.number.isRequired, + selectedJobId: PropTypes.string.isRequired, + selectedDetectorIndex: PropTypes.number, + selectedEntities: PropTypes.object, + selectedForecastId: PropTypes.string, + zoom: PropTypes.object, + toastNotificationService: PropTypes.object, + dataViewsService: PropTypes.object, + }; + + state = getTimeseriesexplorerDefaultState(); + + subscriptions = new Subscription(); + + unmounted = false; + + /** + * Subject for listening brush time range selection. + */ + contextChart$ = new Subject(); + + /** + * Access ML services in react context. + */ + static contextType = context; + + getBoundsRoundedToInterval; + mlTimeSeriesExplorer; + + /** + * Returns field names that don't have a selection yet. + */ + getFieldNamesWithEmptyValues = () => { + const latestEntityControls = this.getControlsForDetector(); + return latestEntityControls + .filter(({ fieldValue }) => fieldValue === null) + .map(({ fieldName }) => fieldName); + }; + + /** + * Checks if all entity control dropdowns have a selection. + */ + arePartitioningFieldsProvided = () => { + const fieldNamesWithEmptyValues = this.getFieldNamesWithEmptyValues(); + return fieldNamesWithEmptyValues.length === 0; + }; + + toggleShowAnnotationsHandler = () => { + this.setState((prevState) => ({ + showAnnotations: !prevState.showAnnotations, + })); + }; + + toggleShowForecastHandler = () => { + this.setState((prevState) => ({ + showForecast: !prevState.showForecast, + })); + }; + + toggleShowModelBoundsHandler = () => { + this.setState({ + showModelBounds: !this.state.showModelBounds, + }); + }; + + setFunctionDescription = (selectedFuction) => { + this.props.appStateHandler(APP_STATE_ACTION.SET_FUNCTION_DESCRIPTION, selectedFuction); + }; + + previousChartProps = {}; + previousShowAnnotations = undefined; + previousShowForecast = undefined; + previousShowModelBounds = undefined; + + tableFilter = (field, value, operator) => { + const entities = this.getControlsForDetector(); + const entity = entities.find(({ fieldName }) => fieldName === field); + + if (entity === undefined) { + return; + } + + const { appStateHandler } = this.props; + + let resultValue = ''; + if (operator === '+' && entity.fieldValue !== value) { + resultValue = value; + } else if (operator === '-' && entity.fieldValue === value) { + resultValue = null; + } else { + return; + } + + const resultEntities = { + ...entities.reduce((appStateEntities, appStateEntity) => { + appStateEntities[appStateEntity.fieldName] = appStateEntity.fieldValue; + return appStateEntities; + }, {}), + [entity.fieldName]: resultValue, + }; + + appStateHandler(APP_STATE_ACTION.SET_ENTITIES, resultEntities); + }; + + contextChartSelectedInitCallDone = false; + + getFocusAggregationInterval(selection) { + const { selectedJob } = this.props; + + // Calculate the aggregation interval for the focus chart. + const bounds = { min: moment(selection.from), max: moment(selection.to) }; + + return this.mlTimeSeriesExplorer.calculateAggregationInterval( + bounds, + CHARTS_POINT_TARGET, + selectedJob + ); + } + + /** + * Gets focus data for the current component state + */ + getFocusData(selection) { + const { selectedForecastId, selectedDetectorIndex, functionDescription, selectedJob } = + this.props; + const { modelPlotEnabled } = this.state; + if (isMetricDetector(selectedJob, selectedDetectorIndex) && functionDescription === undefined) { + return; + } + const entityControls = this.getControlsForDetector(); + + // Calculate the aggregation interval for the focus chart. + const bounds = { min: moment(selection.from), max: moment(selection.to) }; + const focusAggregationInterval = this.getFocusAggregationInterval(selection); + + // Ensure the search bounds align to the bucketing interval so that the first and last buckets are complete. + // For sum or count detectors, short buckets would hold smaller values, and model bounds would also be affected + // to some extent with all detector functions if not searching complete buckets. + const searchBounds = this.getBoundsRoundedToInterval(bounds, focusAggregationInterval, false); + + return this.mlTimeSeriesExplorer.getFocusData( + this.getCriteriaFields(selectedDetectorIndex, entityControls), + selectedDetectorIndex, + focusAggregationInterval, + selectedForecastId, + modelPlotEnabled, + entityControls.filter((entity) => entity.fieldValue !== null), + searchBounds, + selectedJob, + functionDescription, + TIME_FIELD_NAME + ); + } + + contextChartSelected = (selection) => { + const zoomState = { + from: selection.from.toISOString(), + to: selection.to.toISOString(), + }; + + if ( + isEqual(this.props.zoom, zoomState) && + this.state.focusChartData !== undefined && + this.props.previousRefresh === this.props.lastRefresh + ) { + return; + } + + this.contextChart$.next(selection); + this.props.appStateHandler(APP_STATE_ACTION.SET_ZOOM, zoomState); + }; + + setForecastId = (forecastId) => { + this.props.appStateHandler(APP_STATE_ACTION.SET_FORECAST_ID, forecastId); + }; + + displayErrorToastMessages = (error, errorMsg) => { + if (this.props.toastNotificationService) { + this.props.toastNotificationService.displayErrorToast(error, errorMsg, 2000); + } + this.setState({ loading: false, chartDataError: errorMsg }); + }; + + loadSingleMetricData = (fullRefresh = true) => { + const { + autoZoomDuration, + bounds, + selectedDetectorIndex, + zoom, + functionDescription, + selectedJob, + } = this.props; + + const { loadCounter: currentLoadCounter } = this.state; + if (selectedJob === undefined) { + return; + } + if (isMetricDetector(selectedJob, selectedDetectorIndex) && functionDescription === undefined) { + return; + } + + const functionToPlotByIfMetric = aggregationTypeTransform.toES(functionDescription); + + this.contextChartSelectedInitCallDone = false; + + // Only when `fullRefresh` is true we'll reset all data + // and show the loading spinner within the page. + const entityControls = this.getControlsForDetector(); + this.setState( + { + fullRefresh, + loadCounter: currentLoadCounter + 1, + loading: true, + chartDataError: undefined, + ...(fullRefresh + ? { + chartDetails: undefined, + contextChartData: undefined, + contextForecastData: undefined, + focusChartData: undefined, + focusForecastData: undefined, + modelPlotEnabled: + isModelPlotChartableForDetector(selectedJob, selectedDetectorIndex) && + isModelPlotEnabled(selectedJob, selectedDetectorIndex, entityControls), + hasResults: false, + dataNotChartable: false, + } + : {}), + }, + () => { + const { loadCounter, modelPlotEnabled } = this.state; + const { selectedJob } = this.props; + + const detectorIndex = selectedDetectorIndex; + + let awaitingCount = 3; + + const stateUpdate = {}; + + // finish() function, called after each data set has been loaded and processed. + // The last one to call it will trigger the page render. + const finish = (counterVar) => { + awaitingCount--; + if (awaitingCount === 0 && counterVar === loadCounter) { + stateUpdate.hasResults = + (Array.isArray(stateUpdate.contextChartData) && + stateUpdate.contextChartData.length > 0) || + (Array.isArray(stateUpdate.contextForecastData) && + stateUpdate.contextForecastData.length > 0); + stateUpdate.loading = false; + + // Set zoomFrom/zoomTo attributes in scope which will result in the metric chart automatically + // selecting the specified range in the context chart, and so loading that date range in the focus chart. + // Only touch the zoom range if data for the context chart has been loaded and all necessary + // partition fields have a selection. + if ( + stateUpdate.contextChartData.length && + this.arePartitioningFieldsProvided() === true + ) { + // Check for a zoom parameter in the appState (URL). + let focusRange = this.mlTimeSeriesExplorer.calculateInitialFocusRange( + zoom, + stateUpdate.contextAggregationInterval, + bounds + ); + if ( + focusRange === undefined || + this.previousSelectedForecastId !== this.props.selectedForecastId + ) { + focusRange = this.mlTimeSeriesExplorer.calculateDefaultFocusRange( + autoZoomDuration, + stateUpdate.contextAggregationInterval, + stateUpdate.contextChartData, + stateUpdate.contextForecastData + ); + this.previousSelectedForecastId = this.props.selectedForecastId; + } + + this.contextChartSelected({ + from: focusRange[0], + to: focusRange[1], + }); + } + + this.setState(stateUpdate); + } + }; + + const nonBlankEntities = entityControls.filter((entity) => { + return entity.fieldValue !== null; + }); + + if ( + modelPlotEnabled === false && + isSourceDataChartableForDetector(selectedJob, detectorIndex) === false && + nonBlankEntities.length > 0 + ) { + // For detectors where model plot has been enabled with a terms filter and the + // selected entity(s) are not in the terms list, indicate that data cannot be viewed. + stateUpdate.hasResults = false; + stateUpdate.loading = false; + stateUpdate.dataNotChartable = true; + this.setState(stateUpdate); + return; + } + + // Calculate the aggregation interval for the context chart. + // Context chart swimlane will display bucket anomaly score at the same interval. + stateUpdate.contextAggregationInterval = + this.mlTimeSeriesExplorer.calculateAggregationInterval( + bounds, + CHARTS_POINT_TARGET, + selectedJob + ); + + // Ensure the search bounds align to the bucketing interval so that the first and last buckets are complete. + // For sum or count detectors, short buckets would hold smaller values, and model bounds would also be affected + // to some extent with all detector functions if not searching complete buckets. + const searchBounds = this.getBoundsRoundedToInterval( + bounds, + stateUpdate.contextAggregationInterval, + false + ); + + // Query 1 - load metric data at low granularity across full time range. + // Pass a counter flag into the finish() function to make sure we only process the results + // for the most recent call to the load the data in cases where the job selection and time filter + // have been altered in quick succession (such as from the job picker with 'Apply time range'). + const counter = loadCounter; + this.context.services.mlServices.mlTimeSeriesSearchService + .getMetricData( + selectedJob, + detectorIndex, + nonBlankEntities, + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + stateUpdate.contextAggregationInterval.asMilliseconds(), + functionToPlotByIfMetric + ) + .toPromise() + .then((resp) => { + const fullRangeChartData = this.mlTimeSeriesExplorer.processMetricPlotResults( + resp.results, + modelPlotEnabled + ); + stateUpdate.contextChartData = fullRangeChartData; + finish(counter); + }) + .catch((err) => { + const errorMsg = i18n.translate('xpack.ml.timeSeriesExplorer.metricDataErrorMessage', { + defaultMessage: 'Error getting metric data', + }); + this.displayErrorToastMessages(err, errorMsg); + }); + + // Query 2 - load max record score at same granularity as context chart + // across full time range for use in the swimlane. + this.context.services.mlServices.mlResultsService + .getRecordMaxScoreByTime( + selectedJob.job_id, + this.getCriteriaFields(detectorIndex, entityControls), + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + stateUpdate.contextAggregationInterval.asMilliseconds(), + functionToPlotByIfMetric + ) + .then((resp) => { + const fullRangeRecordScoreData = this.mlTimeSeriesExplorer.processRecordScoreResults( + resp.results + ); + stateUpdate.swimlaneData = fullRangeRecordScoreData; + finish(counter); + }) + .catch((err) => { + const errorMsg = i18n.translate( + 'xpack.ml.timeSeriesExplorer.bucketAnomalyScoresErrorMessage', + { + defaultMessage: 'Error getting bucket anomaly scores', + } + ); + + this.displayErrorToastMessages(err, errorMsg); + }); + + // Query 3 - load details on the chart used in the chart title (charting function and entity(s)). + this.context.services.mlServices.mlTimeSeriesSearchService + .getChartDetails( + selectedJob, + detectorIndex, + entityControls, + searchBounds.min.valueOf(), + searchBounds.max.valueOf() + ) + .then((resp) => { + stateUpdate.chartDetails = resp.results; + finish(counter); + }) + .catch((err) => { + this.displayErrorToastMessages( + err, + i18n.translate('xpack.ml.timeSeriesExplorer.entityCountsErrorMessage', { + defaultMessage: 'Error getting entity counts', + }) + ); + }); + } + ); + }; + + /** + * Updates local state of detector related controls from the global state. + * @param callback to invoke after a state update. + */ + getControlsForDetector = () => { + const { selectedDetectorIndex, selectedEntities, selectedJobId, selectedJob } = this.props; + return getControlsForDetector( + selectedDetectorIndex, + selectedEntities, + selectedJobId, + selectedJob + ); + }; + + /** + * Updates criteria fields for API calls, e.g. getAnomaliesTableData + * @param detectorIndex + * @param entities + */ + getCriteriaFields(detectorIndex, entities) { + // Only filter on the entity if the field has a value. + const nonBlankEntities = entities.filter((entity) => entity.fieldValue !== null); + return [ + { + fieldName: 'detector_index', + fieldValue: detectorIndex, + }, + ...nonBlankEntities, + ]; + } + + async componentDidMount() { + this.getBoundsRoundedToInterval = timeBucketsServiceFactory( + this.context.services.uiSettings + ).getBoundsRoundedToInterval; + + this.mlTimeSeriesExplorer = timeSeriesExplorerServiceFactory( + this.context.services.uiSettings, + this.context.services.mlServices.mlApiServices, + this.context.services.mlServices.mlResultsService + ); + + // Listen for context chart updates. + this.subscriptions.add( + this.contextChart$ + .pipe( + tap((selection) => { + this.setState({ + zoomFrom: selection.from, + zoomTo: selection.to, + }); + }), + debounceTime(500), + tap((selection) => { + const { + contextChartData, + contextForecastData, + focusChartData, + zoomFromFocusLoaded, + zoomToFocusLoaded, + } = this.state; + + if ( + (contextChartData === undefined || contextChartData.length === 0) && + (contextForecastData === undefined || contextForecastData.length === 0) + ) { + return; + } + + if ( + (this.contextChartSelectedInitCallDone === false && focusChartData === undefined) || + zoomFromFocusLoaded.getTime() !== selection.from.getTime() || + zoomToFocusLoaded.getTime() !== selection.to.getTime() + ) { + this.contextChartSelectedInitCallDone = true; + + this.setState({ + loading: true, + fullRefresh: false, + }); + } + }), + switchMap((selection) => { + return forkJoin([this.getFocusData(selection)]); + }), + withLatestFrom(this.contextChart$) + ) + .subscribe(([[refreshFocusData, tableData], selection]) => { + const { modelPlotEnabled } = this.state; + + // All the data is ready now for a state update. + this.setState({ + focusAggregationInterval: this.getFocusAggregationInterval({ + from: selection.from, + to: selection.to, + }), + loading: false, + showModelBoundsCheckbox: modelPlotEnabled && refreshFocusData.focusChartData.length > 0, + zoomFromFocusLoaded: selection.from, + zoomToFocusLoaded: selection.to, + ...refreshFocusData, + ...tableData, + }); + }) + ); + + if (this.context && this.props.selectedJob !== undefined) { + // Populate the map of jobs / detectors / field formatters for the selected IDs and refresh. + this.context.services.mlServices.mlFieldFormatService.populateFormats([ + this.props.selectedJob.job_id, + ]); + } + + this.componentDidUpdate(); + } + + componentDidUpdate(previousProps) { + if ( + previousProps === undefined || + previousProps.selectedForecastId !== this.props.selectedForecastId + ) { + if (this.props.selectedForecastId !== undefined) { + // Ensure the forecast data will be shown if hidden previously. + this.setState({ showForecast: true }); + // Not best practice but we need the previous value for another comparison + // once all the data was loaded. + if (previousProps !== undefined) { + this.previousSelectedForecastId = previousProps.selectedForecastId; + } + } + } + + if ( + previousProps === undefined || + !isEqual(previousProps.bounds, this.props.bounds) || + (!isEqual(previousProps.lastRefresh, this.props.lastRefresh) && + previousProps.lastRefresh !== 0) || + !isEqual(previousProps.selectedDetectorIndex, this.props.selectedDetectorIndex) || + !isEqual(previousProps.selectedEntities, this.props.selectedEntities) || + previousProps.selectedForecastId !== this.props.selectedForecastId || + previousProps.selectedJobId !== this.props.selectedJobId || + previousProps.functionDescription !== this.props.functionDescription + ) { + const fullRefresh = + previousProps === undefined || + !isEqual(previousProps.bounds, this.props.bounds) || + !isEqual(previousProps.selectedDetectorIndex, this.props.selectedDetectorIndex) || + !isEqual(previousProps.selectedEntities, this.props.selectedEntities) || + previousProps.selectedForecastId !== this.props.selectedForecastId || + previousProps.selectedJobId !== this.props.selectedJobId || + previousProps.functionDescription !== this.props.functionDescription; + this.loadSingleMetricData(fullRefresh); + } + + if (previousProps === undefined) { + return; + } + } + + componentWillUnmount() { + this.subscriptions.unsubscribe(); + this.unmounted = true; + } + + render() { + const { + autoZoomDuration, + bounds, + chartWidth, + lastRefresh, + selectedDetectorIndex, + selectedJob, + } = this.props; + + const { + chartDetails, + contextAggregationInterval, + contextChartData, + contextForecastData, + dataNotChartable, + focusAggregationInterval, + focusAnnotationData, + focusChartData, + focusForecastData, + fullRefresh, + hasResults, + loading, + modelPlotEnabled, + showAnnotations, + showAnnotationsCheckbox, + showForecast, + showForecastCheckbox, + showModelBounds, + showModelBoundsCheckbox, + swimlaneData, + zoomFrom, + zoomTo, + zoomFromFocusLoaded, + zoomToFocusLoaded, + chartDataError, + } = this.state; + const chartProps = { + modelPlotEnabled, + contextChartData, + contextChartSelected: this.contextChartSelected, + contextForecastData, + contextAggregationInterval, + swimlaneData, + focusAnnotationData, + focusChartData, + focusForecastData, + focusAggregationInterval, + svgWidth: chartWidth, + zoomFrom, + zoomTo, + zoomFromFocusLoaded, + zoomToFocusLoaded, + autoZoomDuration, + }; + + const entityControls = this.getControlsForDetector(); + const fieldNamesWithEmptyValues = this.getFieldNamesWithEmptyValues(); + const arePartitioningFieldsProvided = this.arePartitioningFieldsProvided(); + + let renderFocusChartOnly = true; + + if ( + isEqual(this.previousChartProps.focusForecastData, chartProps.focusForecastData) && + isEqual(this.previousChartProps.focusChartData, chartProps.focusChartData) && + isEqual(this.previousChartProps.focusAnnotationData, chartProps.focusAnnotationData) && + this.previousShowForecast === showForecast && + this.previousShowModelBounds === showModelBounds && + this.props.previousRefresh === lastRefresh + ) { + renderFocusChartOnly = false; + } + + this.previousChartProps = chartProps; + this.previousShowForecast = showForecast; + this.previousShowModelBounds = showModelBounds; + + return ( + <> + {fieldNamesWithEmptyValues.length > 0 && ( + <> + + } + iconType="help" + size="s" + /> + + + )} + + {fullRefresh && loading === true && ( + + )} + + {loading === false && chartDataError !== undefined && ( + + )} + + {arePartitioningFieldsProvided && + selectedJob && + (fullRefresh === false || loading === false) && + hasResults === false && + chartDataError === undefined && ( + + )} + {arePartitioningFieldsProvided && + selectedJob && + (fullRefresh === false || loading === false) && + hasResults === true && ( +
+ + + +

+ + {i18n.translate( + 'xpack.ml.timeSeriesExplorer.singleTimeSeriesAnalysisTitle', + { + defaultMessage: 'Single time series analysis of {functionLabel}', + values: { functionLabel: chartDetails.functionLabel }, + } + )} + +   + {chartDetails.entityData.count === 1 && ( + + {chartDetails.entityData.entities.length > 0 && '('} + {chartDetails.entityData.entities + .map((entity) => { + return `${entity.fieldName}: ${entity.fieldValue}`; + }) + .join(', ')} + {chartDetails.entityData.entities.length > 0 && ')'} + + )} + {chartDetails.entityData.count !== 1 && ( + + {chartDetails.entityData.entities.map((countData, i) => { + return ( + + {i18n.translate( + 'xpack.ml.timeSeriesExplorer.countDataInChartDetailsDescription', + { + defaultMessage: + '{openBrace}{cardinalityValue} distinct {fieldName} {cardinality, plural, one {} other { values}}{closeBrace}', + values: { + openBrace: i === 0 ? '(' : '', + closeBrace: + i === chartDetails.entityData.entities.length - 1 + ? ')' + : '', + cardinalityValue: + countData.cardinality === 0 + ? allValuesLabel + : countData.cardinality, + cardinality: countData.cardinality, + fieldName: countData.fieldName, + }, + } + )} + {i !== chartDetails.entityData.entities.length - 1 ? ', ' : ''} + + ); + })} + + )} +

+
+
+ + + + +
+ + {showModelBoundsCheckbox && ( + + )} + + {showAnnotationsCheckbox && ( + + )} + + {showForecastCheckbox && ( + + + {i18n.translate('xpack.ml.timeSeriesExplorer.showForecastLabel', { + defaultMessage: 'show forecast', + })} + + } + checked={showForecast} + onChange={this.toggleShowForecastHandler} + /> + + )} + + + +
+ )} + + ); + } +} diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_help_popover.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_help_popover.tsx index afd93fd5acee1..3557523c113fc 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_help_popover.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_help_popover.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import React from 'react'; +import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { HelpPopover } from '../components/help_popover/help_popover'; -export const TimeSeriesExplorerHelpPopover = () => { +export const TimeSeriesExplorerHelpPopover: FC<{ embeddableMode: boolean }> = ({ + embeddableMode, +}) => { return ( { defaultMessage="If you create a forecast, predicted data values are added to the chart. A shaded area around these values represents the confidence level; as you forecast further into the future, the confidence level generally decreases." />

-

- -

+ {!embeddableMode && ( +

+ +

+ )}

{ + if ( + isModelPlotChartableForDetector(job, detectorIndex) && + isModelPlotEnabled(job, detectorIndex, entityFields) + ) { + // Extract the partition, by, over fields on which to filter. + const criteriaFields = []; + const detector = job.analysis_config.detectors[detectorIndex]; + if (detector.partition_field_name !== undefined) { + const partitionEntity: any = find(entityFields, { + fieldName: detector.partition_field_name, + }); + if (partitionEntity !== undefined) { + criteriaFields.push( + { fieldName: 'partition_field_name', fieldValue: partitionEntity.fieldName }, + { fieldName: 'partition_field_value', fieldValue: partitionEntity.fieldValue } + ); + } + } + + if (detector.over_field_name !== undefined) { + const overEntity: any = find(entityFields, { fieldName: detector.over_field_name }); + if (overEntity !== undefined) { + criteriaFields.push( + { fieldName: 'over_field_name', fieldValue: overEntity.fieldName }, + { fieldName: 'over_field_value', fieldValue: overEntity.fieldValue } + ); + } + } + + if (detector.by_field_name !== undefined) { + const byEntity: any = find(entityFields, { fieldName: detector.by_field_name }); + if (byEntity !== undefined) { + criteriaFields.push( + { fieldName: 'by_field_name', fieldValue: byEntity.fieldName }, + { fieldName: 'by_field_value', fieldValue: byEntity.fieldValue } + ); + } + } + + return mlResultsService.getModelPlotOutput( + job.job_id, + detectorIndex, + criteriaFields, + earliestMs, + latestMs, + intervalMs + ); + } else { + const obj: ModelPlotOutput = { + success: true, + results: {}, + }; + + const chartConfig = buildConfigFromDetector(job, detectorIndex); + + return mlResultsService + .getMetricData( + chartConfig.datafeedConfig.indices.join(','), + entityFields, + chartConfig.datafeedConfig.query, + esMetricFunction ?? chartConfig.metricFunction, + chartConfig.metricFieldName, + chartConfig.summaryCountFieldName, + chartConfig.timeField, + earliestMs, + latestMs, + intervalMs, + chartConfig?.datafeedConfig + ) + .pipe( + map((resp) => { + each(resp.results, (value, time) => { + // @ts-ignore + obj.results[time] = { + actual: value, + }; + }); + return obj; + }) + ); + } + }, + // Builds chart detail information (charting function description and entity counts) used + // in the title area of the time series chart. + // Queries Elasticsearch if necessary to obtain the distinct count of entities + // for which data is being plotted. + getChartDetails( + job: Job, + detectorIndex: number, + entityFields: any[], + earliestMs: number, + latestMs: number + ) { + return new Promise((resolve, reject) => { + const obj: any = { + success: true, + results: { functionLabel: '', entityData: { entities: [] } }, + }; + + const chartConfig = buildConfigFromDetector(job, detectorIndex); + let functionLabel: string | null = chartConfig.metricFunction; + if (chartConfig.metricFieldName !== undefined) { + functionLabel += ' '; + functionLabel += chartConfig.metricFieldName; + } + obj.results.functionLabel = functionLabel; + + const blankEntityFields = filter(entityFields, (entity) => { + return entity.fieldValue === null; + }); + + // Look to see if any of the entity fields have defined values + // (i.e. blank input), and if so obtain the cardinality. + if (blankEntityFields.length === 0) { + obj.results.entityData.count = 1; + obj.results.entityData.entities = entityFields; + resolve(obj); + } else { + const entityFieldNames: string[] = blankEntityFields.map((f) => f.fieldName); + mlApiServices + .getCardinalityOfFields({ + index: chartConfig.datafeedConfig.indices.join(','), + fieldNames: entityFieldNames, + query: chartConfig.datafeedConfig.query, + timeFieldName: chartConfig.timeField, + earliestMs, + latestMs, + }) + .then((results: any) => { + each(blankEntityFields, (field) => { + // results will not contain keys for non-aggregatable fields, + // so store as 0 to indicate over all field values. + obj.results.entityData.entities.push({ + fieldName: field.fieldName, + cardinality: get(results, field.fieldName, 0), + }); + }); + + resolve(obj); + }) + .catch((resp: any) => { + reject(resp); + }); + } + }); + }, + }; +} + +export type MlTimeSeriesSeachService = ReturnType; diff --git a/x-pack/plugins/ml/public/application/util/index_service.ts b/x-pack/plugins/ml/public/application/util/index_service.ts new file mode 100644 index 0000000000000..f4b6a1fc13d77 --- /dev/null +++ b/x-pack/plugins/ml/public/application/util/index_service.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/public'; +import type { Job } from '../../../common/types/anomaly_detection_jobs'; + +// TODO Consolidate with legacy code in `ml/public/application/util/index_utils.ts`. +export function indexServiceFactory(dataViewsService: DataViewsContract) { + return { + /** + * Retrieves the data view ID from the given name. + * If a job is passed in, a temporary data view will be created if the requested data view doesn't exist. + * @param name - The name or index pattern of the data view. + * @param job - Optional job object. + * @returns The data view ID or null if it doesn't exist. + */ + async getDataViewIdFromName(name: string, job?: Job): Promise { + if (dataViewsService === null) { + throw new Error('Data views are not initialized!'); + } + const dataViews = await dataViewsService.find(name); + const dataView = dataViews.find((dv) => dv.getIndexPattern() === name); + if (!dataView) { + if (job !== undefined) { + const tempDataView = await dataViewsService.create({ + id: undefined, + name, + title: name, + timeFieldName: job.data_description.time_field!, + }); + return tempDataView.id ?? null; + } + return null; + } + return dataView.id ?? dataView.getIndexPattern(); + }, + getDataViewById(id: string): Promise { + if (dataViewsService === null) { + throw new Error('Data views are not initialized!'); + } + + if (id) { + return dataViewsService.get(id); + } else { + return dataViewsService.create({}); + } + }, + }; +} + +export type MlIndexUtils = ReturnType; diff --git a/x-pack/plugins/ml/public/application/util/time_buckets.d.ts b/x-pack/plugins/ml/public/application/util/time_buckets.d.ts index 9a5410918a099..0f413ed9c2c71 100644 --- a/x-pack/plugins/ml/public/application/util/time_buckets.d.ts +++ b/x-pack/plugins/ml/public/application/util/time_buckets.d.ts @@ -33,6 +33,7 @@ export declare class TimeBuckets { public setBounds(bounds: TimeRangeBounds): void; public getBounds(): { min: any; max: any }; public getInterval(): TimeBucketsInterval; + public getIntervalToNearestMultiple(divisorSecs: any): TimeBucketsInterval; public getScaledDateFormat(): string; } diff --git a/x-pack/plugins/ml/public/application/util/time_buckets_service.ts b/x-pack/plugins/ml/public/application/util/time_buckets_service.ts new file mode 100644 index 0000000000000..480f279a603b1 --- /dev/null +++ b/x-pack/plugins/ml/public/application/util/time_buckets_service.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMemo } from 'react'; +import type { IUiSettingsClient } from '@kbn/core/public'; +import { UI_SETTINGS } from '@kbn/data-plugin/public'; +import moment from 'moment'; +import { type TimeRangeBounds, type TimeBucketsInterval, TimeBuckets } from './time_buckets'; +import { useMlKibana } from '../contexts/kibana'; + +// TODO Consolidate with legacy code in `ml/public/application/util/time_buckets.js`. +export function timeBucketsServiceFactory(uiSettings: IUiSettingsClient) { + function getTimeBuckets(): InstanceType { + return new TimeBuckets({ + [UI_SETTINGS.HISTOGRAM_MAX_BARS]: uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + [UI_SETTINGS.HISTOGRAM_BAR_TARGET]: uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), + dateFormat: uiSettings.get('dateFormat'), + 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), + }); + } + function getBoundsRoundedToInterval( + bounds: TimeRangeBounds, + interval: TimeBucketsInterval, + inclusiveEnd: boolean = false + ): Required { + // Returns new bounds, created by flooring the min of the provided bounds to the start of + // the specified interval (a moment duration), and rounded upwards (Math.ceil) to 1ms before + // the start of the next interval (Kibana dashboards search >= bounds min, and <= bounds max, + // so we subtract 1ms off the max to avoid querying start of the new Elasticsearch aggregation bucket). + const intervalMs = interval.asMilliseconds(); + const adjustedMinMs = Math.floor(bounds.min!.valueOf() / intervalMs) * intervalMs; + let adjustedMaxMs = Math.ceil(bounds.max!.valueOf() / intervalMs) * intervalMs; + + // Don't include the start ms of the next bucket unless specified.. + if (inclusiveEnd === false) { + adjustedMaxMs = adjustedMaxMs - 1; + } + return { min: moment(adjustedMinMs), max: moment(adjustedMaxMs) }; + } + + return { getTimeBuckets, getBoundsRoundedToInterval }; +} + +export type TimeBucketsService = ReturnType; + +export function useTimeBucketsService(): TimeBucketsService { + const { + services: { uiSettings }, + } = useMlKibana(); + + const mlTimeBucketsService = useMemo(() => timeBucketsServiceFactory(uiSettings), [uiSettings]); + return mlTimeBucketsService; +} diff --git a/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts b/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts new file mode 100644 index 0000000000000..4af8d98093cbd --- /dev/null +++ b/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts @@ -0,0 +1,648 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMemo } from 'react'; +import type { IUiSettingsClient } from '@kbn/core/public'; +import { aggregationTypeTransform } from '@kbn/ml-anomaly-utils'; +import { isMultiBucketAnomaly, ML_JOB_AGGREGATION } from '@kbn/ml-anomaly-utils'; +import { extractErrorMessage } from '@kbn/ml-error-utils'; +import moment from 'moment'; +import { forkJoin, Observable, of } from 'rxjs'; +import { each, get } from 'lodash'; +import { catchError, map } from 'rxjs/operators'; +import { type MlAnomalyRecordDoc } from '@kbn/ml-anomaly-utils'; +import { parseInterval } from '../../../common/util/parse_interval'; +import type { GetAnnotationsResponse } from '../../../common/types/annotations'; +import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; +import { ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE } from '../../../common/constants/search'; +import { CHARTS_POINT_TARGET } from '../timeseriesexplorer/timeseriesexplorer_constants'; +import { timeBucketsServiceFactory } from './time_buckets_service'; +import type { TimeRangeBounds } from './time_buckets'; +import type { Job } from '../../../common/types/anomaly_detection_jobs'; +import type { TimeBucketsInterval } from './time_buckets'; +import type { + ChartDataPoint, + FocusData, + Interval, +} from '../timeseriesexplorer/timeseriesexplorer_utils/get_focus_data'; +import type { CriteriaField } from '../services/results_service'; +import { + MAX_SCHEDULED_EVENTS, + TIME_FIELD_NAME, +} from '../timeseriesexplorer/timeseriesexplorer_constants'; +import type { MlApiServices } from '../services/ml_api_service'; +import { mlResultsServiceProvider, type MlResultsService } from '../services/results_service'; +import { forecastServiceProvider } from '../services/forecast_service_provider'; +import { timeSeriesSearchServiceFactory } from '../timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service'; +import { useMlKibana } from '../contexts/kibana'; + +// TODO Consolidate with legacy code in +// `ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/timeseriesexplorer_utils.js`. +export function timeSeriesExplorerServiceFactory( + uiSettings: IUiSettingsClient, + mlApiServices: MlApiServices, + mlResultsService: MlResultsService +) { + const timeBuckets = timeBucketsServiceFactory(uiSettings); + const mlForecastService = forecastServiceProvider(mlApiServices); + const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory(mlResultsService, mlApiServices); + + function getAutoZoomDuration(selectedJob: Job) { + // Calculate the 'auto' zoom duration which shows data at bucket span granularity. + // Get the minimum bucket span of selected jobs. + let autoZoomDuration; + if (selectedJob.analysis_config.bucket_span) { + const bucketSpan = parseInterval(selectedJob.analysis_config.bucket_span); + const bucketSpanSeconds = bucketSpan!.asSeconds(); + + // In most cases the duration can be obtained by simply multiplying the points target + // Check that this duration returns the bucket span when run back through the + // TimeBucket interval calculation. + autoZoomDuration = bucketSpanSeconds * 1000 * (CHARTS_POINT_TARGET - 1); + + // Use a maxBars of 10% greater than the target. + const maxBars = Math.floor(1.1 * CHARTS_POINT_TARGET); + const buckets = timeBuckets.getTimeBuckets(); + buckets.setInterval('auto'); + buckets.setBarTarget(Math.floor(CHARTS_POINT_TARGET)); + buckets.setMaxBars(maxBars); + + // Set bounds from 'now' for testing the auto zoom duration. + const nowMs = new Date().getTime(); + const max = moment(nowMs); + const min = moment(nowMs - autoZoomDuration); + buckets.setBounds({ min, max }); + + const calculatedInterval = buckets.getIntervalToNearestMultiple(bucketSpanSeconds); + const calculatedIntervalSecs = calculatedInterval.asSeconds(); + if (calculatedIntervalSecs !== bucketSpanSeconds) { + // If we haven't got the span back, which may occur depending on the 'auto' ranges + // used in TimeBuckets and the bucket span of the job, then multiply by the ratio + // of the bucket span to the calculated interval. + autoZoomDuration = autoZoomDuration * (bucketSpanSeconds / calculatedIntervalSecs); + } + } + + return autoZoomDuration; + } + + function calculateAggregationInterval( + bounds: TimeRangeBounds, + bucketsTarget: number | undefined, + selectedJob: Job + ) { + // Aggregation interval used in queries should be a function of the time span of the chart + // and the bucket span of the selected job(s). + const barTarget = bucketsTarget !== undefined ? bucketsTarget : 100; + // Use a maxBars of 10% greater than the target. + const maxBars = Math.floor(1.1 * barTarget); + const buckets = timeBuckets.getTimeBuckets(); + buckets.setInterval('auto'); + buckets.setBounds(bounds); + buckets.setBarTarget(Math.floor(barTarget)); + buckets.setMaxBars(maxBars); + let aggInterval; + + if (selectedJob.analysis_config.bucket_span) { + // Ensure the aggregation interval is always a multiple of the bucket span to avoid strange + // behaviour such as adjacent chart buckets holding different numbers of job results. + const bucketSpan = parseInterval(selectedJob.analysis_config.bucket_span); + const bucketSpanSeconds = bucketSpan!.asSeconds(); + aggInterval = buckets.getIntervalToNearestMultiple(bucketSpanSeconds); + + // Set the interval back to the job bucket span if the auto interval is smaller. + const secs = aggInterval.asSeconds(); + if (secs < bucketSpanSeconds) { + buckets.setInterval(bucketSpanSeconds + 's'); + aggInterval = buckets.getInterval(); + } + } + + return aggInterval; + } + + function calculateInitialFocusRange( + zoomState: any, + contextAggregationInterval: any, + bounds: TimeRangeBounds + ) { + if (zoomState !== undefined) { + // Check that the zoom times are valid. + // zoomFrom must be at or after context chart search bounds earliest, + // zoomTo must be at or before context chart search bounds latest. + const zoomFrom = moment(zoomState.from, 'YYYY-MM-DDTHH:mm:ss.SSSZ', true); + const zoomTo = moment(zoomState.to, 'YYYY-MM-DDTHH:mm:ss.SSSZ', true); + const searchBounds = timeBuckets.getBoundsRoundedToInterval( + bounds, + contextAggregationInterval, + true + ); + const earliest = searchBounds.min; + const latest = searchBounds.max; + + if ( + zoomFrom.isValid() && + zoomTo.isValid() && + zoomTo.isAfter(zoomFrom) && + zoomFrom.isBetween(earliest, latest, null, '[]') && + zoomTo.isBetween(earliest, latest, null, '[]') + ) { + return [zoomFrom.toDate(), zoomTo.toDate()]; + } + } + + return undefined; + } + + function calculateDefaultFocusRange( + autoZoomDuration: any, + contextAggregationInterval: any, + contextChartData: any, + contextForecastData: any + ) { + const isForecastData = contextForecastData !== undefined && contextForecastData.length > 0; + + const combinedData = + isForecastData === false ? contextChartData : contextChartData.concat(contextForecastData); + const earliestDataDate = combinedData[0].date; + const latestDataDate = combinedData[combinedData.length - 1].date; + + let rangeEarliestMs; + let rangeLatestMs; + + if (isForecastData === true) { + // Return a range centred on the start of the forecast range, depending + // on the time range of the forecast and data. + const earliestForecastDataDate = contextForecastData[0].date; + const latestForecastDataDate = contextForecastData[contextForecastData.length - 1].date; + + rangeLatestMs = Math.min( + earliestForecastDataDate.getTime() + autoZoomDuration / 2, + latestForecastDataDate.getTime() + ); + rangeEarliestMs = Math.max(rangeLatestMs - autoZoomDuration, earliestDataDate.getTime()); + } else { + // Returns the range that shows the most recent data at bucket span granularity. + rangeLatestMs = latestDataDate.getTime() + contextAggregationInterval.asMilliseconds(); + rangeEarliestMs = Math.max(earliestDataDate.getTime(), rangeLatestMs - autoZoomDuration); + } + + return [new Date(rangeEarliestMs), new Date(rangeLatestMs)]; + } + + // Return dataset in format used by the swimlane. + // i.e. array of Objects with keys date (JavaScript date) and score. + function processRecordScoreResults(scoreData: any) { + const bucketScoreData: any = []; + each(scoreData, (dataForTime, time) => { + bucketScoreData.push({ + date: new Date(+time), + score: dataForTime.score, + }); + }); + + return bucketScoreData; + } + + // Return dataset in format used by the single metric chart. + // i.e. array of Objects with keys date (JavaScript date) and value, + // plus lower and upper keys if model plot is enabled for the series. + function processMetricPlotResults(metricPlotData: any, modelPlotEnabled: any) { + const metricPlotChartData: any = []; + if (modelPlotEnabled === true) { + each(metricPlotData, (dataForTime, time) => { + metricPlotChartData.push({ + date: new Date(+time), + lower: dataForTime.modelLower, + value: dataForTime.actual, + upper: dataForTime.modelUpper, + }); + }); + } else { + each(metricPlotData, (dataForTime, time) => { + metricPlotChartData.push({ + date: new Date(+time), + value: dataForTime.actual, + }); + }); + } + + return metricPlotChartData; + } + + // Returns forecast dataset in format used by the single metric chart. + // i.e. array of Objects with keys date (JavaScript date), isForecast, + // value, lower and upper keys. + function processForecastResults(forecastData: any) { + const forecastPlotChartData: any = []; + each(forecastData, (dataForTime, time) => { + forecastPlotChartData.push({ + date: new Date(+time), + isForecast: true, + lower: dataForTime.forecastLower, + value: dataForTime.prediction, + upper: dataForTime.forecastUpper, + }); + }); + + return forecastPlotChartData; + } + + // Finds the chart point which corresponds to an anomaly with the + // specified time. + function findChartPointForAnomalyTime( + chartData: any, + anomalyTime: any, + aggregationInterval: any + ) { + let chartPoint; + if (chartData === undefined) { + return chartPoint; + } + + for (let i = 0; i < chartData.length; i++) { + if (chartData[i].date.getTime() === anomalyTime) { + chartPoint = chartData[i]; + break; + } + } + + if (chartPoint === undefined) { + // Find the time of the point which falls immediately before the + // time of the anomaly. This is the start of the chart 'bucket' + // which contains the anomalous bucket. + let foundItem; + const intervalMs = aggregationInterval.asMilliseconds(); + for (let i = 0; i < chartData.length; i++) { + const itemTime = chartData[i].date.getTime(); + if (anomalyTime - itemTime < intervalMs) { + foundItem = chartData[i]; + break; + } + } + + chartPoint = foundItem; + } + + return chartPoint; + } + + // Uses data from the list of anomaly records to add anomalyScore, + // function, actual and typical properties, plus causes and multi-bucket + // info if applicable, to the chartData entries for anomalous buckets. + function processDataForFocusAnomalies( + chartData: ChartDataPoint[], + anomalyRecords: MlAnomalyRecordDoc[], + aggregationInterval: Interval, + modelPlotEnabled: boolean, + functionDescription?: string + ) { + const timesToAddPointsFor: number[] = []; + + // Iterate through the anomaly records making sure we have chart points for each anomaly. + const intervalMs = aggregationInterval.asMilliseconds(); + let lastChartDataPointTime: any; + if (chartData !== undefined && chartData.length > 0) { + lastChartDataPointTime = chartData[chartData.length - 1].date.getTime(); + } + anomalyRecords.forEach((record: MlAnomalyRecordDoc) => { + const recordTime = record[TIME_FIELD_NAME]; + const chartPoint = findChartPointForAnomalyTime(chartData, recordTime, aggregationInterval); + if (chartPoint === undefined) { + const timeToAdd = Math.floor(recordTime / intervalMs) * intervalMs; + if (timesToAddPointsFor.indexOf(timeToAdd) === -1 && timeToAdd !== lastChartDataPointTime) { + timesToAddPointsFor.push(timeToAdd); + } + } + }); + + timesToAddPointsFor.sort((a, b) => a - b); + + timesToAddPointsFor.forEach((time) => { + const pointToAdd: ChartDataPoint = { + date: new Date(time), + value: null, + }; + + if (modelPlotEnabled === true) { + pointToAdd.upper = null; + pointToAdd.lower = null; + } + chartData.push(pointToAdd); + }); + + // Iterate through the anomaly records adding the + // various properties required for display. + anomalyRecords.forEach((record) => { + // Look for a chart point with the same time as the record. + // If none found, find closest time in chartData set. + const recordTime = record[TIME_FIELD_NAME]; + if ( + record.function === ML_JOB_AGGREGATION.METRIC && + record.function_description !== functionDescription + ) + return; + + const chartPoint = findChartPointForAnomalyTime(chartData, recordTime, aggregationInterval); + if (chartPoint !== undefined) { + // If chart aggregation interval > bucket span, there may be more than + // one anomaly record in the interval, so use the properties from + // the record with the highest anomalyScore. + const recordScore = record.record_score; + const pointScore = chartPoint.anomalyScore; + if (pointScore === undefined || pointScore < recordScore) { + chartPoint.anomalyScore = recordScore; + chartPoint.function = record.function; + + if (record.actual !== undefined) { + // If cannot match chart point for anomaly time + // substitute the value with the record's actual so it won't plot as null/0 + if (chartPoint.value === null || record.function === ML_JOB_AGGREGATION.METRIC) { + chartPoint.value = Array.isArray(record.actual) ? record.actual[0] : record.actual; + } + + chartPoint.actual = record.actual; + chartPoint.typical = record.typical; + } else { + const causes = get(record, 'causes', []); + if (causes.length > 0) { + chartPoint.byFieldName = record.by_field_name; + chartPoint.numberOfCauses = causes.length; + if (causes.length === 1) { + // If only a single cause, copy actual and typical values to the top level. + const cause = record.causes![0]; + chartPoint.actual = cause.actual; + chartPoint.typical = cause.typical; + // substitute the value with the record's actual so it won't plot as null/0 + if (chartPoint.value === null) { + chartPoint.value = cause.actual; + } + } + } + } + + if ( + record.anomaly_score_explanation !== undefined && + record.anomaly_score_explanation.multi_bucket_impact !== undefined + ) { + chartPoint.multiBucketImpact = record.anomaly_score_explanation.multi_bucket_impact; + } + + chartPoint.isMultiBucketAnomaly = isMultiBucketAnomaly(record); + } + } + }); + + return chartData; + } + + function findChartPointForScheduledEvent(chartData: any, eventTime: any) { + let chartPoint; + if (chartData === undefined) { + return chartPoint; + } + + for (let i = 0; i < chartData.length; i++) { + if (chartData[i].date.getTime() === eventTime) { + chartPoint = chartData[i]; + break; + } + } + + return chartPoint; + } + // Adds a scheduledEvents property to any points in the chart data set + // which correspond to times of scheduled events for the job. + function processScheduledEventsForChart( + chartData: ChartDataPoint[], + scheduledEvents: Array<{ events: any; time: number }> | undefined, + aggregationInterval: TimeBucketsInterval + ) { + if (scheduledEvents !== undefined) { + const timesToAddPointsFor: number[] = []; + + // Iterate through the scheduled events making sure we have a chart point for each event. + const intervalMs = aggregationInterval.asMilliseconds(); + let lastChartDataPointTime: number | undefined; + if (chartData !== undefined && chartData.length > 0) { + lastChartDataPointTime = chartData[chartData.length - 1].date.getTime(); + } + + // In case there's no chart data/sparse data during these scheduled events + // ensure we add chart points at every aggregation interval for these scheduled events. + let sortRequired = false; + each(scheduledEvents, (events, time) => { + const exactChartPoint = findChartPointForScheduledEvent(chartData, +time); + + if (exactChartPoint !== undefined) { + exactChartPoint.scheduledEvents = events; + } else { + const timeToAdd: number = Math.floor(time / intervalMs) * intervalMs; + if ( + timesToAddPointsFor.indexOf(timeToAdd) === -1 && + timeToAdd !== lastChartDataPointTime + ) { + const pointToAdd = { + date: new Date(timeToAdd), + value: null, + scheduledEvents: events, + }; + + chartData.push(pointToAdd); + sortRequired = true; + } + } + }); + + // Sort chart data by time if extra points were added at the end of the array for scheduled events. + if (sortRequired) { + chartData.sort((a, b) => a.date.getTime() - b.date.getTime()); + } + } + + return chartData; + } + + function getFocusData( + criteriaFields: CriteriaField[], + detectorIndex: number, + focusAggregationInterval: TimeBucketsInterval, + forecastId: string, + modelPlotEnabled: boolean, + nonBlankEntities: any[], + searchBounds: any, + selectedJob: Job, + functionDescription?: string | undefined + ): Observable { + const esFunctionToPlotIfMetric = + functionDescription !== undefined + ? aggregationTypeTransform.toES(functionDescription) + : functionDescription; + + return forkJoin([ + // Query 1 - load metric data across selected time range. + mlTimeSeriesSearchService.getMetricData( + selectedJob, + detectorIndex, + nonBlankEntities, + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + focusAggregationInterval.asMilliseconds(), + esFunctionToPlotIfMetric + ), + // Query 2 - load all the records across selected time range for the chart anomaly markers. + mlApiServices.results.getAnomalyRecords$( + [selectedJob.job_id], + criteriaFields, + 0, + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + focusAggregationInterval.expression, + functionDescription + ), + // Query 3 - load any scheduled events for the selected job. + mlResultsService.getScheduledEventsByBucket( + [selectedJob.job_id], + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + focusAggregationInterval.asMilliseconds(), + 1, + MAX_SCHEDULED_EVENTS + ), + // Query 4 - load any annotations for the selected job. + mlApiServices.annotations + .getAnnotations$({ + jobIds: [selectedJob.job_id], + earliestMs: searchBounds.min.valueOf(), + latestMs: searchBounds.max.valueOf(), + maxAnnotations: ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE, + detectorIndex, + entities: nonBlankEntities, + }) + .pipe( + catchError((resp) => + of({ + annotations: {}, + totalCount: 0, + error: extractErrorMessage(resp), + success: false, + } as GetAnnotationsResponse) + ) + ), + // Plus query for forecast data if there is a forecastId stored in the appState. + forecastId !== undefined + ? (() => { + let aggType; + const detector = selectedJob.analysis_config.detectors[detectorIndex]; + const esAgg = mlFunctionToESAggregation(detector.function); + if (!modelPlotEnabled && (esAgg === 'sum' || esAgg === 'count')) { + aggType = { avg: 'sum', max: 'sum', min: 'sum' }; + } + return mlForecastService.getForecastData( + selectedJob, + detectorIndex, + forecastId, + nonBlankEntities, + searchBounds.min.valueOf(), + searchBounds.max.valueOf(), + focusAggregationInterval.asMilliseconds(), + aggType + ); + })() + : of(null), + ]).pipe( + map( + ([metricData, recordsForCriteria, scheduledEventsByBucket, annotations, forecastData]) => { + // Sort in descending time order before storing in scope. + const anomalyRecords = recordsForCriteria?.records + .sort((a, b) => a[TIME_FIELD_NAME] - b[TIME_FIELD_NAME]) + .reverse(); + + const scheduledEvents = scheduledEventsByBucket?.events[selectedJob.job_id]; + + let focusChartData = processMetricPlotResults(metricData.results, modelPlotEnabled); + // Tell the results container directives to render the focus chart. + focusChartData = processDataForFocusAnomalies( + focusChartData, + anomalyRecords, + focusAggregationInterval, + modelPlotEnabled, + functionDescription + ); + focusChartData = processScheduledEventsForChart( + focusChartData, + scheduledEvents, + focusAggregationInterval + ); + + const refreshFocusData: FocusData = { + scheduledEvents, + anomalyRecords, + focusChartData, + }; + + if (annotations) { + if (annotations.error !== undefined) { + refreshFocusData.focusAnnotationError = annotations.error; + refreshFocusData.focusAnnotationData = []; + } else { + refreshFocusData.focusAnnotationData = ( + annotations.annotations[selectedJob.job_id] ?? [] + ) + .sort((a, b) => { + return a.timestamp - b.timestamp; + }) + .map((d, i: number) => { + d.key = (i + 1).toString(); + return d; + }); + } + } + + if (forecastData) { + refreshFocusData.focusForecastData = processForecastResults(forecastData.results); + refreshFocusData.showForecastCheckbox = refreshFocusData.focusForecastData.length > 0; + } + return refreshFocusData; + } + ) + ); + } + + return { + getAutoZoomDuration, + calculateAggregationInterval, + calculateInitialFocusRange, + calculateDefaultFocusRange, + processRecordScoreResults, + processMetricPlotResults, + processForecastResults, + findChartPointForAnomalyTime, + processDataForFocusAnomalies, + findChartPointForScheduledEvent, + processScheduledEventsForChart, + getFocusData, + }; +} + +export function useTimeSeriesExplorerService(): TimeSeriesExplorerService { + const { + services: { + uiSettings, + mlServices: { mlApiServices }, + }, + } = useMlKibana(); + const mlResultsService = mlResultsServiceProvider(mlApiServices); + + const mlTimeSeriesExplorer = useMemo( + () => timeSeriesExplorerServiceFactory(uiSettings, mlApiServices, mlResultsService), + [uiSettings, mlApiServices, mlResultsService] + ); + return mlTimeSeriesExplorer; +} + +export type TimeSeriesExplorerService = ReturnType; diff --git a/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx b/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx index 00c4a02d4e929..182d070266c9a 100644 --- a/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx +++ b/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx @@ -26,7 +26,8 @@ import { JobSelectorFlyout } from './components/job_selector_flyout'; */ export async function resolveJobSelection( coreStart: CoreStart, - selectedJobIds?: JobId[] + selectedJobIds?: JobId[], + singleSelection: boolean = false ): Promise<{ jobIds: string[]; groups: Array<{ groupId: string; jobIds: string[] }> }> { const { http, @@ -74,7 +75,7 @@ export async function resolveJobSelection( selectedIds={selectedJobIds} withTimeRangeSelector={false} dateFormatTz={dateFormatTz} - singleSelection={false} + singleSelection={singleSelection} timeseriesOnly={true} onFlyoutClose={onFlyoutClose} onSelectionConfirmed={onSelectionConfirmed} diff --git a/x-pack/plugins/ml/public/embeddables/constants.ts b/x-pack/plugins/ml/public/embeddables/constants.ts index cfe50f25cd889..1001cd89c7498 100644 --- a/x-pack/plugins/ml/public/embeddables/constants.ts +++ b/x-pack/plugins/ml/public/embeddables/constants.ts @@ -7,6 +7,7 @@ export const ANOMALY_SWIMLANE_EMBEDDABLE_TYPE = 'ml_anomaly_swimlane' as const; export const ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE = 'ml_anomaly_charts' as const; +export const ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE = 'ml_single_metric_viewer' as const; export type AnomalySwimLaneEmbeddableType = typeof ANOMALY_SWIMLANE_EMBEDDABLE_TYPE; export type AnomalyExplorerChartsEmbeddableType = typeof ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE; diff --git a/x-pack/plugins/ml/public/embeddables/index.ts b/x-pack/plugins/ml/public/embeddables/index.ts index 0a505fe04ea85..9f0d2d75b1162 100644 --- a/x-pack/plugins/ml/public/embeddables/index.ts +++ b/x-pack/plugins/ml/public/embeddables/index.ts @@ -9,6 +9,7 @@ import type { EmbeddableSetup } from '@kbn/embeddable-plugin/public'; import { AnomalySwimlaneEmbeddableFactory } from './anomaly_swimlane'; import type { MlCoreSetup } from '../plugin'; import { AnomalyChartsEmbeddableFactory } from './anomaly_charts'; +import { SingleMetricViewerEmbeddableFactory } from './single_metric_viewer'; export * from './constants'; export * from './types'; @@ -25,6 +26,8 @@ export function registerEmbeddables(embeddable: EmbeddableSetup, core: MlCoreSet ); const anomalyChartsFactory = new AnomalyChartsEmbeddableFactory(core.getStartServices); - embeddable.registerEmbeddableFactory(anomalyChartsFactory.type, anomalyChartsFactory); + + const singleMetricViewerFactory = new SingleMetricViewerEmbeddableFactory(core.getStartServices); + embeddable.registerEmbeddableFactory(singleMetricViewerFactory.type, singleMetricViewerFactory); } diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/_index.scss b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/_index.scss new file mode 100644 index 0000000000000..b6f91cc749dcc --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/_index.scss @@ -0,0 +1,6 @@ +// ML has it's own variables for coloring +@import '../../application/variables'; + +// Protect the rest of Kibana from ML generic namespacing +@import '../../application/timeseriesexplorer/timeseriesexplorer'; +@import '../../application/timeseriesexplorer/timeseriesexplorer_annotations'; \ No newline at end of file diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container.tsx new file mode 100644 index 0000000000000..88c120c9747e1 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container.tsx @@ -0,0 +1,204 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { EuiResizeObserver } from '@elastic/eui'; +import { Observable } from 'rxjs'; +import { throttle } from 'lodash'; +import { MlJob } from '@elastic/elasticsearch/lib/api/types'; +import usePrevious from 'react-use/lib/usePrevious'; +import { useToastNotificationService } from '../../application/services/toast_notification_service'; +import { useEmbeddableExecutionContext } from '../common/use_embeddable_execution_context'; +import { useSingleMetricViewerInputResolver } from './use_single_metric_viewer_input_resolver'; +import type { ISingleMetricViewerEmbeddable } from './single_metric_viewer_embeddable'; +import type { + SingleMetricViewerEmbeddableInput, + AnomalyChartsEmbeddableOutput, + SingleMetricViewerEmbeddableServices, +} from '..'; +import { ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE } from '..'; +import { TimeSeriesExplorerEmbeddableChart } from '../../application/timeseriesexplorer/timeseriesexplorer_embeddable_chart'; +import { APP_STATE_ACTION } from '../../application/timeseriesexplorer/timeseriesexplorer_constants'; +import { useTimeSeriesExplorerService } from '../../application/util/time_series_explorer_service'; +import './_index.scss'; + +const RESIZE_THROTTLE_TIME_MS = 500; + +interface AppStateZoom { + from?: string; + to?: string; +} + +export interface EmbeddableSingleMetricViewerContainerProps { + id: string; + embeddableContext: InstanceType; + embeddableInput: Observable; + services: SingleMetricViewerEmbeddableServices; + refresh: Observable; + onInputChange: (input: Partial) => void; + onOutputChange: (output: Partial) => void; + onRenderComplete: () => void; + onLoading: () => void; + onError: (error: Error) => void; +} + +export const EmbeddableSingleMetricViewerContainer: FC< + EmbeddableSingleMetricViewerContainerProps +> = ({ + id, + embeddableContext, + embeddableInput, + services, + refresh, + onInputChange, + onOutputChange, + onRenderComplete, + onError, + onLoading, +}) => { + useEmbeddableExecutionContext( + services[0].executionContext, + embeddableInput, + ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE, + id + ); + const [chartWidth, setChartWidth] = useState(0); + const [zoom, setZoom] = useState(); + const [selectedForecastId, setSelectedForecastId] = useState(); + const [detectorIndex, setDetectorIndex] = useState(0); + const [selectedJob, setSelectedJob] = useState(); + const [autoZoomDuration, setAutoZoomDuration] = useState(); + + const { mlApiServices } = services[2]; + const { data, bounds, lastRefresh } = useSingleMetricViewerInputResolver( + embeddableInput, + refresh, + services[1].data.query.timefilter.timefilter, + onRenderComplete + ); + const selectedJobId = data?.jobIds[0]; + const previousRefresh = usePrevious(lastRefresh ?? 0); + const mlTimeSeriesExplorer = useTimeSeriesExplorerService(); + + // Holds the container height for previously fetched data + const containerHeightRef = useRef(); + const toastNotificationService = useToastNotificationService(); + + useEffect( + function setUpSelectedJob() { + async function fetchSelectedJob() { + if (mlApiServices && selectedJobId !== undefined) { + const { jobs } = await mlApiServices.getJobs({ jobId: selectedJobId }); + const job = jobs[0]; + setSelectedJob(job); + } + } + fetchSelectedJob(); + }, + [selectedJobId, mlApiServices] + ); + + useEffect( + function setUpAutoZoom() { + let zoomDuration: number | undefined; + if (selectedJobId !== undefined && selectedJob !== undefined) { + zoomDuration = mlTimeSeriesExplorer.getAutoZoomDuration(selectedJob); + setAutoZoomDuration(zoomDuration); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedJobId, selectedJob?.job_id, mlTimeSeriesExplorer] + ); + + // eslint-disable-next-line react-hooks/exhaustive-deps + const resizeHandler = useCallback( + throttle((e: { width: number; height: number }) => { + // Keep previous container height so it doesn't change the page layout + containerHeightRef.current = e.height; + + if (Math.abs(chartWidth - e.width) > 20) { + setChartWidth(e.width); + } + }, RESIZE_THROTTLE_TIME_MS), + [chartWidth] + ); + + const appStateHandler = useCallback( + (action: string, payload?: any) => { + /** + * Empty zoom indicates that chart hasn't been rendered yet, + * hence any updates prior that should replace the URL state. + */ + + switch (action) { + case APP_STATE_ACTION.SET_DETECTOR_INDEX: + setDetectorIndex(payload); + break; + + case APP_STATE_ACTION.SET_FORECAST_ID: + setSelectedForecastId(payload); + setZoom(undefined); + break; + + case APP_STATE_ACTION.SET_ZOOM: + setZoom(payload); + break; + + case APP_STATE_ACTION.UNSET_ZOOM: + setZoom(undefined); + break; + } + }, + + [setZoom, setDetectorIndex, setSelectedForecastId] + ); + + const containerPadding = 10; + + return ( + + {(resizeRef) => ( +

+ {data !== undefined && autoZoomDuration !== undefined && ( + + )} +
+ )} + + ); +}; + +// required for dynamic import using React.lazy() +// eslint-disable-next-line import/no-default-export +export default EmbeddableSingleMetricViewerContainer; diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container_lazy.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container_lazy.tsx new file mode 100644 index 0000000000000..0a69aaf2c2deb --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/embeddable_single_metric_viewer_container_lazy.tsx @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +export const EmbeddableSingleMetricViewerContainer = React.lazy( + () => import('./embeddable_single_metric_viewer_container') +); diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/index.ts b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/index.ts new file mode 100644 index 0000000000000..9afdbe3d1298c --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/index.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 { SingleMetricViewerEmbeddableFactory } from './single_metric_viewer_embeddable_factory'; diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx new file mode 100644 index 0000000000000..82a1b5abc8b63 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Suspense } from 'react'; +import ReactDOM from 'react-dom'; +import { pick } from 'lodash'; + +import { Embeddable } from '@kbn/embeddable-plugin/public'; + +import { CoreStart } from '@kbn/core/public'; +import { i18n } from '@kbn/i18n'; +import { Subject } from 'rxjs'; +import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; +import { IContainer } from '@kbn/embeddable-plugin/public'; +import { DatePickerContextProvider, type DatePickerDependencies } from '@kbn/ml-date-picker'; +import { UI_SETTINGS } from '@kbn/data-plugin/common'; +import { EmbeddableSingleMetricViewerContainer } from './embeddable_single_metric_viewer_container_lazy'; +import type { JobId } from '../../../common/types/anomaly_detection_jobs'; +import type { MlDependencies } from '../../application/app'; +import { + ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE, + SingleMetricViewerEmbeddableInput, + AnomalyChartsEmbeddableOutput, + SingleMetricViewerServices, +} from '..'; +import { EmbeddableLoading } from '../common/components/embeddable_loading_fallback'; + +export const getDefaultSingleMetricViewerPanelTitle = (jobIds: JobId[]) => + i18n.translate('xpack.ml.singleMetricViewerEmbeddable.title', { + defaultMessage: 'ML single metric viewer chart for {jobIds}', + values: { jobIds: jobIds.join(', ') }, + }); + +export type ISingleMetricViewerEmbeddable = typeof SingleMetricViewerEmbeddable; + +export class SingleMetricViewerEmbeddable extends Embeddable< + SingleMetricViewerEmbeddableInput, + AnomalyChartsEmbeddableOutput +> { + private node?: HTMLElement; + private reload$ = new Subject(); + public readonly type: string = ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE; + + constructor( + initialInput: SingleMetricViewerEmbeddableInput, + public services: [CoreStart, MlDependencies, SingleMetricViewerServices], + parent?: IContainer + ) { + super(initialInput, {} as AnomalyChartsEmbeddableOutput, parent); + } + + public onLoading() { + this.renderComplete.dispatchInProgress(); + this.updateOutput({ loading: true, error: undefined }); + } + + public onError(error: Error) { + this.renderComplete.dispatchError(); + this.updateOutput({ loading: false, error: { name: error.name, message: error.message } }); + } + + public onRenderComplete() { + this.renderComplete.dispatchComplete(); + this.updateOutput({ loading: false, error: undefined }); + } + + public render(node: HTMLElement) { + super.render(node); + this.node = node; + + // required for the export feature to work + this.node.setAttribute('data-shared-item', ''); + + const I18nContext = this.services[0].i18n.Context; + const theme$ = this.services[0].theme.theme$; + + const datePickerDeps: DatePickerDependencies = { + ...pick(this.services[0], ['http', 'notifications', 'theme', 'uiSettings', 'i18n']), + data: this.services[1].data, + uiSettingsKeys: UI_SETTINGS, + showFrozenDataTierChoice: false, + }; + + ReactDOM.render( + + + + + }> + + + + + + , + node + ); + } + + public destroy() { + super.destroy(); + if (this.node) { + ReactDOM.unmountComponentAtNode(this.node); + } + } + + public reload() { + this.reload$.next(); + } + + public supportedTriggers() { + return []; + } +} diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.ts b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.ts new file mode 100644 index 0000000000000..06b2f9b024bfa --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +import type { StartServicesAccessor } from '@kbn/core/public'; +import type { EmbeddableFactoryDefinition, IContainer } from '@kbn/embeddable-plugin/public'; + +import { PLUGIN_ICON, PLUGIN_ID, ML_APP_NAME } from '../../../common/constants/app'; +import { + ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE, + SingleMetricViewerEmbeddableInput, + SingleMetricViewerEmbeddableServices, +} from '..'; +import type { MlPluginStart, MlStartDependencies } from '../../plugin'; +import type { MlDependencies } from '../../application/app'; +import { HttpService } from '../../application/services/http_service'; +import { AnomalyExplorerChartsService } from '../../application/services/anomaly_explorer_charts_service'; + +export class SingleMetricViewerEmbeddableFactory + implements EmbeddableFactoryDefinition +{ + public readonly type = ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE; + + public readonly grouping = [ + { + id: PLUGIN_ID, + getDisplayName: () => ML_APP_NAME, + getIconType: () => PLUGIN_ICON, + }, + ]; + + constructor( + private getStartServices: StartServicesAccessor + ) {} + + public async isEditable() { + return true; + } + + public getDisplayName() { + return i18n.translate('xpack.ml.components.mlSingleMetricViewerEmbeddable.displayName', { + defaultMessage: 'Single metric viewer', + }); + } + + public getDescription() { + return i18n.translate('xpack.ml.components.mlSingleMetricViewerEmbeddable.description', { + defaultMessage: 'View anomaly detection single metric results in a chart.', + }); + } + + public async getExplicitInput(): Promise> { + const [coreStart, pluginStart, singleMetricServices] = await this.getServices(); + + try { + const { resolveEmbeddableSingleMetricViewerUserInput } = await import( + './single_metric_viewer_setup_flyout' + ); + return await resolveEmbeddableSingleMetricViewerUserInput( + coreStart, + pluginStart, + singleMetricServices + ); + } catch (e) { + return Promise.reject(); + } + } + + private async getServices(): Promise { + const [ + [coreStart, pluginsStart], + { AnomalyDetectorService }, + { fieldFormatServiceFactory }, + { indexServiceFactory }, + { mlApiServicesProvider }, + { mlResultsServiceProvider }, + { timeSeriesSearchServiceFactory }, + ] = await Promise.all([ + await this.getStartServices(), + await import('../../application/services/anomaly_detector_service'), + await import('../../application/services/field_format_service_factory'), + await import('../../application/util/index_service'), + await import('../../application/services/ml_api_service'), + await import('../../application/services/results_service'), + await import( + '../../application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service' + ), + ]); + + const httpService = new HttpService(coreStart.http); + const anomalyDetectorService = new AnomalyDetectorService(httpService); + const mlApiServices = mlApiServicesProvider(httpService); + const mlResultsService = mlResultsServiceProvider(mlApiServices); + const mlIndexUtils = indexServiceFactory(pluginsStart.data.dataViews); + const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory( + mlResultsService, + mlApiServices + ); + const mlFieldFormatService = fieldFormatServiceFactory(mlApiServices, mlIndexUtils); + + const anomalyExplorerService = new AnomalyExplorerChartsService( + pluginsStart.data.query.timefilter.timefilter, + mlApiServices, + mlResultsService + ); + + return [ + coreStart, + pluginsStart as MlDependencies, + { + anomalyDetectorService, + anomalyExplorerService, + mlResultsService, + mlApiServices, + mlTimeSeriesSearchService, + mlFieldFormatService, + }, + ]; + } + + public async create(initialInput: SingleMetricViewerEmbeddableInput, parent?: IContainer) { + const services = await this.getServices(); + const { SingleMetricViewerEmbeddable } = await import('./single_metric_viewer_embeddable'); + return new SingleMetricViewerEmbeddable(initialInput, services, parent); + } +} diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx new file mode 100644 index 0000000000000..89af056068063 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx @@ -0,0 +1,157 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useState } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiForm, + EuiFormRow, + EuiModalBody, + EuiModalFooter, + EuiModalHeader, + EuiModalHeaderTitle, + EuiFieldText, + EuiModal, + EuiSpacer, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { MlJob } from '@elastic/elasticsearch/lib/api/types'; +import type { SingleMetricViewerServices } from '..'; +import { TimeRangeBounds } from '../../application/util/time_buckets'; +import { SeriesControls } from '../../application/timeseriesexplorer/components/series_controls'; +import { + APP_STATE_ACTION, + type TimeseriesexplorerActionType, +} from '../../application/timeseriesexplorer/timeseriesexplorer_constants'; + +export interface SingleMetricViewerInitializerProps { + bounds: TimeRangeBounds; + defaultTitle: string; + initialInput?: SingleMetricViewerServices; + job: MlJob; + onCreate: (props: { + panelTitle: string; + functionDescription?: string; + selectedDetectorIndex: number; + selectedEntities: any; + }) => void; + onCancel: () => void; +} + +export const SingleMetricViewerInitializer: FC = ({ + bounds, + defaultTitle, + initialInput, + job, + onCreate, + onCancel, +}) => { + const [panelTitle, setPanelTitle] = useState(defaultTitle); + const [functionDescription, setFunctionDescription] = useState(); + const [selectedDetectorIndex, setSelectedDetectorIndex] = useState(0); + const [selectedEntities, setSelectedEntities] = useState(); + + const isPanelTitleValid = panelTitle.length > 0; + + const handleStateUpdate = (action: TimeseriesexplorerActionType, payload: any) => { + switch (action) { + case APP_STATE_ACTION.SET_ENTITIES: + setSelectedEntities(payload); + break; + case APP_STATE_ACTION.SET_FUNCTION_DESCRIPTION: + setFunctionDescription(payload); + break; + case APP_STATE_ACTION.SET_DETECTOR_INDEX: + setSelectedDetectorIndex(payload); + break; + default: + break; + } + }; + + return ( + + + + + + + + + + + } + isInvalid={!isPanelTitleValid} + > + setPanelTitle(e.target.value)} + isInvalid={!isPanelTitleValid} + /> + + + + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx new file mode 100644 index 0000000000000..e9822c01f865a --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { CoreStart } from '@kbn/core/public'; +import { toMountPoint } from '@kbn/react-kibana-mount'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { getDefaultSingleMetricViewerPanelTitle } from './single_metric_viewer_embeddable'; +import type { SingleMetricViewerEmbeddableInput, SingleMetricViewerServices } from '..'; +import { resolveJobSelection } from '../common/resolve_job_selection'; +import { SingleMetricViewerInitializer } from './single_metric_viewer_initializer'; +import type { MlStartDependencies } from '../../plugin'; + +export async function resolveEmbeddableSingleMetricViewerUserInput( + coreStart: CoreStart, + pluginStart: MlStartDependencies, + input: SingleMetricViewerServices +): Promise> { + const { overlays, theme, i18n } = coreStart; + const { mlApiServices } = input; + const timefilter = pluginStart.data.query.timefilter.timefilter; + + return new Promise(async (resolve, reject) => { + try { + const { jobIds } = await resolveJobSelection(coreStart, undefined, true); + const title = getDefaultSingleMetricViewerPanelTitle(jobIds); + const { jobs } = await mlApiServices.getJobs({ jobId: jobIds.join(',') }); + + const modalSession = overlays.openModal( + toMountPoint( + + { + modalSession.close(); + resolve({ + jobIds, + title: panelTitle, + functionDescription, + panelTitle, + selectedDetectorIndex, + selectedEntities, + }); + }} + onCancel={() => { + modalSession.close(); + reject(); + }} + /> + , + { theme, i18n } + ) + ); + } catch (error) { + reject(error); + } + }); +} diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/use_single_metric_viewer_input_resolver.ts b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/use_single_metric_viewer_input_resolver.ts new file mode 100644 index 0000000000000..c9f9d57fd7803 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/use_single_metric_viewer_input_resolver.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useState } from 'react'; +import { combineLatest, Observable } from 'rxjs'; +import { startWith } from 'rxjs/operators'; +import { TimefilterContract } from '@kbn/data-plugin/public'; +import { SingleMetricViewerEmbeddableInput } from '..'; +import type { TimeRangeBounds } from '../../application/util/time_buckets'; + +export function useSingleMetricViewerInputResolver( + embeddableInput: Observable, + refresh: Observable, + timefilter: TimefilterContract, + onRenderComplete: () => void +) { + const [data, setData] = useState(); + const [bounds, setBounds] = useState(); + const [lastRefresh, setLastRefresh] = useState(); + + useEffect(function subscribeToEmbeddableInput() { + const subscription = combineLatest([embeddableInput, refresh.pipe(startWith(null))]).subscribe( + (input) => { + if (input !== undefined) { + setData(input[0]); + if (timefilter !== undefined) { + const { timeRange } = input[0]; + const currentBounds = timefilter.calculateBounds(timeRange); + setBounds(currentBounds); + setLastRefresh(Date.now()); + } + onRenderComplete(); + } + } + ); + + return () => subscription.unsubscribe(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return { data, bounds, lastRefresh }; +} diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts index 48a7b5d43a5ac..56a33f488d534 100644 --- a/x-pack/plugins/ml/public/embeddables/types.ts +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -27,6 +27,9 @@ import { MlEmbeddableTypes, } from './constants'; import { MlResultsService } from '../application/services/results_service'; +import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlFieldFormatService } from '../application/services/field_format_service'; +import type { MlTimeSeriesSeachService } from '../application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service'; export interface AnomalySwimlaneEmbeddableCustomInput { jobIds: JobId[]; @@ -100,13 +103,45 @@ export interface AnomalyChartsEmbeddableCustomInput { export type AnomalyChartsEmbeddableInput = EmbeddableInput & AnomalyChartsEmbeddableCustomInput; +export interface SingleMetricViewerEmbeddableCustomInput { + jobIds: JobId[]; + title: string; + functionDescription?: string; + panelTitle: string; + selectedDetectorIndex: number; + selectedEntities: MlEntityField[]; + // Embeddable inputs which are not included in the default interface + filters: Filter[]; + query: Query; + refreshConfig: RefreshInterval; + timeRange: TimeRange; +} + +export type SingleMetricViewerEmbeddableInput = EmbeddableInput & + SingleMetricViewerEmbeddableCustomInput; + export interface AnomalyChartsServices { anomalyDetectorService: AnomalyDetectorService; anomalyExplorerService: AnomalyExplorerChartsService; mlResultsService: MlResultsService; + mlApiServices?: MlApiServices; +} + +export interface SingleMetricViewerServices { + anomalyExplorerService: AnomalyExplorerChartsService; + anomalyDetectorService: AnomalyDetectorService; + mlApiServices: MlApiServices; + mlFieldFormatService: MlFieldFormatService; + mlResultsService: MlResultsService; + mlTimeSeriesSearchService?: MlTimeSeriesSeachService; } export type AnomalyChartsEmbeddableServices = [CoreStart, MlDependencies, AnomalyChartsServices]; +export type SingleMetricViewerEmbeddableServices = [ + CoreStart, + MlDependencies, + SingleMetricViewerServices +]; export interface AnomalyChartsCustomOutput { entityFields?: MlEntityField[]; severity?: number; From 05555d0bce33c146130a92b7c81f412558d9d72d Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Thu, 8 Feb 2024 14:34:13 -0600 Subject: [PATCH 048/104] [Dev Tools] Introduce UI setting for Docked Console (#176414) ## Summary Introduce a new UI setting to allow users to disable the "Docked Console" aka the EmbeddableConsole from the console plugin. This console is currently used on Search pages and Index Management pages for 8.13, and will be added to more pages in future releases. ### Screenshots ![image](https://github.com/elastic/kibana/assets/1972968/c8b7ed8a-8695-486d-aef5-d403ea4d4547) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../settings/utilities/category/const.ts | 2 ++ .../utilities/category/get_category_name.ts | 4 +++ .../settings/search_project/index.ts | 6 +++- .../settings/search_project/tsconfig.json | 1 + src/plugins/console/public/plugin.ts | 7 +++- src/plugins/dev_tools/common/constants.ts | 16 ++++++++++ src/plugins/dev_tools/common/index.ts | 9 ++++++ src/plugins/dev_tools/public/index.ts | 1 + src/plugins/dev_tools/server/plugin.ts | 9 ++++-- src/plugins/dev_tools/server/ui_settings.ts | 32 +++++++++++++++++++ src/plugins/dev_tools/tsconfig.json | 2 +- .../server/collectors/management/schema.ts | 4 +++ .../server/collectors/management/types.ts | 1 + src/plugins/telemetry/schema/oss_plugins.json | 6 ++++ 14 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src/plugins/dev_tools/common/constants.ts create mode 100644 src/plugins/dev_tools/common/index.ts create mode 100644 src/plugins/dev_tools/server/ui_settings.ts diff --git a/packages/kbn-management/settings/utilities/category/const.ts b/packages/kbn-management/settings/utilities/category/const.ts index 67a17ecb0cc7a..9f9d65a34a04b 100644 --- a/packages/kbn-management/settings/utilities/category/const.ts +++ b/packages/kbn-management/settings/utilities/category/const.ts @@ -22,6 +22,7 @@ export const SECURITY_SOLUTION_CATEGORY = 'securitySolution'; export const TIMELION_CATEGORY = 'timelion'; export const VISUALIZATION_CATEGORY = 'visualization'; export const ENTERPRISE_SEARCH_CATEGORY = 'enterpriseSearch'; +export const DEV_TOOLS_CATEGORY = 'devTools'; export const CATEGORY_ORDER = [ GENERAL_CATEGORY, @@ -39,4 +40,5 @@ export const CATEGORY_ORDER = [ SECURITY_SOLUTION_CATEGORY, TIMELION_CATEGORY, VISUALIZATION_CATEGORY, + DEV_TOOLS_CATEGORY, ]; diff --git a/packages/kbn-management/settings/utilities/category/get_category_name.ts b/packages/kbn-management/settings/utilities/category/get_category_name.ts index 110d207bf5a6c..88756c34e412c 100644 --- a/packages/kbn-management/settings/utilities/category/get_category_name.ts +++ b/packages/kbn-management/settings/utilities/category/get_category_name.ts @@ -11,6 +11,7 @@ import { ACCESSIBILITY_CATEGORY, AUTOCOMPLETE_CATEGORY, BANNER_CATEGORY, + DEV_TOOLS_CATEGORY, DISCOVER_CATEGORY, ENTERPRISE_SEARCH_CATEGORY, GENERAL_CATEGORY, @@ -92,6 +93,9 @@ const names: Record = { [ROLLUPS_CATEGORY]: i18n.translate('management.settings.categoryNames.rollupsLabel', { defaultMessage: 'Rollups', }), + [DEV_TOOLS_CATEGORY]: i18n.translate('management.settings.categoryNames.devToolsLabel', { + defaultMessage: 'Developer Tools', + }), }; export function getCategoryName(category?: string) { diff --git a/packages/serverless/settings/search_project/index.ts b/packages/serverless/settings/search_project/index.ts index a26c658501617..5a16690fd5f76 100644 --- a/packages/serverless/settings/search_project/index.ts +++ b/packages/serverless/settings/search_project/index.ts @@ -7,5 +7,9 @@ */ import { COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX_ID } from '@kbn/management-settings-ids'; +import { ENABLE_DOCKED_CONSOLE_UI_SETTING_ID } from '@kbn/dev-tools-plugin/common'; -export const SEARCH_PROJECT_SETTINGS = [COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX_ID]; +export const SEARCH_PROJECT_SETTINGS = [ + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX_ID, + ENABLE_DOCKED_CONSOLE_UI_SETTING_ID, +]; diff --git a/packages/serverless/settings/search_project/tsconfig.json b/packages/serverless/settings/search_project/tsconfig.json index 16d6022e3d9bc..7d290d255a784 100644 --- a/packages/serverless/settings/search_project/tsconfig.json +++ b/packages/serverless/settings/search_project/tsconfig.json @@ -15,5 +15,6 @@ ], "kbn_references": [ "@kbn/management-settings-ids", + "@kbn/dev-tools-plugin", ] } diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts index 53cb16befe865..ca097322486ea 100644 --- a/src/plugins/console/public/plugin.ts +++ b/src/plugins/console/public/plugin.ts @@ -7,6 +7,7 @@ */ import { i18n } from '@kbn/i18n'; import { Plugin, CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/public'; +import { ENABLE_DOCKED_CONSOLE_UI_SETTING_ID } from '@kbn/dev-tools-plugin/public'; import { renderEmbeddableConsole } from './application/containers/embeddable'; import { @@ -109,10 +110,14 @@ export class ConsoleUIPlugin implements Plugin(); const consoleStart: ConsolePluginStart = {}; + const embeddedConsoleUiSetting = core.uiSettings.get( + ENABLE_DOCKED_CONSOLE_UI_SETTING_ID + ); const embeddedConsoleAvailable = isConsoleUiEnabled && isEmbeddedConsoleEnabled && - core.application.capabilities?.dev_tools?.show === true; + core.application.capabilities?.dev_tools?.show === true && + embeddedConsoleUiSetting; if (embeddedConsoleAvailable) { consoleStart.renderEmbeddableConsole = (props?: EmbeddableConsoleProps) => { diff --git a/src/plugins/dev_tools/common/constants.ts b/src/plugins/dev_tools/common/constants.ts new file mode 100644 index 0000000000000..b5e7c9adde842 --- /dev/null +++ b/src/plugins/dev_tools/common/constants.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * The UI Setting prefix and category for dev tools UI Settings + */ +export const DEV_TOOLS_FEATURE_ID = 'devTools'; +/** + * UI Setting ID for enabling / disabling the docked console in Kibana + */ +export const ENABLE_DOCKED_CONSOLE_UI_SETTING_ID = 'devTools:enableDockedConsole'; diff --git a/src/plugins/dev_tools/common/index.ts b/src/plugins/dev_tools/common/index.ts new file mode 100644 index 0000000000000..dc6ec6152e519 --- /dev/null +++ b/src/plugins/dev_tools/common/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { DEV_TOOLS_FEATURE_ID, ENABLE_DOCKED_CONSOLE_UI_SETTING_ID } from './constants'; diff --git a/src/plugins/dev_tools/public/index.ts b/src/plugins/dev_tools/public/index.ts index 9e685ee4ff507..03f0981a4a845 100644 --- a/src/plugins/dev_tools/public/index.ts +++ b/src/plugins/dev_tools/public/index.ts @@ -12,6 +12,7 @@ import { PluginInitializerContext } from '@kbn/core/public'; import { DevToolsPlugin } from './plugin'; export * from './plugin'; +export * from '../common/constants'; export function plugin(initializerContext: PluginInitializerContext) { return new DevToolsPlugin(initializerContext); diff --git a/src/plugins/dev_tools/server/plugin.ts b/src/plugins/dev_tools/server/plugin.ts index f4157691e2a87..dbb4098f74e79 100644 --- a/src/plugins/dev_tools/server/plugin.ts +++ b/src/plugins/dev_tools/server/plugin.ts @@ -6,12 +6,17 @@ * Side Public License, v 1. */ -import { PluginInitializerContext, Plugin } from '@kbn/core/server'; +import { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; +import { uiSettings } from './ui_settings'; export class DevToolsServerPlugin implements Plugin { constructor(initializerContext: PluginInitializerContext) {} - public setup() { + public setup(core: CoreSetup) { + /** + * Register Dev Tools UI Settings + */ + core.uiSettings.register(uiSettings); return {}; } diff --git a/src/plugins/dev_tools/server/ui_settings.ts b/src/plugins/dev_tools/server/ui_settings.ts new file mode 100644 index 0000000000000..ff7d04d847b46 --- /dev/null +++ b/src/plugins/dev_tools/server/ui_settings.ts @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { schema } from '@kbn/config-schema'; +import { UiSettingsParams } from '@kbn/core/types'; +import { i18n } from '@kbn/i18n'; + +import { DEV_TOOLS_FEATURE_ID, ENABLE_DOCKED_CONSOLE_UI_SETTING_ID } from '../common/constants'; + +/** + * uiSettings definitions for Dev Tools + */ +export const uiSettings: Record> = { + [ENABLE_DOCKED_CONSOLE_UI_SETTING_ID]: { + category: [DEV_TOOLS_FEATURE_ID], + description: i18n.translate('devTools.uiSettings.dockedConsole.description', { + defaultMessage: + 'Docks the Console in the Kibana UI. This setting does not affect the standard Console in Dev Tools.', + }), + name: i18n.translate('devTools.uiSettings.dockedConsole.name', { + defaultMessage: 'Docked Console', + }), + requiresPageReload: true, + schema: schema.boolean(), + value: true, + }, +}; diff --git a/src/plugins/dev_tools/tsconfig.json b/src/plugins/dev_tools/tsconfig.json index b8dee30d16e73..13e30f92c8d6e 100644 --- a/src/plugins/dev_tools/tsconfig.json +++ b/src/plugins/dev_tools/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "target/types", }, - "include": ["public/**/*", "server/**/*"], + "include": ["common/*", "public/**/*", "server/**/*"], "kbn_references": [ "@kbn/core", "@kbn/url-forwarding-plugin", diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 12e419822c5c8..1269a68e41c17 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -628,4 +628,8 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, }, + 'devTools:enableDockedConsole': { + type: 'boolean', + _meta: { description: 'Non-default value of setting.' }, + }, }; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index f850103afb14b..177a01b81af19 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -166,4 +166,5 @@ export interface UsageStats { 'observability:profilingCostPervCPUPerHour': number; 'observability:profilingAWSCostDiscountRate': number; 'data_views:fields_excluded_data_tiers': string; + 'devTools:enableDockedConsole': boolean; } diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 659c791645ca9..b5108f3d9269d 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10257,6 +10257,12 @@ "_meta": { "description": "Non-default value of setting." } + }, + "devTools:enableDockedConsole": { + "type": "boolean", + "_meta": { + "description": "Non-default value of setting." + } } } }, From 1bd88ff98726fde98fa71e8931eabbf38ece00f7 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 8 Feb 2024 13:34:51 -0700 Subject: [PATCH 049/104] [maps] ES|QL adhoc data view (#176310) Fixes https://github.com/elastic/kibana/issues/176325 https://github.com/elastic/kibana/pull/174736 resolved the issue of [Filter bar displays repeated same dataview names equal to the number of ES|QL panels based on that dataview in the dashboard](https://github.com/elastic/kibana/issues/168131). This PR uses `getESQLAdHocDataview` to create an adhoc data view for ESQL statements. ### Test steps 1. install sample web logs data set. Wait for install to finish (so web logs is default data view) 2. install sample flights data set. 3. create new map 4. add ESQL layer. Set statement to `from kibana_sample_data_flights | keep DestLocation | limit 10000`. Click run. 5. Verify data view is passed to unified search and flights fields are displayed in typeahead in unified search 6. save map 7. open map in new tab. Verify adhoc data view is re-hydrated in new tab and unified search works as expected --- .../source_descriptor_types.ts | 1 + .../esql_source/create_source_editor.test.tsx | 22 +++++++-- .../esql_source/create_source_editor.tsx | 24 +++++++--- .../sources/esql_source/esql_editor.tsx | 8 +--- .../sources/esql_source/esql_source.test.ts | 3 ++ .../sources/esql_source/esql_source.tsx | 9 ++++ .../classes/sources/esql_source/esql_utils.ts | 47 ++++++++----------- .../esql_source/update_source_editor.test.tsx | 43 +++++++++++++---- .../esql_source/update_source_editor.tsx | 8 +++- .../fixtures/kbn_archiver/maps.json | 4 +- 10 files changed, 109 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts index b8979103f50d8..ebbbfd3fde1c1 100644 --- a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts @@ -45,6 +45,7 @@ export type ESQLSourceDescriptor = AbstractSourceDescriptor & { id: string; esql: string; columns: ESQLColumn[]; + dataViewId: string; /* * Date field used to narrow ES|QL requests by global time range */ diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.test.tsx index eba948dec895f..cb7206e5bab7c 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.test.tsx @@ -7,10 +7,12 @@ import React from 'react'; import { render, waitFor } from '@testing-library/react'; +import type { DataViewSpec } from '@kbn/data-plugin/common'; import { CreateSourceEditor } from './create_source_editor'; jest.mock('../../../kibana_services', () => { - const mockDefaultDataView = { + const DEFAULT_DATA_VIEW_INDEX_PATTERN = 'logs'; + const defaultDataView = { fields: [ { name: 'location', @@ -23,10 +25,11 @@ jest.mock('../../../kibana_services', () => { ], timeFieldName: '@timestamp', getIndexPattern: () => { - return 'logs'; + return DEFAULT_DATA_VIEW_INDEX_PATTERN; }, }; - const mockDataView = { + + const otherDataView = { fields: [ { name: 'geometry', @@ -37,14 +40,21 @@ jest.mock('../../../kibana_services', () => { return 'world_countries'; }, }; + return { getIndexPatternService() { return { + create: async (spec: DataViewSpec) => { + return { + ...(spec.title === DEFAULT_DATA_VIEW_INDEX_PATTERN ? defaultDataView : otherDataView), + id: spec.id, + }; + }, get: async () => { - return mockDataView; + return otherDataView; }, getDefaultDataView: async () => { - return mockDefaultDataView; + return defaultDataView; }, }; }, @@ -63,6 +73,7 @@ describe('CreateSourceEditor', () => { type: 'geo_point', }, ], + dataViewId: '30de729e173668cbf8954aa56c4aca5b82a1005586a608b692dae478219f8c76', dateField: '@timestamp', esql: 'from logs | keep location | limit 10000', geoField: 'location', @@ -89,6 +100,7 @@ describe('CreateSourceEditor', () => { type: 'geo_shape', }, ], + dataViewId: 'c9f096614a62aa31893a2d6e8f43139bda7dcdb262b9373f79d0173cc152b4a4', dateField: undefined, esql: 'from world_countries | keep geometry | limit 10000', geoField: 'geometry', diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.tsx index 4c75246aed567..4533c54d1a1ce 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/create_source_editor.tsx @@ -9,6 +9,7 @@ import React, { useEffect, useState } from 'react'; import useDebounce from 'react-use/lib/useDebounce'; import { i18n } from '@kbn/i18n'; import type { ESQLColumn } from '@kbn/es-types'; +import { getESQLAdHocDataview } from '@kbn/esql-utils'; import { EuiFormRow, EuiPanel, @@ -32,6 +33,7 @@ interface Props { export function CreateSourceEditor(props: Props) { const [isInitialized, setIsInitialized] = useState(false); + const [adhocDataViewId, setAdhocDataViewId] = useState(); const [columns, setColumns] = useState([]); const [esql, setEsql] = useState(''); const [dateField, setDateField] = useState(); @@ -52,17 +54,20 @@ export function CreateSourceEditor(props: Props) { } getDataView() - .then((dataView) => { + .then(async (dataView) => { + const adhocDataView = dataView + ? await getESQLAdHocDataview(dataView.getIndexPattern(), getIndexPatternService()) + : undefined; if (ignore) { return; } - if (dataView) { + if (adhocDataView) { let initialGeoField: DataViewField | undefined; const initialDateFields: string[] = []; const initialGeoFields: string[] = []; - for (let i = 0; i < dataView.fields.length; i++) { - const field = dataView.fields[i]; + for (let i = 0; i < adhocDataView.fields.length; i++) { + const field = adhocDataView.fields[i]; if ( [ES_GEO_FIELD_TYPE.GEO_POINT, ES_GEO_FIELD_TYPE.GEO_SHAPE].includes( field.type as ES_GEO_FIELD_TYPE @@ -77,12 +82,13 @@ export function CreateSourceEditor(props: Props) { if (initialGeoField) { let initialDateField: string | undefined; - if (dataView.timeFieldName) { + // get default time field from default data view instead of adhoc data view + if (dataView?.timeFieldName) { initialDateField = dataView.timeFieldName; } else if (initialDateFields.length) { initialDateField = initialDateFields[0]; } - const initialEsql = `from ${dataView.getIndexPattern()} | keep ${ + const initialEsql = `from ${adhocDataView.getIndexPattern()} | keep ${ initialGeoField.name } | limit 10000`; setColumns([ @@ -94,6 +100,7 @@ export function CreateSourceEditor(props: Props) { : ESQL_GEO_POINT_TYPE, }, ]); + setAdhocDataViewId(adhocDataView.id); setDateField(initialDateField); setDateFields(initialDateFields); setGeoField(initialGeoField.name); @@ -123,9 +130,10 @@ export function CreateSourceEditor(props: Props) { useDebounce( () => { const sourceConfig = - esql && esql.length + esql && esql.length && adhocDataViewId ? { columns, + dataViewId: adhocDataViewId, dateField, geoField, esql, @@ -138,6 +146,7 @@ export function CreateSourceEditor(props: Props) { }, 0, [ + adhocDataViewId, columns, dateField, geoField, @@ -154,6 +163,7 @@ export function CreateSourceEditor(props: Props) { { + setAdhocDataViewId(change.adhocDataViewId); setColumns(change.columns); setEsql(change.esql); setDateFields(change.dateFields); diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_editor.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_editor.tsx index 0145dc8239273..8ed04f61adb5d 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_editor.tsx @@ -17,11 +17,13 @@ import { getESQLMeta, verifyGeometryColumn } from './esql_utils'; interface Props { esql: string; onESQLChange: ({ + adhocDataViewId, columns, dateFields, geoFields, esql, }: { + adhocDataViewId: string; columns: ESQLColumn[]; dateFields: string[]; geoFields: string[]; @@ -81,12 +83,6 @@ export function ESQLEditor(props: Props) { return; } setError(err); - props.onESQLChange({ - columns: [], - dateFields: [], - geoFields: [], - esql: '', - }); } setIsLoading(false); diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.test.ts b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.test.ts index 42446ad8cb7e4..eabaedf681b2c 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.test.ts @@ -11,6 +11,7 @@ import { VECTOR_SHAPE_TYPE } from '../../../../common/constants'; describe('getSupportedShapeTypes', () => { test('should return point for geo_point column', async () => { const descriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from kibana_sample_data_logs | keep geo.coordinates | limit 10000', columns: [ { @@ -25,6 +26,7 @@ describe('getSupportedShapeTypes', () => { test('should return all geometry types for geo_shape column', async () => { const descriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from world_countries | keep geometry | limit 10000', columns: [ { @@ -43,6 +45,7 @@ describe('getSupportedShapeTypes', () => { test('should fallback to point when geometry column can not be found', async () => { const descriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from world_countries | keep geometry | limit 10000', }); const esqlSource = new ESQLSource(descriptor); diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx index d438a714beb40..53745e7426b70 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx @@ -52,12 +52,17 @@ export class ESQLSource extends AbstractVectorSource implements IVectorSource { throw new Error('Cannot create ESQLSourceDescriptor when esql is not provided'); } + if (!isValidStringConfig(descriptor.dataViewId)) { + throw new Error('Cannot create ESQLSourceDescriptor when dataViewId is not provided'); + } + return { ...descriptor, id: isValidStringConfig(descriptor.id) ? descriptor.id! : uuidv4(), type: SOURCE_TYPES.ESQL, esql: descriptor.esql!, columns: descriptor.columns ? descriptor.columns : [], + dataViewId: descriptor.dataViewId!, narrowByGlobalSearch: typeof descriptor.narrowByGlobalSearch !== 'undefined' ? descriptor.narrowByGlobalSearch @@ -316,4 +321,8 @@ export class ESQLSource extends AbstractVectorSource implements IVectorSource { narrowByGlobalTime: this._descriptor.narrowByGlobalTime, }; } + + getIndexPatternId() { + return this._descriptor.dataViewId; + } } diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_utils.ts b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_utils.ts index c247170874ba3..144516f7db5d0 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_utils.ts +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_utils.ts @@ -7,7 +7,8 @@ import { i18n } from '@kbn/i18n'; import { lastValueFrom } from 'rxjs'; -import { getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; +import type { DataView } from '@kbn/data-plugin/common'; +import { getESQLAdHocDataview, getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; import type { ESQLColumn, ESQLSearchReponse } from '@kbn/es-types'; import { ES_GEO_FIELD_TYPE } from '../../../../common/constants'; import { getData, getIndexPatternService } from '../../../kibana_services'; @@ -49,10 +50,14 @@ export function verifyGeometryColumn(columns: ESQLColumn[]) { } export async function getESQLMeta(esql: string) { - const fields = await getFields(esql); + const adhocDataView = await getESQLAdHocDataview( + getIndexPatternFromESQLQuery(esql), + getIndexPatternService() + ); return { columns: await getColumns(esql), - ...fields, + adhocDataViewId: adhocDataView.id!, + ...getFields(adhocDataView), }; } @@ -105,33 +110,19 @@ async function getColumns(esql: string) { } } -export async function getFields(esql: string) { +export function getFields(dataView: DataView) { const dateFields: string[] = []; const geoFields: string[] = []; - const pattern: string = getIndexPatternFromESQLQuery(esql); - try { - // TODO pass field type filter to getFieldsForWildcard when field type filtering is supported - (await getIndexPatternService().getFieldsForWildcard({ pattern })).forEach((field) => { - if (field.type === 'date') { - dateFields.push(field.name); - } else if ( - field.type === ES_GEO_FIELD_TYPE.GEO_POINT || - field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE - ) { - geoFields.push(field.name); - } - }); - } catch (error) { - throw new Error( - i18n.translate('xpack.maps.source.esql.getFieldsErrorMsg', { - defaultMessage: `Unable to load fields from index pattern: {pattern}. {errorMessage}`, - values: { - errorMessage: error.message, - pattern, - }, - }) - ); - } + dataView.fields.forEach((field) => { + if (field.type === 'date') { + dateFields.push(field.name); + } else if ( + field.type === ES_GEO_FIELD_TYPE.GEO_POINT || + field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE + ) { + geoFields.push(field.name); + } + }); return { dateFields, diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.test.tsx index 7c6f9f34b1f56..7491f6bc2b049 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.test.tsx @@ -11,19 +11,38 @@ import userEvent from '@testing-library/user-event'; import { UpdateSourceEditor } from './update_source_editor'; import { ESQLSource } from './esql_source'; -jest.mock('./esql_utils', () => ({})); - -describe('UpdateSourceEditor', () => { - beforeEach(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('./esql_utils').getFields = async () => { +jest.mock('../../../kibana_services', () => { + return { + getIndexPatternService() { return { - dateFields: ['timestamp', 'utc_timestamp'], - geoFields: ['location', 'dest_location'], + get: async () => { + return { + fields: [ + { + name: 'timestamp', + type: 'date', + }, + { + name: 'utc_timestamp', + type: 'date', + }, + { + name: 'location', + type: 'geo_point', + }, + { + name: 'utc_timestamp', + type: 'geo_point', + }, + ], + }; + }, }; - }; - }); + }, + }; +}); +describe('UpdateSourceEditor', () => { describe('narrow by map bounds switch', () => { function getNarrowByMapBoundsSwitch() { return screen.getByText('Narrow ES|QL statement by visible map area'); @@ -32,6 +51,7 @@ describe('UpdateSourceEditor', () => { test('should set geoField when checked and geo field is not set', async () => { const onChange = jest.fn(); const sourceDescriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from logs | keep location | limit 10000', columns: [ { @@ -55,6 +75,7 @@ describe('UpdateSourceEditor', () => { test('should not reset geoField when checked and geoField is set', async () => { const onChange = jest.fn(); const sourceDescriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from logs | keep location | limit 10000', columns: [ { @@ -82,6 +103,7 @@ describe('UpdateSourceEditor', () => { test('should set dateField when checked and date field is not set', async () => { const onChange = jest.fn(); const sourceDescriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from logs | keep location | limit 10000', columns: [ { @@ -105,6 +127,7 @@ describe('UpdateSourceEditor', () => { test('should not reset dateField when checked and dateField is set', async () => { const onChange = jest.fn(); const sourceDescriptor = ESQLSource.createDescriptor({ + dataViewId: '1234', esql: 'from logs | keep location | limit 10000', columns: [ { diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.tsx index 1a147cf93085f..e77bcf862f929 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/update_source_editor.tsx @@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n'; import type { ESQLSourceDescriptor } from '../../../../common/descriptor_types'; import type { OnSourceChangeArgs } from '../source'; import { ForceRefreshCheckbox } from '../../../components/force_refresh_checkbox'; +import { getIndexPatternService } from '../../../kibana_services'; import { ESQLEditor } from './esql_editor'; import { NarrowByMapBounds, NarrowByTime } from './narrow_by_field'; import { getFields } from './esql_utils'; @@ -35,11 +36,13 @@ export function UpdateSourceEditor(props: Props) { useEffect(() => { let ignore = false; - getFields(props.sourceDescriptor.esql) - .then((fields) => { + getIndexPatternService() + .get(props.sourceDescriptor.dataViewId) + .then((dataView) => { if (ignore) { return; } + const fields = getFields(dataView); setDateFields(fields.dateFields); setGeoFields(fields.geoFields); setIsInitialized(true); @@ -79,6 +82,7 @@ export function UpdateSourceEditor(props: Props) { setGeoFields(change.geoFields); const changes: OnSourceChangeArgs[] = [ { propName: 'columns', value: change.columns }, + { propName: 'dataViewId', value: change.adhocDataViewId }, { propName: 'esql', value: change.esql }, ]; function ensureField(key: 'dateField' | 'geoField', fields: string[]) { diff --git a/x-pack/test/functional/fixtures/kbn_archiver/maps.json b/x-pack/test/functional/fixtures/kbn_archiver/maps.json index 1ce5bc3fd6aa1..b7fef81c49bfb 100644 --- a/x-pack/test/functional/fixtures/kbn_archiver/maps.json +++ b/x-pack/test/functional/fixtures/kbn_archiver/maps.json @@ -1181,8 +1181,8 @@ "attributes": { "title": "esql example", "description": "", - "mapStateJSON": "{\"adHocDataViews\":[],\"zoom\":4.1,\"center\":{\"lon\":-100.61091,\"lat\":33.23887},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-20T01:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"settings\":{\"autoFitToDataBounds\":false,\"backgroundColor\":\"#ffffff\",\"customIcons\":[],\"disableInteractive\":false,\"disableTooltipControl\":false,\"hideToolbarOverlay\":false,\"hideLayerControl\":false,\"hideViewControl\":false,\"initialLocation\":\"LAST_SAVED_LOCATION\",\"fixedLocation\":{\"lat\":0,\"lon\":0,\"zoom\":2},\"browserLocation\":{\"zoom\":2},\"keydownScrollZoom\":false,\"maxZoom\":24,\"minZoom\":0,\"showScaleControl\":false,\"showSpatialFilters\":true,\"showTimesliderToggleButton\":true,\"spatialFiltersAlpa\":0.3,\"spatialFiltersFillColor\":\"#DA8B45\",\"spatialFiltersLineColor\":\"#DA8B45\"}}", - "layerListJSON": "[{\"sourceDescriptor\":{\"columns\":[{\"name\":\"geo.coordinates\",\"type\":\"geo_point\"}],\"dateField\":\"@timestamp\",\"esql\":\"from logstash-* | KEEP geo.coordinates | limit 10000\",\"id\":\"fad0e2eb-9278-415c-bdc8-1189a46eac0b\",\"type\":\"ESQL\",\"narrowByGlobalSearch\":true,\"narrowByMapBounds\":true,\"applyForceRefresh\":true,\"geoField\":\"geo.coordinates\",\"narrowByGlobalTime\":true},\"id\":\"59ca05b3-e3be-4fb4-ab4d-56c17b8bd589\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}},\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#54B399\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#41937c\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":6}},\"iconOrientation\":{\"type\":\"STATIC\",\"options\":{\"orientation\":0}},\"labelText\":{\"type\":\"STATIC\",\"options\":{\"value\":\"\"}},\"labelColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#000000\"}},\"labelSize\":{\"type\":\"STATIC\",\"options\":{\"size\":14}},\"labelZoomRange\":{\"options\":{\"useLayerZoomRange\":true,\"minZoom\":0,\"maxZoom\":24}},\"labelBorderColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"labelBorderSize\":{\"options\":{\"size\":\"SMALL\"}},\"labelPosition\":{\"options\":{\"position\":\"CENTER\"}}},\"isTimeAware\":true},\"includeInFitToBounds\":true,\"type\":\"GEOJSON_VECTOR\",\"joins\":[],\"disableTooltips\":false}]", + "mapStateJSON": "{\"adHocDataViews\":[{\"id\":\"624b9c7c17e840dd2161e64c37fe4696eb042ca3afbba2c390c742e3f576a8c9\",\"title\":\"logstash-*\",\"sourceFilters\":[],\"fieldFormats\":{},\"runtimeFieldMap\":{},\"fieldAttrs\":{},\"allowNoIndex\":false,\"name\":\"logstash-*\",\"allowHidden\":false}],\"zoom\":4.1,\"center\":{\"lon\":-100.61091,\"lat\":33.23887},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-20T01:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"settings\":{\"autoFitToDataBounds\":false,\"backgroundColor\":\"#ffffff\",\"customIcons\":[],\"disableInteractive\":false,\"disableTooltipControl\":false,\"hideToolbarOverlay\":false,\"hideLayerControl\":false,\"hideViewControl\":false,\"initialLocation\":\"LAST_SAVED_LOCATION\",\"fixedLocation\":{\"lat\":0,\"lon\":0,\"zoom\":2},\"browserLocation\":{\"zoom\":2},\"keydownScrollZoom\":false,\"maxZoom\":24,\"minZoom\":0,\"showScaleControl\":false,\"showSpatialFilters\":true,\"showTimesliderToggleButton\":true,\"spatialFiltersAlpa\":0.3,\"spatialFiltersFillColor\":\"#DA8B45\",\"spatialFiltersLineColor\":\"#DA8B45\"}}", + "layerListJSON": "[{\"sourceDescriptor\":{\"columns\":[{\"name\":\"geo.coordinates\",\"type\":\"geo_point\"}],\"dataViewId\":\"624b9c7c17e840dd2161e64c37fe4696eb042ca3afbba2c390c742e3f576a8c9\",\"dateField\":\"@timestamp\",\"esql\":\"from logstash-* | KEEP geo.coordinates | limit 10000\",\"id\":\"fad0e2eb-9278-415c-bdc8-1189a46eac0b\",\"type\":\"ESQL\",\"narrowByGlobalSearch\":true,\"narrowByMapBounds\":true,\"applyForceRefresh\":true,\"geoField\":\"geo.coordinates\",\"narrowByGlobalTime\":true},\"id\":\"59ca05b3-e3be-4fb4-ab4d-56c17b8bd589\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}},\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#54B399\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#41937c\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":6}},\"iconOrientation\":{\"type\":\"STATIC\",\"options\":{\"orientation\":0}},\"labelText\":{\"type\":\"STATIC\",\"options\":{\"value\":\"\"}},\"labelColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#000000\"}},\"labelSize\":{\"type\":\"STATIC\",\"options\":{\"size\":14}},\"labelZoomRange\":{\"options\":{\"useLayerZoomRange\":true,\"minZoom\":0,\"maxZoom\":24}},\"labelBorderColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"labelBorderSize\":{\"options\":{\"size\":\"SMALL\"}},\"labelPosition\":{\"options\":{\"position\":\"CENTER\"}}},\"isTimeAware\":true},\"includeInFitToBounds\":true,\"type\":\"GEOJSON_VECTOR\",\"joins\":[],\"disableTooltips\":false}]", "uiStateJSON": "{\"isLayerTOCOpen\":true,\"openTOCDetails\":[]}" }, "references": [], From e3f1d1272b4d0d5d4097417dd010ca71da7b25ae Mon Sep 17 00:00:00 2001 From: Adam Demjen Date: Thu, 8 Feb 2024 15:36:00 -0500 Subject: [PATCH 050/104] [Search] Consolidate ML model fetch calls (#176257) ## Summary With the introduction of [fetch_ml_models.ts](https://github.com/elastic/kibana/blob/main/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.ts), the fetching and enriching of ML models for Search purposes has been consolidated in that API. This allows us to remove the dependency on the older method that works with ML plugin-specific `TrainedModel` entities. This PR makes the following changes: - Switch over code that depend on ML models to use the new function from `fetch_ml_models.ts` (that already does sorting/filtering). - Move the fetch process to `ml_inference_logic.ts`, and begin periodically polling after mounting the logic. This enables passing down values to lower components, e.g. `model_select_logic.ts`, instead of repeating the fetch there. - Use `MlModel` instead of `TrainedModel/MlTrainedModelConfig`. This requires adding some missing properties to `MlModel`: `types`, `inputFieldNames`, `version`. - Remove the old fetch methods (`x-pack/plugins/enterprise_search/server/lib/ml/ml_*_logic.ts`). - Remove the "no models available" component and condition, since as of 8.12 at least the ELSER/E5 placeholders are always present. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../ml_inference_pipeline/index.test.ts | 38 ++- .../common/ml_inference_pipeline/index.ts | 12 +- .../enterprise_search/common/types/ml.ts | 5 + .../cached_fetch_models_api_logic.test.ts | 8 +- .../cached_fetch_models_api_logic.ts | 2 + .../ml_models/ml_model_stats_logic.test.ts | 25 -- .../api/ml_models/ml_model_stats_logic.ts | 35 -- .../api/ml_models/ml_models_logic.test.ts | 28 -- .../api/ml_models/ml_models_logic.ts | 31 -- .../ml_models/ml_trained_models_logic.test.ts | 177 ---------- .../api/ml_models/ml_trained_models_logic.ts | 169 ---------- .../add_inference_pipeline_flyout.test.tsx | 6 - .../add_inference_pipeline_flyout.tsx | 13 +- .../ml_inference/inference_config.tsx | 7 +- .../ml_inference/ml_inference_logic.test.ts | 315 +++++++----------- .../ml_inference/ml_inference_logic.ts | 104 +++--- .../ml_inference/model_select.test.tsx | 3 + .../ml_inference/model_select_logic.test.ts | 36 +- .../ml_inference/model_select_logic.ts | 61 ++-- .../ml_inference/model_select_option.test.tsx | 3 + .../pipelines/ml_inference/no_models.tsx | 57 ---- .../shared/ml_inference/utils.test.ts | 81 +---- .../components/shared/ml_inference/utils.ts | 23 -- .../server/lib/ml/fetch_ml_models.test.ts | 51 +++ .../server/lib/ml/fetch_ml_models.ts | 67 ++-- .../enterprise_search/server/lib/ml/utils.ts | 2 + .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 29 files changed, 345 insertions(+), 1023 deletions(-) delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/no_models.tsx diff --git a/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.test.ts b/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.test.ts index 78af0a862d302..93f8152efa19b 100644 --- a/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.test.ts +++ b/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.test.ts @@ -8,6 +8,7 @@ import { MlTrainedModelConfig, MlTrainedModelStats } from '@elastic/elasticsearch/lib/api/types'; import { BUILT_IN_MODEL_TAG, TRAINED_MODEL_TYPE } from '@kbn/ml-trained-models-utils'; +import { MlModel, MlModelDeploymentState } from '../types/ml'; import { MlInferencePipeline, TrainedModelState } from '../types/pipelines'; import { @@ -19,7 +20,7 @@ import { parseModelStateReasonFromStats, } from '.'; -const mockModel: MlTrainedModelConfig = { +const mockTrainedModel: MlTrainedModelConfig = { inference_config: { ner: {}, }, @@ -32,8 +33,27 @@ const mockModel: MlTrainedModelConfig = { version: '1', }; +const mockModel: MlModel = { + modelId: 'model_1', + type: 'ner', + title: 'Model 1', + description: 'Model 1 description', + licenseType: 'elastic', + modelDetailsPageUrl: 'https://my-model.ai', + deploymentState: MlModelDeploymentState.NotDeployed, + startTime: 0, + targetAllocationCount: 0, + nodeAllocationCount: 0, + threadsPerAllocation: 0, + isPlaceholder: false, + hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', +}; + describe('getMlModelTypesForModelConfig lib function', () => { - const builtInMockModel: MlTrainedModelConfig = { + const builtInMockTrainedModel: MlTrainedModelConfig = { inference_config: { text_classification: {}, }, @@ -47,13 +67,13 @@ describe('getMlModelTypesForModelConfig lib function', () => { it('should return the model type and inference config type', () => { const expected = ['pytorch', 'ner']; - const response = getMlModelTypesForModelConfig(mockModel); + const response = getMlModelTypesForModelConfig(mockTrainedModel); expect(response.sort()).toEqual(expected.sort()); }); it('should include the built in type', () => { const expected = ['lang_ident', 'text_classification', BUILT_IN_MODEL_TAG]; - const response = getMlModelTypesForModelConfig(builtInMockModel); + const response = getMlModelTypesForModelConfig(builtInMockTrainedModel); expect(response.sort()).toEqual(expected.sort()); }); }); @@ -71,9 +91,9 @@ describe('generateMlInferencePipelineBody lib function', () => { { inference: { field_map: { - 'my-source-field': 'MODEL_INPUT_FIELD', + 'my-source-field': 'title', }, - model_id: 'test_id', + model_id: 'model_1', on_failure: [ { append: { @@ -154,21 +174,21 @@ describe('generateMlInferencePipelineBody lib function', () => { { inference: expect.objectContaining({ field_map: { - 'my-source-field1': 'MODEL_INPUT_FIELD', + 'my-source-field1': 'title', }, }), }, { inference: expect.objectContaining({ field_map: { - 'my-source-field2': 'MODEL_INPUT_FIELD', + 'my-source-field2': 'title', }, }), }, { inference: expect.objectContaining({ field_map: { - 'my-source-field3': 'MODEL_INPUT_FIELD', + 'my-source-field3': 'title', }, }), }, diff --git a/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.ts b/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.ts index 5f56c1105b297..fa16dd29f83b1 100644 --- a/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.ts +++ b/x-pack/plugins/enterprise_search/common/ml_inference_pipeline/index.ts @@ -18,6 +18,8 @@ import { BUILT_IN_MODEL_TAG, } from '@kbn/ml-trained-models-utils'; +import { MlModel } from '../types/ml'; + import { MlInferencePipeline, CreateMLInferencePipeline, @@ -33,7 +35,7 @@ export interface MlInferencePipelineParams { description?: string; fieldMappings: FieldMapping[]; inferenceConfig?: InferencePipelineInferenceConfig; - model: MlTrainedModelConfig; + model: MlModel; pipelineName: string; } @@ -90,7 +92,7 @@ export const generateMlInferencePipelineBody = ({ model_version: model.version, pipeline: pipelineName, processed_timestamp: '{{{ _ingest.timestamp }}}', - types: getMlModelTypesForModelConfig(model), + types: model.types, }, ], }, @@ -104,19 +106,19 @@ export const getInferenceProcessor = ( sourceField: string, targetField: string, inferenceConfig: InferencePipelineInferenceConfig | undefined, - model: MlTrainedModelConfig, + model: MlModel, pipelineName: string ): IngestInferenceProcessor => { // If model returned no input field, insert a placeholder const modelInputField = - model.input?.field_names?.length > 0 ? model.input.field_names[0] : 'MODEL_INPUT_FIELD'; + model.inputFieldNames.length > 0 ? model.inputFieldNames[0] : 'MODEL_INPUT_FIELD'; return { field_map: { [sourceField]: modelInputField, }, inference_config: inferenceConfig, - model_id: model.model_id, + model_id: model.modelId, on_failure: [ { append: { diff --git a/x-pack/plugins/enterprise_search/common/types/ml.ts b/x-pack/plugins/enterprise_search/common/types/ml.ts index 894ffa6f0726b..2f40475535107 100644 --- a/x-pack/plugins/enterprise_search/common/types/ml.ts +++ b/x-pack/plugins/enterprise_search/common/types/ml.ts @@ -27,6 +27,10 @@ export interface MlModel { modelId: string; /** Model inference type, e.g. ner, text_classification */ type: string; + /** Type-related tags: model type (e.g. pytorch), inference type, built-in tag */ + types: string[]; + /** Field names in inference input configuration */ + inputFieldNames: string[]; title: string; description?: string; licenseType?: string; @@ -44,4 +48,5 @@ export interface MlModel { isPlaceholder: boolean; /** Does this model have deployment stats? */ hasStats: boolean; + version?: string; } diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.test.ts index 6d66ed5704721..869bd9273ac09 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.test.ts @@ -30,8 +30,11 @@ const DEFAULT_VALUES: CachedFetchModelsApiLogicValues = { const FETCH_MODELS_API_DATA_RESPONSE: MlModel[] = [ { modelId: 'model_1', - title: 'Model 1', type: 'ner', + title: 'Model 1', + description: 'Model 1 description', + licenseType: 'elastic', + modelDetailsPageUrl: 'https://my-model.ai', deploymentState: MlModelDeploymentState.NotDeployed, startTime: 0, targetAllocationCount: 0, @@ -39,6 +42,9 @@ const FETCH_MODELS_API_DATA_RESPONSE: MlModel[] = [ threadsPerAllocation: 0, isPlaceholder: false, hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', }, ]; const FETCH_MODELS_API_ERROR_RESPONSE = { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.ts index d65af6ec2fcf4..a26dbada96c08 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/cached_fetch_models_api_logic.ts @@ -18,6 +18,8 @@ import { FetchModelsApiLogic, FetchModelsApiResponse } from './fetch_models_api_ const FETCH_MODELS_POLLING_DURATION = 5000; // 5 seconds const FETCH_MODELS_POLLING_DURATION_ON_FAILURE = 30000; // 30 seconds +export type { FetchModelsApiResponse } from './fetch_models_api_logic'; + export interface CachedFetchModlesApiLogicActions { apiError: Actions<{}, FetchModelsApiResponse>['apiError']; apiReset: Actions<{}, FetchModelsApiResponse>['apiReset']; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.test.ts deleted file mode 100644 index 4bcea4ac4e83a..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { mockHttpValues } from '../../../__mocks__/kea_logic'; -import { mlModelStats } from '../../__mocks__/ml_models.mock'; - -import { getMLModelsStats } from './ml_model_stats_logic'; - -describe('MLModelsApiLogic', () => { - const { http } = mockHttpValues; - beforeEach(() => { - jest.clearAllMocks(); - }); - describe('getMLModelsStats', () => { - it('calls the ml api', async () => { - http.get.mockResolvedValue(mlModelStats); - const result = await getMLModelsStats(); - expect(http.get).toHaveBeenCalledWith('/internal/ml/trained_models/_stats', { version: '1' }); - expect(result).toEqual(mlModelStats); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.ts deleted file mode 100644 index d8bc341fcb6c3..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_model_stats_logic.ts +++ /dev/null @@ -1,35 +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 { MlTrainedModelStats } from '@elastic/elasticsearch/lib/api/types'; - -import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; -import { HttpLogic } from '../../../shared/http'; - -export type GetMlModelsStatsArgs = undefined; - -export interface GetMlModelsStatsResponse { - count: number; - trained_model_stats: MlTrainedModelStats[]; -} - -export const getMLModelsStats = async () => { - return await HttpLogic.values.http.get( - '/internal/ml/trained_models/_stats', - { version: '1' } - ); -}; - -export const MLModelsStatsApiLogic = createApiLogic( - ['ml_models_stats_api_logic'], - getMLModelsStats, - { - clearFlashMessagesOnMakeRequest: false, - showErrorFlash: false, - } -); - -export type MLModelsStatsApiLogicActions = Actions; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.test.ts deleted file mode 100644 index cffdc08dfd2ef..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.test.ts +++ /dev/null @@ -1,28 +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 { mockHttpValues } from '../../../__mocks__/kea_logic'; -import { mlModels } from '../../__mocks__/ml_models.mock'; - -import { getMLModels } from './ml_models_logic'; - -describe('MLModelsApiLogic', () => { - const { http } = mockHttpValues; - beforeEach(() => { - jest.clearAllMocks(); - }); - describe('getMLModels', () => { - it('calls the ml api', async () => { - http.get.mockResolvedValue(mlModels); - const result = await getMLModels(); - expect(http.get).toHaveBeenCalledWith('/internal/ml/trained_models', { - query: { size: 1000, with_pipelines: true }, - version: '1', - }); - expect(result).toEqual(mlModels); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.ts deleted file mode 100644 index 9cec020b8d782..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_models_logic.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 { TrainedModelConfigResponse } from '@kbn/ml-plugin/common/types/trained_models'; - -import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; -import { HttpLogic } from '../../../shared/http'; - -export type GetMlModelsArgs = number | undefined; - -export type GetMlModelsResponse = TrainedModelConfigResponse[]; - -export const getMLModels = async (size: GetMlModelsArgs = 1000) => { - return await HttpLogic.values.http.get( - '/internal/ml/trained_models', - { - query: { size, with_pipelines: true }, - version: '1', - } - ); -}; - -export const MLModelsApiLogic = createApiLogic(['ml_models_api_logic'], getMLModels, { - clearFlashMessagesOnMakeRequest: false, - showErrorFlash: false, -}); - -export type MLModelsApiLogicActions = Actions; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.test.ts deleted file mode 100644 index 6a1a4e0e512df..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.test.ts +++ /dev/null @@ -1,177 +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 { LogicMounter } from '../../../__mocks__/kea_logic'; -import { mlModels, mlModelStats } from '../../__mocks__/ml_models.mock'; - -import { HttpError, Status } from '../../../../../common/types/api'; - -import { MLModelsStatsApiLogic } from './ml_model_stats_logic'; -import { MLModelsApiLogic } from './ml_models_logic'; -import { TrainedModelsApiLogic, TrainedModelsApiLogicValues } from './ml_trained_models_logic'; - -const DEFAULT_VALUES: TrainedModelsApiLogicValues = { - error: null, - status: Status.IDLE, - data: null, - // models - modelsApiStatus: { - status: Status.IDLE, - }, - modelsData: undefined, - modelsApiError: undefined, - modelsStatus: Status.IDLE, - // stats - modelStatsApiStatus: { - status: Status.IDLE, - }, - modelStatsData: undefined, - modelsStatsApiError: undefined, - modelStatsStatus: Status.IDLE, -}; - -describe('TrainedModelsApiLogic', () => { - const { mount } = new LogicMounter(TrainedModelsApiLogic); - const { mount: mountMLModelsApiLogic } = new LogicMounter(MLModelsApiLogic); - const { mount: mountMLModelsStatsApiLogic } = new LogicMounter(MLModelsStatsApiLogic); - - beforeEach(() => { - jest.clearAllMocks(); - - mountMLModelsApiLogic(); - mountMLModelsStatsApiLogic(); - mount(); - }); - - it('has default values', () => { - expect(TrainedModelsApiLogic.values).toEqual(DEFAULT_VALUES); - }); - describe('selectors', () => { - describe('data', () => { - it('returns combined trained models', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - MLModelsStatsApiLogic.actions.apiSuccess(mlModelStats); - - expect(TrainedModelsApiLogic.values.data).toEqual([ - { - ...mlModels[0], - ...mlModelStats.trained_model_stats[0], - }, - { - ...mlModels[1], - ...mlModelStats.trained_model_stats[1], - }, - { - ...mlModels[2], - ...mlModelStats.trained_model_stats[2], - }, - ]); - }); - it('returns just models if stats not available', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - - expect(TrainedModelsApiLogic.values.data).toEqual(mlModels); - }); - it('returns null trained models even with stats if models missing', () => { - MLModelsStatsApiLogic.actions.apiSuccess(mlModelStats); - - expect(TrainedModelsApiLogic.values.data).toEqual(null); - }); - }); - describe('error', () => { - const modelError: HttpError = { - body: { - error: 'Model Error', - statusCode: 400, - }, - fetchOptions: {}, - request: {}, - } as HttpError; - const statsError: HttpError = { - body: { - error: 'Stats Error', - statusCode: 500, - }, - fetchOptions: {}, - request: {}, - } as HttpError; - - it('returns null with no errors', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - MLModelsStatsApiLogic.actions.apiSuccess(mlModelStats); - - expect(TrainedModelsApiLogic.values.error).toBeNull(); - }); - it('models error', () => { - MLModelsApiLogic.actions.apiError(modelError); - - expect(TrainedModelsApiLogic.values.error).toBe(modelError); - }); - it('stats error', () => { - MLModelsStatsApiLogic.actions.apiError(statsError); - - expect(TrainedModelsApiLogic.values.error).toBe(statsError); - }); - it('prefers models error if both api calls fail', () => { - MLModelsApiLogic.actions.apiError(modelError); - MLModelsStatsApiLogic.actions.apiError(statsError); - - expect(TrainedModelsApiLogic.values.error).toBe(modelError); - }); - }); - describe('status', () => { - it('returns matching status for both calls', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - MLModelsStatsApiLogic.actions.apiSuccess(mlModelStats); - - expect(TrainedModelsApiLogic.values.status).toEqual(Status.SUCCESS); - }); - it('returns models status when its lower', () => { - MLModelsStatsApiLogic.actions.apiSuccess(mlModelStats); - - expect(TrainedModelsApiLogic.values.status).toEqual(Status.IDLE); - }); - it('returns stats status when its lower', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - - expect(TrainedModelsApiLogic.values.status).toEqual(Status.IDLE); - }); - it('returns error status if one api call fails', () => { - MLModelsApiLogic.actions.apiSuccess(mlModels); - MLModelsStatsApiLogic.actions.apiError({ - body: { - error: 'Stats Error', - statusCode: 500, - }, - fetchOptions: {}, - request: {}, - } as HttpError); - - expect(TrainedModelsApiLogic.values.status).toEqual(Status.ERROR); - }); - }); - }); - describe('actions', () => { - it('makeRequest fetches models and stats', () => { - jest.spyOn(TrainedModelsApiLogic.actions, 'makeGetModelsRequest'); - jest.spyOn(TrainedModelsApiLogic.actions, 'makeGetModelsStatsRequest'); - - TrainedModelsApiLogic.actions.makeRequest(undefined); - - expect(TrainedModelsApiLogic.actions.makeGetModelsRequest).toHaveBeenCalledTimes(1); - expect(TrainedModelsApiLogic.actions.makeGetModelsStatsRequest).toHaveBeenCalledTimes(1); - }); - it('apiReset resets both api logics', () => { - jest.spyOn(TrainedModelsApiLogic.actions, 'getModelsApiReset'); - jest.spyOn(TrainedModelsApiLogic.actions, 'getModelsStatsApiReset'); - - TrainedModelsApiLogic.actions.apiReset(); - - expect(TrainedModelsApiLogic.actions.getModelsApiReset).toHaveBeenCalledTimes(1); - expect(TrainedModelsApiLogic.actions.getModelsStatsApiReset).toHaveBeenCalledTimes(1); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.ts deleted file mode 100644 index d36a80df6af6a..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/ml_trained_models_logic.ts +++ /dev/null @@ -1,169 +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 { kea, MakeLogicType } from 'kea'; - -import { MlTrainedModelStats } from '@elastic/elasticsearch/lib/api/types'; -import { TrainedModelConfigResponse } from '@kbn/ml-plugin/common/types/trained_models'; - -import { ApiStatus, Status, HttpError } from '../../../../../common/types/api'; -import { Actions } from '../../../shared/api_logic/create_api_logic'; - -import { - GetMlModelsStatsResponse, - MLModelsStatsApiLogic, - MLModelsStatsApiLogicActions, -} from './ml_model_stats_logic'; -import { GetMlModelsResponse, MLModelsApiLogic, MLModelsApiLogicActions } from './ml_models_logic'; - -export type TrainedModel = TrainedModelConfigResponse & Partial; - -export type TrainedModelsApiLogicActions = Actions & { - getModelsApiError: MLModelsApiLogicActions['apiError']; - getModelsApiReset: MLModelsApiLogicActions['apiReset']; - getModelsApiSuccess: MLModelsApiLogicActions['apiSuccess']; - getModelsStatsApiError: MLModelsStatsApiLogicActions['apiError']; - getModelsStatsApiReset: MLModelsStatsApiLogicActions['apiReset']; - getModelsStatsApiSuccess: MLModelsStatsApiLogicActions['apiSuccess']; - makeGetModelsRequest: MLModelsApiLogicActions['makeRequest']; - makeGetModelsStatsRequest: MLModelsStatsApiLogicActions['makeRequest']; -}; -export interface TrainedModelsApiLogicValues { - error: HttpError | null; - status: Status; - data: TrainedModel[] | null; - // models - modelsApiStatus: ApiStatus; - modelsData: GetMlModelsResponse | undefined; - modelsApiError?: HttpError; - modelsStatus: Status; - // stats - modelStatsApiStatus: ApiStatus; - modelStatsData: GetMlModelsStatsResponse | undefined; - modelsStatsApiError?: HttpError; - modelStatsStatus: Status; -} - -export const TrainedModelsApiLogic = kea< - MakeLogicType ->({ - actions: { - apiError: (error) => error, - apiReset: true, - apiSuccess: (result) => result, - makeRequest: () => undefined, - }, - connect: { - actions: [ - MLModelsApiLogic, - [ - 'apiError as getModelsApiError', - 'apiReset as getModelsApiReset', - 'apiSuccess as getModelsApiSuccess', - 'makeRequest as makeGetModelsRequest', - ], - MLModelsStatsApiLogic, - [ - 'apiError as getModelsStatsApiError', - 'apiReset as getModelsStatsApiReset', - 'apiSuccess as getModelsStatsApiSuccess', - 'makeRequest as makeGetModelsStatsRequest', - ], - ], - values: [ - MLModelsApiLogic, - [ - 'apiStatus as modelsApiStatus', - 'error as modelsApiError', - 'status as modelsStatus', - 'data as modelsData', - ], - MLModelsStatsApiLogic, - [ - 'apiStatus as modelStatsApiStatus', - 'error as modelsStatsApiError', - 'status as modelStatsStatus', - 'data as modelStatsData', - ], - ], - }, - listeners: ({ actions, values }) => ({ - getModelsApiError: (error) => { - actions.apiError(error); - }, - getModelsApiSuccess: () => { - if (!values.data) return; - actions.apiSuccess(values.data); - }, - getModelsStatsApiError: (error) => { - if (values.modelsApiError) return; - actions.apiError(error); - }, - getModelsStatsApiSuccess: () => { - if (!values.data) return; - actions.apiSuccess(values.data); - }, - apiReset: () => { - actions.getModelsApiReset(); - actions.getModelsStatsApiReset(); - }, - makeRequest: () => { - actions.makeGetModelsRequest(undefined); - actions.makeGetModelsStatsRequest(undefined); - }, - }), - path: ['enterprise_search', 'api', 'ml_trained_models_api_logic'], - selectors: ({ selectors }) => ({ - data: [ - () => [selectors.modelsData, selectors.modelStatsData], - ( - modelsData: TrainedModelsApiLogicValues['modelsData'], - modelStatsData: TrainedModelsApiLogicValues['modelStatsData'] - ): TrainedModel[] | null => { - if (!modelsData) return null; - if (!modelStatsData) return modelsData; - const statsMap: Record = - modelStatsData.trained_model_stats.reduce((map, value) => { - if (value.model_id) { - map[value.model_id] = value; - } - return map; - }, {} as Record); - return modelsData.map((modelConfig) => { - const modelStats = statsMap[modelConfig.model_id]; - return { - ...modelConfig, - ...(modelStats ?? {}), - }; - }); - }, - ], - error: [ - () => [selectors.modelsApiStatus, selectors.modelStatsApiStatus], - ( - modelsApiStatus: TrainedModelsApiLogicValues['modelsApiStatus'], - modelStatsApiStatus: TrainedModelsApiLogicValues['modelStatsApiStatus'] - ) => { - if (modelsApiStatus.error) return modelsApiStatus.error; - if (modelStatsApiStatus.error) return modelStatsApiStatus.error; - return null; - }, - ], - status: [ - () => [selectors.modelsApiStatus, selectors.modelStatsApiStatus], - ( - modelsApiStatus: TrainedModelsApiLogicValues['modelsApiStatus'], - modelStatsApiStatus: TrainedModelsApiLogicValues['modelStatsApiStatus'] - ) => { - if (modelsApiStatus.status === modelStatsApiStatus.status) return modelsApiStatus.status; - if (modelsApiStatus.status === Status.ERROR || modelStatsApiStatus.status === Status.ERROR) - return Status.ERROR; - if (modelsApiStatus.status < modelStatsApiStatus.status) return modelsApiStatus.status; - return modelStatsApiStatus.status; - }, - ], - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.test.tsx index 68bf7fc48e7dd..09789e34c963b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.test.tsx @@ -29,7 +29,6 @@ import { import { ConfigureFields } from './configure_fields'; import { ConfigurePipeline } from './configure_pipeline'; import { EMPTY_PIPELINE_CONFIGURATION } from './ml_inference_logic'; -import { NoModelsPanel } from './no_models'; import { ReviewPipeline } from './review_pipeline'; import { TestPipeline } from './test_pipeline'; import { AddInferencePipelineSteps } from './types'; @@ -82,11 +81,6 @@ describe('AddInferencePipelineFlyout', () => { const wrapper = shallow(); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(1); }); - it('renders no models panel when there are no models', () => { - setMockValues({ ...DEFAULT_VALUES, supportedMLModels: [] }); - const wrapper = shallow(); - expect(wrapper.find(NoModelsPanel)).toHaveLength(1); - }); it('renders AddInferencePipelineHorizontalSteps', () => { const wrapper = shallow(); expect(wrapper.find(AddInferencePipelineHorizontalSteps)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.tsx index 654cdafad35eb..57aa7ab467488 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/add_inference_pipeline_flyout.tsx @@ -41,7 +41,6 @@ import { IndexViewLogic } from '../../index_view_logic'; import { ConfigureFields } from './configure_fields'; import { ConfigurePipeline } from './configure_pipeline'; import { MLInferenceLogic } from './ml_inference_logic'; -import { NoModelsPanel } from './no_models'; import { ReviewPipeline } from './review_pipeline'; import { TestPipeline } from './test_pipeline'; import { AddInferencePipelineSteps } from './types'; @@ -54,9 +53,15 @@ export interface AddInferencePipelineFlyoutProps { export const AddInferencePipelineFlyout = (props: AddInferencePipelineFlyoutProps) => { const { indexName } = useValues(IndexNameLogic); - const { setIndexName } = useActions(MLInferenceLogic); + const { setIndexName, makeMlInferencePipelinesRequest, startPollingModels, makeMappingRequest } = + useActions(MLInferenceLogic); useEffect(() => { setIndexName(indexName); + + // Trigger fetching of initial data: existing ML pipelines, available models, index mapping + makeMlInferencePipelinesRequest(undefined); + startPollingModels(); + makeMappingRequest({ indexName }); }, [indexName]); return ( @@ -82,7 +87,6 @@ export const AddInferencePipelineContent = ({ onClose }: AddInferencePipelineFly const { ingestionMethod } = useValues(IndexViewLogic); const { createErrors, - supportedMLModels, isLoading, addInferencePipelineModal: { step }, } = useValues(MLInferenceLogic); @@ -103,9 +107,6 @@ export const AddInferencePipelineContent = ({ onClose }: AddInferencePipelineFly ); } - if (supportedMLModels.length === 0) { - return ; - } return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx index 7b3fdf4353d99..244f7a3e8a200 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/inference_config.tsx @@ -14,7 +14,6 @@ import { i18n } from '@kbn/i18n'; import { SUPPORTED_PYTORCH_TASKS } from '@kbn/ml-trained-models-utils'; -import { getMlModelTypesForModelConfig } from '../../../../../../../common/ml_inference_pipeline'; import { getMLType } from '../../../shared/ml_inference/utils'; import { MLInferenceLogic } from './ml_inference_logic'; @@ -23,10 +22,10 @@ import { ZeroShotClassificationInferenceConfiguration } from './zero_shot_infere export const InferenceConfiguration: React.FC = () => { const { addInferencePipelineModal: { configuration }, - selectedMLModel, + selectedModel, } = useValues(MLInferenceLogic); - if (!selectedMLModel || configuration.existingPipeline) return null; - const modelType = getMLType(getMlModelTypesForModelConfig(selectedMLModel)); + if (!selectedModel || configuration.existingPipeline) return null; + const modelType = getMLType(selectedModel.types); switch (modelType) { case SUPPORTED_PYTORCH_TASKS.ZERO_SHOT_CLASSIFICATION: return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index e12366f42f3ef..ae3cc237c67a5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -6,16 +6,16 @@ */ import { LogicMounter } from '../../../../../__mocks__/kea_logic'; -import { nerModel, textExpansionModel } from '../../../../__mocks__/ml_models.mock'; import { HttpResponse } from '@kbn/core/public'; -import { ErrorResponse } from '../../../../../../../common/types/api'; +import { ErrorResponse, Status } from '../../../../../../../common/types/api'; +import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml'; import { TrainedModelState } from '../../../../../../../common/types/pipelines'; import { GetDocumentsApiLogic } from '../../../../api/documents/get_document_logic'; import { MappingsApiLogic } from '../../../../api/mappings/mappings_logic'; -import { MLModelsApiLogic } from '../../../../api/ml_models/ml_models_logic'; +import { CachedFetchModelsApiLogic } from '../../../../api/ml_models/cached_fetch_models_api_logic'; import { StartTextExpansionModelApiLogic } from '../../../../api/ml_models/text_expansion/start_text_expansion_model_api_logic'; import { AttachMlInferencePipelineApiLogic } from '../../../../api/pipelines/attach_ml_inference_pipeline'; import { CreateMlInferencePipelineApiLogic } from '../../../../api/pipelines/create_ml_inference_pipeline'; @@ -50,6 +50,7 @@ const DEFAULT_VALUES: MLInferenceProcessorsValues = { index: null, isConfigureStepValid: false, isLoading: true, + isModelsInitialLoading: false, isPipelineDataValid: false, isTextExpansionModelSelected: false, mappingData: undefined, @@ -57,17 +58,38 @@ const DEFAULT_VALUES: MLInferenceProcessorsValues = { mlInferencePipeline: undefined, mlInferencePipelineProcessors: undefined, mlInferencePipelinesData: undefined, - mlModelsData: null, - mlModelsStatus: 0, - selectedMLModel: null, + modelsData: undefined, + modelsStatus: 0, + selectableModels: [], + selectedModel: undefined, sourceFields: undefined, - supportedMLModels: [], }; +const MODELS: MlModel[] = [ + { + modelId: 'model_1', + type: 'ner', + title: 'Model 1', + description: 'Model 1 description', + licenseType: 'elastic', + modelDetailsPageUrl: 'https://my-model.ai', + deploymentState: MlModelDeploymentState.NotDeployed, + startTime: 0, + targetAllocationCount: 0, + nodeAllocationCount: 0, + threadsPerAllocation: 0, + isPlaceholder: false, + hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', + }, +]; + describe('MlInferenceLogic', () => { const { mount } = new LogicMounter(MLInferenceLogic); const { mount: mountMappingApiLogic } = new LogicMounter(MappingsApiLogic); - const { mount: mountMLModelsApiLogic } = new LogicMounter(MLModelsApiLogic); + const { mount: mountCachedFetchModelsApiLogic } = new LogicMounter(CachedFetchModelsApiLogic); const { mount: mountSimulateExistingMlInterfacePipelineApiLogic } = new LogicMounter( SimulateExistingMlInterfacePipelineApiLogic ); @@ -92,7 +114,7 @@ describe('MlInferenceLogic', () => { beforeEach(() => { jest.clearAllMocks(); mountMappingApiLogic(); - mountMLModelsApiLogic(); + mountCachedFetchModelsApiLogic(); mountFetchMlInferencePipelineProcessorsApiLogic(); mountFetchMlInferencePipelinesApiLogic(); mountSimulateExistingMlInterfacePipelineApiLogic(); @@ -105,7 +127,13 @@ describe('MlInferenceLogic', () => { }); it('has expected default values', () => { - expect(MLInferenceLogic.values).toEqual(DEFAULT_VALUES); + CachedFetchModelsApiLogic.actions.apiSuccess(MODELS); + expect(MLInferenceLogic.values).toEqual({ + ...DEFAULT_VALUES, + modelsData: MODELS, // Populated by afterMount hook + modelsStatus: Status.SUCCESS, + selectableModels: MODELS, + }); }); describe('actions', () => { @@ -184,6 +212,7 @@ describe('MlInferenceLogic', () => { describe('selectors', () => { describe('existingInferencePipelines', () => { beforeEach(() => { + CachedFetchModelsApiLogic.actions.apiSuccess(MODELS); MappingsApiLogic.actions.apiSuccess({ mappings: { properties: { @@ -206,7 +235,7 @@ describe('MlInferenceLogic', () => { field_map: { body: 'text_field', }, - model_id: 'test-model', + model_id: MODELS[0].modelId, target_field: 'ml.inference.test-field', }, }, @@ -218,8 +247,8 @@ describe('MlInferenceLogic', () => { expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([ { disabled: false, - modelId: 'test-model', - modelType: '', + modelId: MODELS[0].modelId, + modelType: 'ner', pipelineName: 'unit-test', sourceFields: ['body'], indexFields: ['body'], @@ -235,7 +264,7 @@ describe('MlInferenceLogic', () => { field_map: { title: 'text_field', // Does not exist in index }, - model_id: 'test-model', + model_id: MODELS[0].modelId, target_field: 'ml.inference.title', }, }, @@ -244,7 +273,7 @@ describe('MlInferenceLogic', () => { field_map: { body: 'text_field', // Exists in index }, - model_id: 'test-model', + model_id: MODELS[0].modelId, target_field: 'ml.inference.body', }, }, @@ -253,7 +282,7 @@ describe('MlInferenceLogic', () => { field_map: { body_content: 'text_field', // Does not exist in index }, - model_id: 'test-model', + model_id: MODELS[0].modelId, target_field: 'ml.inference.body_content', }, }, @@ -266,8 +295,8 @@ describe('MlInferenceLogic', () => { { disabled: true, disabledReason: expect.stringContaining('title, body_content'), - modelId: 'test-model', - modelType: '', + modelId: MODELS[0].modelId, + modelType: 'ner', pipelineName: 'unit-test', sourceFields: ['title', 'body', 'body_content'], indexFields: ['body'], @@ -306,7 +335,7 @@ describe('MlInferenceLogic', () => { it('filters pipeline if pipeline already attached', () => { FetchMlInferencePipelineProcessorsApiLogic.actions.apiSuccess([ { - modelId: 'test-model', + modelId: MODELS[0].modelId, modelState: TrainedModelState.Started, pipelineName: 'unit-test', pipelineReferences: ['test@ml-inference'], @@ -321,7 +350,7 @@ describe('MlInferenceLogic', () => { field_map: { body: 'text_field', }, - model_id: 'test-model', + model_id: MODELS[0].modelId, target_field: 'ml.inference.test-field', }, }, @@ -333,165 +362,6 @@ describe('MlInferenceLogic', () => { expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([]); }); }); - describe('mlInferencePipeline', () => { - it('returns undefined when configuration is invalid', () => { - MLInferenceLogic.actions.setInferencePipelineConfiguration({ - modelID: '', - pipelineName: '', // Invalid - fieldMappings: [], // Invalid - targetField: '', - }); - - expect(MLInferenceLogic.values.mlInferencePipeline).toBeUndefined(); - }); - it('generates inference pipeline', () => { - MLModelsApiLogic.actions.apiSuccess([nerModel]); - MLInferenceLogic.actions.setInferencePipelineConfiguration({ - modelID: nerModel.model_id, - pipelineName: 'unit-test', - fieldMappings: [ - { - sourceField: 'body', - targetField: 'ml.inference.body', - }, - ], - targetField: '', - }); - - expect(MLInferenceLogic.values.mlInferencePipeline).not.toBeUndefined(); - }); - it('returns undefined when existing pipeline not yet selected', () => { - MLInferenceLogic.actions.setInferencePipelineConfiguration({ - existingPipeline: true, - modelID: '', - pipelineName: '', - fieldMappings: [], - targetField: '', - }); - expect(MLInferenceLogic.values.mlInferencePipeline).toBeUndefined(); - }); - it('return existing pipeline when selected', () => { - const existingPipeline = { - description: 'this is a test', - processors: [], - version: 1, - }; - FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ - 'unit-test': existingPipeline, - }); - MLInferenceLogic.actions.setInferencePipelineConfiguration({ - existingPipeline: true, - modelID: '', - pipelineName: 'unit-test', - fieldMappings: [ - { - sourceField: 'body', - targetField: 'ml.inference.body', - }, - ], - targetField: '', - }); - expect(MLInferenceLogic.values.mlInferencePipeline).not.toBeUndefined(); - expect(MLInferenceLogic.values.mlInferencePipeline).toEqual(existingPipeline); - }); - }); - describe('supportedMLModels', () => { - it('filters unsupported ML models', () => { - MLModelsApiLogic.actions.apiSuccess([ - { - inference_config: { - ner: {}, - }, - input: { - field_names: ['text_field'], - }, - model_id: 'ner-mocked-model', - model_type: 'pytorch', - tags: [], - version: '1', - }, - { - inference_config: { - some_unsupported_task_type: {}, - }, - input: { - field_names: ['text_field'], - }, - model_id: 'unsupported-mocked-model', - model_type: 'pytorch', - tags: [], - version: '1', - }, - ]); - - expect(MLInferenceLogic.values.supportedMLModels).toEqual([ - expect.objectContaining({ - inference_config: { - ner: {}, - }, - }), - ]); - }); - - it('promotes text_expansion ML models and sorts others by ID', () => { - MLModelsApiLogic.actions.apiSuccess([ - { - inference_config: { - ner: {}, - }, - input: { - field_names: ['text_field'], - }, - model_id: 'ner-mocked-model', - model_type: 'pytorch', - tags: [], - version: '1', - }, - { - inference_config: { - text_expansion: {}, - }, - input: { - field_names: ['text_field'], - }, - model_id: 'text-expansion-mocked-model', - model_type: 'pytorch', - tags: [], - version: '1', - }, - { - inference_config: { - text_embedding: {}, - }, - input: { - field_names: ['text_field'], - }, - model_id: 'text-embedding-mocked-model', - model_type: 'pytorch', - tags: [], - version: '1', - }, - ]); - - expect(MLInferenceLogic.values.supportedMLModels).toEqual([ - expect.objectContaining({ - inference_config: { - text_expansion: {}, - }, - }), - expect.objectContaining({ - inference_config: { - ner: {}, - }, - }), - expect.objectContaining({ - inference_config: { - text_embedding: {}, - }, - }), - ]); - }); - }); describe('formErrors', () => { it('has errors when configuration is empty', () => { expect(MLInferenceLogic.values.formErrors).toEqual({ @@ -570,6 +440,75 @@ describe('MlInferenceLogic', () => { }); }); }); + describe('mlInferencePipeline', () => { + it('returns undefined when configuration is invalid', () => { + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + modelID: '', + pipelineName: '', // Invalid + fieldMappings: [], // Invalid + targetField: '', + }); + + expect(MLInferenceLogic.values.mlInferencePipeline).toBeUndefined(); + }); + it('generates inference pipeline', () => { + CachedFetchModelsApiLogic.actions.apiSuccess(MODELS); + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + modelID: MODELS[0].modelId, + pipelineName: 'unit-test', + fieldMappings: [ + { + sourceField: 'body', + targetField: 'ml.inference.body', + }, + ], + targetField: '', + }); + + expect(MLInferenceLogic.values.mlInferencePipeline).not.toBeUndefined(); + }); + it('returns undefined when existing pipeline not yet selected', () => { + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + existingPipeline: true, + modelID: '', + pipelineName: '', + fieldMappings: [], + targetField: '', + }); + expect(MLInferenceLogic.values.mlInferencePipeline).toBeUndefined(); + }); + it('return existing pipeline when selected', () => { + const existingPipeline = { + description: 'this is a test', + processors: [], + version: 1, + }; + FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ + 'unit-test': existingPipeline, + }); + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + existingPipeline: true, + modelID: '', + pipelineName: 'unit-test', + fieldMappings: [ + { + sourceField: 'body', + targetField: 'ml.inference.body', + }, + ], + targetField: '', + }); + expect(MLInferenceLogic.values.mlInferencePipeline).not.toBeUndefined(); + expect(MLInferenceLogic.values.mlInferencePipeline).toEqual(existingPipeline); + }); + }); + describe('selectableModels', () => { + it('makes fetch models request', () => { + MLInferenceLogic.actions.fetchModelsApiSuccess(MODELS); + + expect(MLInferenceLogic.values.selectableModels).toBe(MODELS); + }); + }); }); describe('listeners', () => { @@ -615,14 +554,14 @@ describe('MlInferenceLogic', () => { ...mockModelConfiguration, configuration: { ...mockModelConfiguration.configuration, - modelID: textExpansionModel.model_id, + modelID: MODELS[0].modelId, fieldMappings: [], }, }, }); jest.spyOn(MLInferenceLogic.actions, 'makeCreatePipelineRequest'); - MLModelsApiLogic.actions.apiSuccess([textExpansionModel]); + CachedFetchModelsApiLogic.actions.apiSuccess(MODELS); MLInferenceLogic.actions.selectFields(['my_source_field1', 'my_source_field2']); MLInferenceLogic.actions.addSelectedFieldsToMapping(true); MLInferenceLogic.actions.createPipeline(); @@ -630,7 +569,7 @@ describe('MlInferenceLogic', () => { expect(MLInferenceLogic.actions.makeCreatePipelineRequest).toHaveBeenCalledWith({ indexName: mockModelConfiguration.indexName, inferenceConfig: undefined, - modelId: textExpansionModel.model_id, + modelId: MODELS[0].modelId, fieldMappings: [ { sourceField: 'my_source_field1', @@ -648,13 +587,13 @@ describe('MlInferenceLogic', () => { }); describe('startTextExpansionModelSuccess', () => { it('fetches ml models', () => { - jest.spyOn(MLInferenceLogic.actions, 'makeMLModelsRequest'); + jest.spyOn(MLInferenceLogic.actions, 'startPollingModels'); StartTextExpansionModelApiLogic.actions.apiSuccess({ deploymentState: 'started', modelId: 'foo', }); - expect(MLInferenceLogic.actions.makeMLModelsRequest).toHaveBeenCalledWith(undefined); + expect(MLInferenceLogic.actions.startPollingModels).toHaveBeenCalled(); }); }); describe('onAddInferencePipelineStepChange', () => { @@ -673,12 +612,12 @@ describe('MlInferenceLogic', () => { existingPipeline: false, }); jest.spyOn(MLInferenceLogic.actions, 'fetchPipelineByName'); - jest.spyOn(MLInferenceLogic.actions, 'makeMLModelsRequest'); + jest.spyOn(MLInferenceLogic.actions, 'startPollingModels'); MLInferenceLogic.actions.onAddInferencePipelineStepChange(AddInferencePipelineSteps.Fields); expect(MLInferenceLogic.actions.fetchPipelineByName).toHaveBeenCalledWith({ pipelineName: 'ml-inference-unit-test-pipeline', }); - expect(MLInferenceLogic.actions.makeMLModelsRequest).toHaveBeenCalledWith(undefined); + expect(MLInferenceLogic.actions.startPollingModels).toHaveBeenCalled(); }); it('does not trigger pipeline and model fetch existing pipeline is selected', () => { MLInferenceLogic.actions.setInferencePipelineConfiguration({ @@ -688,10 +627,10 @@ describe('MlInferenceLogic', () => { existingPipeline: true, }); jest.spyOn(MLInferenceLogic.actions, 'fetchPipelineByName'); - jest.spyOn(MLInferenceLogic.actions, 'makeMLModelsRequest'); + jest.spyOn(MLInferenceLogic.actions, 'startPollingModels'); MLInferenceLogic.actions.onAddInferencePipelineStepChange(AddInferencePipelineSteps.Fields); expect(MLInferenceLogic.actions.fetchPipelineByName).not.toHaveBeenCalled(); - expect(MLInferenceLogic.actions.makeMLModelsRequest).not.toHaveBeenCalled(); + expect(MLInferenceLogic.actions.startPollingModels).not.toHaveBeenCalled(); }); }); describe('fetchPipelineSuccess', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index bdcf23d71a743..3383a8772f3ce 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -14,11 +14,11 @@ import { formatPipelineName, generateMlInferencePipelineBody, getMlInferencePrefixedFieldName, - getMlModelTypesForModelConfig, ML_INFERENCE_PREFIX, parseMlInferenceParametersFromPipeline, } from '../../../../../../../common/ml_inference_pipeline'; import { Status } from '../../../../../../../common/types/api'; +import { MlModel } from '../../../../../../../common/types/ml'; import { MlInferencePipeline } from '../../../../../../../common/types/pipelines'; import { Actions } from '../../../../../shared/api_logic/create_api_logic'; @@ -34,10 +34,10 @@ import { MappingsApiLogic, } from '../../../../api/mappings/mappings_logic'; import { - TrainedModel, - TrainedModelsApiLogicActions, - TrainedModelsApiLogic, -} from '../../../../api/ml_models/ml_trained_models_logic'; + CachedFetchModelsApiLogic, + CachedFetchModlesApiLogicActions, + FetchModelsApiResponse, +} from '../../../../api/ml_models/cached_fetch_models_api_logic'; import { StartTextExpansionModelApiLogic, StartTextExpansionModelApiLogicActions, @@ -68,12 +68,7 @@ import { } from '../../../../api/pipelines/fetch_pipeline'; import { isConnectorIndex } from '../../../../utils/indices'; -import { - getMLType, - isSupportedMLModel, - sortModels, - sortSourceFields, -} from '../../../shared/ml_inference/utils'; +import { getMLType, sortSourceFields } from '../../../shared/ml_inference/utils'; import { PipelinesLogic } from '../pipelines_logic'; import { @@ -143,6 +138,7 @@ export interface MLInferenceProcessorsActions { CreateMlInferencePipelineResponse >['apiSuccess']; createPipeline: () => void; + fetchModelsApiSuccess: CachedFetchModlesApiLogicActions['apiSuccess']; fetchPipelineByName: FetchPipelineApiLogicActions['makeRequest']; fetchPipelineSuccess: FetchPipelineApiLogicActions['apiSuccess']; makeAttachPipelineRequest: Actions< @@ -153,7 +149,6 @@ export interface MLInferenceProcessorsActions { CreateMlInferencePipelineApiLogicArgs, CreateMlInferencePipelineResponse >['makeRequest']; - makeMLModelsRequest: TrainedModelsApiLogicActions['makeRequest']; makeMappingRequest: Actions['makeRequest']; makeMlInferencePipelinesRequest: Actions< FetchMlInferencePipelinesArgs, @@ -164,7 +159,6 @@ export interface MLInferenceProcessorsActions { FetchMlInferencePipelinesArgs, FetchMlInferencePipelinesResponse >['apiSuccess']; - mlModelsApiError: TrainedModelsApiLogicActions['apiError']; onAddInferencePipelineStepChange: (step: AddInferencePipelineSteps) => { step: AddInferencePipelineSteps; }; @@ -181,6 +175,7 @@ export interface MLInferenceProcessorsActions { configuration: InferencePipelineConfiguration; }; setTargetField: (targetFieldName: string) => { targetFieldName: string }; + startPollingModels: CachedFetchModlesApiLogicActions['startPolling']; startTextExpansionModelSuccess: StartTextExpansionModelApiLogicActions['apiSuccess']; } @@ -200,6 +195,7 @@ export interface MLInferenceProcessorsValues { index: CachedFetchIndexApiLogicValues['indexData']; isConfigureStepValid: boolean; isLoading: boolean; + isModelsInitialLoading: boolean; isPipelineDataValid: boolean; isTextExpansionModelSelected: boolean; mappingData: typeof MappingsApiLogic.values.data; @@ -207,11 +203,11 @@ export interface MLInferenceProcessorsValues { mlInferencePipeline: MlInferencePipeline | undefined; mlInferencePipelineProcessors: FetchMlInferencePipelineProcessorsResponse | undefined; mlInferencePipelinesData: FetchMlInferencePipelinesResponse | undefined; - mlModelsData: TrainedModel[] | null; - mlModelsStatus: Status; - selectedMLModel: TrainedModel | null; + modelsData: FetchModelsApiResponse | undefined; + modelsStatus: Status; + selectableModels: MlModel[]; + selectedModel: MlModel | undefined; sourceFields: string[] | undefined; - supportedMLModels: TrainedModel[]; } export const MLInferenceLogic = kea< @@ -238,6 +234,8 @@ export const MLInferenceLogic = kea< }, connect: { actions: [ + CachedFetchModelsApiLogic, + ['apiSuccess as fetchModelsApiSuccess', 'startPolling as startPollingModels'], FetchMlInferencePipelinesApiLogic, [ 'makeRequest as makeMlInferencePipelinesRequest', @@ -245,8 +243,6 @@ export const MLInferenceLogic = kea< ], MappingsApiLogic, ['makeRequest as makeMappingRequest', 'apiError as mappingsApiError'], - TrainedModelsApiLogic, - ['makeRequest as makeMLModelsRequest', 'apiError as mlModelsApiError'], CreateMlInferencePipelineApiLogic, [ 'apiError as createApiError', @@ -260,7 +256,7 @@ export const MLInferenceLogic = kea< 'makeRequest as makeAttachPipelineRequest', ], PipelinesLogic, - ['closeAddMlInferencePipelineModal as closeAddMlInferencePipelineModal'], + ['closeAddMlInferencePipelineModal'], StartTextExpansionModelApiLogic, ['apiSuccess as startTextExpansionModelSuccess'], FetchPipelineApiLogic, @@ -271,21 +267,20 @@ export const MLInferenceLogic = kea< ], ], values: [ + CachedFetchModelsApiLogic, + ['modelsData', 'status as modelsStatus', 'isInitialLoading as isModelsInitialLoading'], CachedFetchIndexApiLogic, ['indexData as index'], FetchMlInferencePipelinesApiLogic, ['data as mlInferencePipelinesData'], MappingsApiLogic, ['data as mappingData', 'status as mappingStatus'], - TrainedModelsApiLogic, - ['data as mlModelsData', 'status as mlModelsStatus'], FetchMlInferencePipelineProcessorsApiLogic, ['data as mlInferencePipelineProcessors'], FetchPipelineApiLogic, ['data as existingPipeline'], ], }, - events: {}, listeners: ({ values, actions }) => ({ attachPipeline: () => { const { @@ -340,11 +335,6 @@ export const MLInferenceLogic = kea< targetField: '', }); }, - setIndexName: ({ indexName }) => { - actions.makeMlInferencePipelinesRequest(undefined); - actions.makeMLModelsRequest(undefined); - actions.makeMappingRequest({ indexName }); - }, mlInferencePipelinesSuccess: (data) => { if ( (data?.length ?? 0) === 0 && @@ -359,7 +349,7 @@ export const MLInferenceLogic = kea< }, startTextExpansionModelSuccess: () => { // Refresh ML models list when the text expansion model is started - actions.makeMLModelsRequest(undefined); + actions.startPollingModels(); }, onAddInferencePipelineStepChange: ({ step }) => { const { @@ -377,12 +367,12 @@ export const MLInferenceLogic = kea< // back to the Configuration step if we find a pipeline with the same name // Re-fetch ML model list to include those that were deployed in this step - actions.makeMLModelsRequest(undefined); + actions.startPollingModels(); } actions.setAddInferencePipelineStep(step); }, fetchPipelineSuccess: () => { - // We found a pipeline with the name go back to configuration step + // We found a pipeline with the name, go back to configuration step actions.setAddInferencePipelineStep(AddInferencePipelineSteps.Configuration); }, }), @@ -509,30 +499,28 @@ export const MLInferenceLogic = kea< }, ], isLoading: [ - () => [selectors.mlModelsStatus, selectors.mappingStatus], - (mlModelsStatus, mappingStatus) => - !API_REQUEST_COMPLETE_STATUSES.includes(mlModelsStatus) || - !API_REQUEST_COMPLETE_STATUSES.includes(mappingStatus), + () => [selectors.mappingStatus], + (mappingStatus: Status) => !API_REQUEST_COMPLETE_STATUSES.includes(mappingStatus), ], isPipelineDataValid: [ () => [selectors.formErrors], (errors: AddInferencePipelineFormErrors) => Object.keys(errors).length === 0, ], isTextExpansionModelSelected: [ - () => [selectors.selectedMLModel], - (model: TrainedModel | null) => !!model?.inference_config?.text_expansion, + () => [selectors.selectedModel], + (model: MlModel | null) => model?.type === 'text_expansion', ], mlInferencePipeline: [ () => [ selectors.isPipelineDataValid, selectors.addInferencePipelineModal, - selectors.mlModelsData, + selectors.modelsData, selectors.mlInferencePipelinesData, ], ( isPipelineDataValid: MLInferenceProcessorsValues['isPipelineDataValid'], { configuration }: MLInferenceProcessorsValues['addInferencePipelineModal'], - models: MLInferenceProcessorsValues['mlModelsData'], + models: MLInferenceProcessorsValues['modelsData'], mlInferencePipelinesData: MLInferenceProcessorsValues['mlInferencePipelinesData'] ) => { if (configuration.existingPipeline) { @@ -546,7 +534,7 @@ export const MLInferenceLogic = kea< return pipeline as MlInferencePipeline; } if (!isPipelineDataValid) return undefined; - const model = models?.find((mlModel) => mlModel.model_id === configuration.modelID); + const model = models?.find((mlModel) => mlModel.modelId === configuration.modelID); if (!model) return undefined; return generateMlInferencePipelineBody({ @@ -581,23 +569,28 @@ export const MLInferenceLogic = kea< .sort(sortSourceFields); }, ], - supportedMLModels: [ - () => [selectors.mlModelsData], - (mlModelsData: MLInferenceProcessorsValues['mlModelsData']) => { - return (mlModelsData?.filter(isSupportedMLModel) ?? []).sort(sortModels); - }, + selectableModels: [ + () => [selectors.modelsData], + (response: FetchModelsApiResponse) => response ?? [], + ], + selectedModel: [ + () => [selectors.selectableModels, selectors.addInferencePipelineModal], + ( + models: MlModel[], + addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal'] + ) => models.find((m) => m.modelId === addInferencePipelineModal.configuration.modelID), ], existingInferencePipelines: [ () => [ selectors.mlInferencePipelinesData, selectors.sourceFields, - selectors.supportedMLModels, + selectors.selectableModels, selectors.mlInferencePipelineProcessors, ], ( mlInferencePipelinesData: MLInferenceProcessorsValues['mlInferencePipelinesData'], indexFields: MLInferenceProcessorsValues['sourceFields'], - supportedMLModels: MLInferenceProcessorsValues['supportedMLModels'], + selectableModels: MLInferenceProcessorsValues['selectableModels'], mlInferencePipelineProcessors: MLInferenceProcessorsValues['mlInferencePipelineProcessors'] ) => { if (!mlInferencePipelinesData) { @@ -619,8 +612,8 @@ export const MLInferenceLogic = kea< const sourceFields = fieldMappings?.map((m) => m.sourceField) ?? []; const missingSourceFields = sourceFields.filter((f) => !indexFields?.includes(f)) ?? []; - const mlModel = supportedMLModels.find((model) => model.model_id === modelId); - const modelType = mlModel ? getMLType(getMlModelTypesForModelConfig(mlModel)) : ''; + const mlModel = selectableModels.find((model) => model.modelId === modelId); + const modelType = mlModel ? getMLType(mlModel.types) : ''; const disabledReason = missingSourceFields.length > 0 ? EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS(missingSourceFields.join(', ')) @@ -641,18 +634,5 @@ export const MLInferenceLogic = kea< return existingPipelines; }, ], - selectedMLModel: [ - () => [selectors.supportedMLModels, selectors.addInferencePipelineModal], - ( - supportedMLModels: MLInferenceProcessorsValues['supportedMLModels'], - addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal'] - ) => { - return ( - supportedMLModels.find( - (model) => model.model_id === addInferencePipelineModal.configuration.modelID - ) ?? null - ); - }, - ], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx index c8a970751643a..b08b4697e6cfc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx @@ -52,6 +52,9 @@ const DEFAULT_MODEL: MlModel = { threadsPerAllocation: 0, isPlaceholder: false, hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', }; const MOCK_ACTIONS = { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts index b0c26aaf8be8c..8af7d59a1ceec 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts @@ -8,7 +8,7 @@ import { LogicMounter } from '../../../../../__mocks__/kea_logic'; import { HttpError } from '../../../../../../../common/types/api'; -import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml'; +import { MlModelDeploymentState } from '../../../../../../../common/types/ml'; import { CachedFetchModelsApiLogic } from '../../../../api/ml_models/cached_fetch_models_api_logic'; import { CreateModelApiLogic, @@ -22,31 +22,15 @@ const CREATE_MODEL_API_RESPONSE: CreateModelResponse = { modelId: 'model_1', deploymentState: MlModelDeploymentState.NotDeployed, }; -const FETCH_MODELS_API_DATA_RESPONSE: MlModel[] = [ - { - modelId: 'model_1', - title: 'Model 1', - type: 'ner', - deploymentState: MlModelDeploymentState.NotDeployed, - startTime: 0, - targetAllocationCount: 0, - nodeAllocationCount: 0, - threadsPerAllocation: 0, - isPlaceholder: false, - hasStats: false, - }, -]; describe('ModelSelectLogic', () => { const { mount } = new LogicMounter(ModelSelectLogic); const { mount: mountCreateModelApiLogic } = new LogicMounter(CreateModelApiLogic); - const { mount: mountCachedFetchModelsApiLogic } = new LogicMounter(CachedFetchModelsApiLogic); const { mount: mountStartModelApiLogic } = new LogicMounter(StartModelApiLogic); beforeEach(() => { jest.clearAllMocks(); mountCreateModelApiLogic(); - mountCachedFetchModelsApiLogic(); mountStartModelApiLogic(); mount(); }); @@ -82,16 +66,6 @@ describe('ModelSelectLogic', () => { }); }); - describe('fetchModels', () => { - it('makes fetch models request', () => { - jest.spyOn(ModelSelectLogic.actions, 'fetchModelsMakeRequest'); - - ModelSelectLogic.actions.fetchModels(); - - expect(ModelSelectLogic.actions.fetchModelsMakeRequest).toHaveBeenCalled(); - }); - }); - describe('startModel', () => { it('makes start model request', () => { const modelId = 'model_1'; @@ -150,14 +124,6 @@ describe('ModelSelectLogic', () => { }); }); - describe('selectableModels', () => { - it('gets models data from API response', () => { - CachedFetchModelsApiLogic.actions.apiSuccess(FETCH_MODELS_API_DATA_RESPONSE); - - expect(ModelSelectLogic.values.selectableModels).toEqual(FETCH_MODELS_API_DATA_RESPONSE); - }); - }); - describe('isLoading', () => { it('is set to true if the fetch API is loading the first time', () => { CachedFetchModelsApiLogic.actions.apiReset(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts index 4074ffac92f6b..09fd2e0ae8f54 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts @@ -10,15 +10,10 @@ import { kea, MakeLogicType } from 'kea'; import { HttpError, Status } from '../../../../../../../common/types/api'; import { MlModel } from '../../../../../../../common/types/ml'; import { getErrorsFromHttpResponse } from '../../../../../shared/flash_messages/handle_api_errors'; -import { - CachedFetchModelsApiLogic, - CachedFetchModlesApiLogicActions, -} from '../../../../api/ml_models/cached_fetch_models_api_logic'; import { CreateModelApiLogic, CreateModelApiLogicActions, } from '../../../../api/ml_models/create_model_api_logic'; -import { FetchModelsApiResponse } from '../../../../api/ml_models/fetch_models_api_logic'; import { StartModelApiLogic, StartModelApiLogicActions, @@ -37,17 +32,13 @@ export interface ModelSelectActions { createModelError: CreateModelApiLogicActions['apiError']; createModelMakeRequest: CreateModelApiLogicActions['makeRequest']; createModelSuccess: CreateModelApiLogicActions['apiSuccess']; - fetchModels: () => void; - fetchModelsError: CachedFetchModlesApiLogicActions['apiError']; - fetchModelsMakeRequest: CachedFetchModlesApiLogicActions['makeRequest']; - fetchModelsSuccess: CachedFetchModlesApiLogicActions['apiSuccess']; setInferencePipelineConfiguration: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; setInferencePipelineConfigurationFromMLInferenceLogic: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; startModel: (modelId: string) => { modelId: string }; startModelError: CreateModelApiLogicActions['apiError']; startModelMakeRequest: StartModelApiLogicActions['makeRequest']; startModelSuccess: StartModelApiLogicActions['apiSuccess']; - startPollingModels: CachedFetchModlesApiLogicActions['startPolling']; + startPollingModels: MLInferenceProcessorsActions['startPollingModels']; } export interface ModelSelectValues { @@ -59,12 +50,12 @@ export interface ModelSelectValues { ingestionMethod: string; ingestionMethodFromIndexViewLogic: string; isLoading: boolean; - isInitialLoading: boolean; + isModelsInitialLoadingFromMLInferenceLogic: boolean; modelStateChangeError: string | undefined; - modelsData: FetchModelsApiResponse | undefined; - modelsStatus: Status; selectableModels: MlModel[]; + selectableModelsFromMLInferenceLogic: MlModel[]; selectedModel: MlModel | undefined; + selectedModelFromMLInferenceLogic: MlModel | undefined; startModelError: HttpError | undefined; startModelStatus: Status; } @@ -72,19 +63,11 @@ export interface ModelSelectValues { export const ModelSelectLogic = kea>({ actions: { createModel: (modelId: string) => ({ modelId }), - fetchModels: true, setInferencePipelineConfiguration: (configuration) => ({ configuration }), startModel: (modelId: string) => ({ modelId }), }, connect: { actions: [ - CachedFetchModelsApiLogic, - [ - 'makeRequest as fetchModelsMakeRequest', - 'apiSuccess as fetchModelsSuccess', - 'apiError as fetchModelsError', - 'startPolling as startPollingModels', - ], CreateModelApiLogic, [ 'makeRequest as createModelMakeRequest', @@ -93,8 +76,9 @@ export const ModelSelectLogic = kea ({ - afterMount: () => { - actions.startPollingModels(); - }, - }), listeners: ({ actions }) => ({ createModel: ({ modelId }) => { actions.createModelMakeRequest({ modelId }); @@ -130,9 +112,6 @@ export const ModelSelectLogic = kea { - actions.fetchModelsMakeRequest({}); - }, setInferencePipelineConfiguration: ({ configuration }) => { actions.setInferencePipelineConfigurationFromMLInferenceLogic(configuration); }, @@ -167,16 +146,16 @@ export const ModelSelectLogic = kea [selectors.modelsData], - (response: FetchModelsApiResponse) => response ?? [], + () => [selectors.selectableModelsFromMLInferenceLogic], + (selectableModels) => selectableModels, // Pass-through ], selectedModel: [ - () => [selectors.selectableModels, selectors.addInferencePipelineModal], - ( - models: MlModel[], - addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal'] - ) => models.find((m) => m.modelId === addInferencePipelineModal.configuration.modelID), + () => [selectors.selectedModelFromMLInferenceLogic], + (selectedModel) => selectedModel, // Pass-through + ], + isLoading: [ + () => [selectors.isModelsInitialLoadingFromMLInferenceLogic], + (isModelsInitialLoading) => isModelsInitialLoading, // Pass-through ], - isLoading: [() => [selectors.isInitialLoading], (isInitialLoading) => isInitialLoading], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx index bcf4eb8342db1..6c4f1f4bbabb8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx @@ -34,6 +34,9 @@ const DEFAULT_PROPS: EuiSelectableOption = { threadsPerAllocation: 0, isPlaceholder: false, hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', }; describe('ModelSelectOption', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/no_models.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/no_models.tsx deleted file mode 100644 index 4670b00e93927..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/no_models.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { EuiEmptyPrompt, EuiImage, EuiLink, EuiText, useEuiTheme } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import noMlModelsGraphicDark from '../../../../../../assets/images/no_ml_models_dark.svg'; -import noMlModelsGraphicLight from '../../../../../../assets/images/no_ml_models_light.svg'; - -import { docLinks } from '../../../../../shared/doc_links'; - -export const NoModelsPanel: React.FC = () => { - const { colorMode } = useEuiTheme(); - - return ( - - - -

- - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.esDocs.link', - { defaultMessage: 'Learn how to add a trained model' } - )} - - ), - }} - /> -

-
- - } - /> - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.test.ts index 4ddf5b1c4b77a..1e4eb17744517 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.test.ts @@ -4,89 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { nerModel, textClassificationModel } from '../../../__mocks__/ml_models.mock'; -import { TrainedModelConfigResponse } from '@kbn/ml-plugin/common/types/trained_models'; - -import { - getMLType, - getModelDisplayTitle, - isSupportedMLModel, - sortSourceFields, - NLP_CONFIG_KEYS, -} from './utils'; +import { getMLType, getModelDisplayTitle, sortSourceFields, NLP_CONFIG_KEYS } from './utils'; describe('ml inference utils', () => { - describe('isSupportedMLModel', () => { - const makeFakeModel = ( - config: Partial - ): TrainedModelConfigResponse => { - const { inference_config: _throwAway, ...base } = nerModel; - return { - inference_config: {}, - ...base, - ...config, - }; - }; - it('returns true for expected models', () => { - const models: TrainedModelConfigResponse[] = [ - nerModel, - textClassificationModel, - makeFakeModel({ - inference_config: { - text_embedding: {}, - }, - model_id: 'mock-text_embedding', - }), - makeFakeModel({ - inference_config: { - zero_shot_classification: { - classification_labels: [], - }, - }, - model_id: 'mock-zero_shot_classification', - }), - makeFakeModel({ - inference_config: { - question_answering: {}, - }, - model_id: 'mock-question_answering', - }), - makeFakeModel({ - inference_config: { - fill_mask: {}, - }, - model_id: 'mock-fill_mask', - }), - makeFakeModel({ - inference_config: { - classification: {}, - }, - model_id: 'lang_ident_model_1', - model_type: 'lang_ident', - }), - ]; - - for (const model of models) { - expect(isSupportedMLModel(model)).toBe(true); - } - }); - - it('returns false for unexpected models', () => { - const models: TrainedModelConfigResponse[] = [ - makeFakeModel({}), - makeFakeModel({ - inference_config: { - fakething: {}, - }, - }), - ]; - - for (const model of models) { - expect(isSupportedMLModel(model)).toBe(false); - } - }); - }); describe('sortSourceFields', () => { it('promotes fields', () => { let fields: string[] = ['id', 'body', 'url']; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.ts index 3d97f52c659c1..88d273fcef135 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/ml_inference/utils.ts @@ -6,12 +6,9 @@ */ import { i18n } from '@kbn/i18n'; -import { TrainedModelConfigResponse } from '@kbn/ml-plugin/common/types/trained_models'; import { TRAINED_MODEL_TYPE, SUPPORTED_PYTORCH_TASKS } from '@kbn/ml-trained-models-utils'; -import { TrainedModel } from '../../../api/ml_models/ml_trained_models_logic'; - export const NLP_CONFIG_KEYS: string[] = Object.values(SUPPORTED_PYTORCH_TASKS); export const RECOMMENDED_FIELDS = ['body', 'body_content', 'title']; @@ -51,13 +48,6 @@ export const NLP_DISPLAY_TITLES: Record = { ), }; -export const isSupportedMLModel = (model: TrainedModelConfigResponse): boolean => { - return ( - Object.keys(model.inference_config || {}).some((key) => NLP_CONFIG_KEYS.includes(key)) || - model.model_type === TRAINED_MODEL_TYPE.LANG_IDENT - ); -}; - export const sortSourceFields = (a: string, b: string): number => { const promoteA = RECOMMENDED_FIELDS.includes(a); const promoteB = RECOMMENDED_FIELDS.includes(b); @@ -82,16 +72,3 @@ export const getMLType = (modelTypes: string[]): string => { }; export const getModelDisplayTitle = (type: string): string | undefined => NLP_DISPLAY_TITLES[type]; - -export const isTextExpansionModel = (model: TrainedModel): boolean => - Boolean(model.inference_config?.text_expansion); - -/** - * Sort function for displaying a list of models. Promotes text_expansion models and sorts the rest by model ID. - */ -export const sortModels = (m1: TrainedModel, m2: TrainedModel) => - isTextExpansionModel(m1) - ? -1 - : isTextExpansionModel(m2) - ? 1 - : m1.model_id.localeCompare(m2.model_id); diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts index bd02af095fe04..b96bfe6de8e7f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.test.ts @@ -72,12 +72,18 @@ describe('fetchMlModels', () => { inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: 'model_1', inference_config: { text_classification: {}, }, + input: { + fields: ['text_field'], + }, }, ], }; @@ -160,24 +166,36 @@ describe('fetchMlModels', () => { inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: E5_LINUX_OPTIMIZED_MODEL_ID, inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: ELSER_MODEL_ID, inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: ELSER_LINUX_OPTIMIZED_MODEL_ID, inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, ], }; @@ -210,24 +228,36 @@ describe('fetchMlModels', () => { inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: E5_LINUX_OPTIMIZED_MODEL_ID, inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: ELSER_MODEL_ID, inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: ELSER_LINUX_OPTIMIZED_MODEL_ID, inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, ], }; @@ -265,18 +295,27 @@ describe('fetchMlModels', () => { inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: E5_MODEL_ID, inference_config: { text_embedding: {}, }, + input: { + fields: ['text_field'], + }, }, { model_id: 'model_1', inference_config: { ner: {}, }, + input: { + fields: ['text_field'], + }, }, ], }; @@ -337,6 +376,9 @@ describe('fetchMlModels', () => { inference_config: { text_expansion: {}, }, + input: { + fields: ['text_field'], + }, }, ], }; @@ -385,18 +427,27 @@ describe('fetchMlModels', () => { inference_config: { ner: {}, // "Named Entity Recognition" }, + input: { + fields: ['text_field'], + }, }, { model_id: 'model_2', inference_config: { text_embedding: {}, // "Dense Vector Text Embedding" }, + input: { + fields: ['text_field'], + }, }, { model_id: 'model_3', inference_config: { text_classification: {}, // "Text Classification" }, + input: { + fields: ['text_field'], + }, }, ], }; diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.ts b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.ts index c1af4ab69c0bc..c39b6ec146ea1 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/fetch_ml_models.ts @@ -6,9 +6,12 @@ */ import { MlTrainedModelConfig, MlTrainedModelStats } from '@elastic/elasticsearch/lib/api/types'; + import { i18n } from '@kbn/i18n'; import { MlTrainedModels } from '@kbn/ml-plugin/server'; +import { getMlModelTypesForModelConfig } from '../../../common/ml_inference_pipeline'; + import { MlModelDeploymentState, MlModel } from '../../../common/types/ml'; import { @@ -109,39 +112,39 @@ export const fetchCompatiblePromotedModelIds = async (trainedModelsProvider: MlT }; const getModel = (modelConfig: MlTrainedModelConfig, modelStats?: MlTrainedModelStats): MlModel => { - { - const modelId = modelConfig.model_id; - const type = modelConfig.inference_config ? Object.keys(modelConfig.inference_config)[0] : ''; - const model = { - ...BASE_MODEL, - modelId, - type, - title: getUserFriendlyTitle(modelId, type), - isPromoted: [ - ELSER_MODEL_ID, - ELSER_LINUX_OPTIMIZED_MODEL_ID, - E5_MODEL_ID, - E5_LINUX_OPTIMIZED_MODEL_ID, - ].includes(modelId), - }; - - // Enrich deployment stats - if (modelStats && modelStats.deployment_stats) { - model.hasStats = true; - model.deploymentState = getDeploymentState( - modelStats.deployment_stats.allocation_status.state - ); - model.nodeAllocationCount = modelStats.deployment_stats.allocation_status.allocation_count; - model.targetAllocationCount = - modelStats.deployment_stats.allocation_status.target_allocation_count; - model.threadsPerAllocation = modelStats.deployment_stats.threads_per_allocation; - model.startTime = modelStats.deployment_stats.start_time; - } else if (model.modelId === LANG_IDENT_MODEL_ID) { - model.deploymentState = MlModelDeploymentState.FullyAllocated; - } - - return model; + const modelId = modelConfig.model_id; + const type = modelConfig.inference_config ? Object.keys(modelConfig.inference_config)[0] : ''; + const model = { + ...BASE_MODEL, + modelId, + type, + title: getUserFriendlyTitle(modelId, type), + description: modelConfig.description, + types: getMlModelTypesForModelConfig(modelConfig), + inputFieldNames: modelConfig.input.field_names, + version: modelConfig.version, + isPromoted: [ + ELSER_MODEL_ID, + ELSER_LINUX_OPTIMIZED_MODEL_ID, + E5_MODEL_ID, + E5_LINUX_OPTIMIZED_MODEL_ID, + ].includes(modelId), + }; + + // Enrich deployment stats + if (modelStats && modelStats.deployment_stats) { + model.hasStats = true; + model.deploymentState = getDeploymentState(modelStats.deployment_stats.allocation_status.state); + model.nodeAllocationCount = modelStats.deployment_stats.allocation_status.allocation_count; + model.targetAllocationCount = + modelStats.deployment_stats.allocation_status.target_allocation_count; + model.threadsPerAllocation = modelStats.deployment_stats.threads_per_allocation; + model.startTime = modelStats.deployment_stats.start_time; + } else if (model.modelId === LANG_IDENT_MODEL_ID) { + model.deploymentState = MlModelDeploymentState.FullyAllocated; } + + return model; }; const enrichModelWithDownloadStatus = async ( diff --git a/x-pack/plugins/enterprise_search/server/lib/ml/utils.ts b/x-pack/plugins/enterprise_search/server/lib/ml/utils.ts index 19a43059d3a08..d063fd158385a 100644 --- a/x-pack/plugins/enterprise_search/server/lib/ml/utils.ts +++ b/x-pack/plugins/enterprise_search/server/lib/ml/utils.ts @@ -60,6 +60,8 @@ export const BASE_MODEL = { threadsPerAllocation: 0, isPlaceholder: false, hasStats: false, + types: [], + inputFieldNames: [], }; export const ELSER_MODEL_PLACEHOLDER: MlModel = { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index a9b62b8622cdc..da642ec3e02ff 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -12766,7 +12766,6 @@ "xpack.enterpriseSearch.content.indices.connectorScheduling.page.description": "Votre connecteur est désormais déployé. Vous pouvez planifier du contenu récurrent et accéder aux synchronisations de contrôle ici. Si vous souhaitez exécuter un test rapide, lancez une synchronisation unique à l’aide du bouton {sync}.", "xpack.enterpriseSearch.content.indices.connectorScheduling.schedulePanel.documentLevelSecurity.dlsDisabledCallout.text": "{link} pour ce connecteur afin d'activer ces options.", "xpack.enterpriseSearch.content.indices.deleteIndex.successToast.title": "Votre index {indexName} et toute configuration d'ingestion associée ont été supprimés avec succès", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.description": "Aucun de vos modèles entraînés de Machine Learning ne peut être utilisé par un pipeline d'inférence. {documentationLink}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.missingSourceFieldsDescription": "Champs manquants dans cet index : {commaSeparatedMissingSourceFields}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.name.helpText": "Les noms de pipeline sont uniques dans un déploiement, et ils peuvent uniquement contenir des lettres, des chiffres, des traits de soulignement et des traits d'union. Cela créera un pipeline nommé {pipelineName}.", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.fields.descriptionReview": "Vérifiez les mappings des champs du pipeline que vous avez choisi afin de vous assurer que les champs source et cible correspondent à votre cas d'utilisation spécifique. {notEditable}", @@ -14190,8 +14189,6 @@ "xpack.enterpriseSearch.content.indices.extractionRules.editRule.url.urlFiltersLink": "En savoir plus sur les filtres d'URL", "xpack.enterpriseSearch.content.indices.extractionRules.editRule.urlLabel": "URL", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.createErrors": "Erreur lors de la création d'un pipeline", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.esDocs.link": "Découvrir comment ajouter un modèle entraîné", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.imageAlt": "Illustration d'absence de modèles de Machine Learning", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.description": "Créez ou réutilisez un pipeline enfant qui servira de processeur dans votre pipeline principal.", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "Champ obligatoire.", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipelineLabel": "Sélectionner un pipeline d'inférence existant", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 77335897bd208..a754e68664876 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12779,7 +12779,6 @@ "xpack.enterpriseSearch.content.indices.connectorScheduling.page.description": "コネクターがデプロイされました。ここで、繰り返しコンテンツとアクセス制御同期をスケジュールします。簡易テストを実行する場合は、{sync}ボタンを使用してワンタイム同期を実行します。", "xpack.enterpriseSearch.content.indices.connectorScheduling.schedulePanel.documentLevelSecurity.dlsDisabledCallout.text": "これらのオプションを有効にするには、このコネクターの{link}。", "xpack.enterpriseSearch.content.indices.deleteIndex.successToast.title": "インデックス{indexName}と関連付けられたすべての統合構成が正常に削除されました", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.description": "推論パイプラインで使用できる学習済み機械学習モデルがありません。{documentationLink}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.missingSourceFieldsDescription": "このインデックスで欠落しているフィールド:{commaSeparatedMissingSourceFields}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.name.helpText": "パイプライン名はデプロイ内で一意であり、文字、数字、アンダースコア、ハイフンのみを使用できます。これにより、{pipelineName}という名前のパイプラインが作成されます。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.fields.descriptionReview": "選択したパイプラインのフィールドマッピングを調べ、ソースフィールドとターゲットフィールドが特定のユースケースに適合していることを確認します。{notEditable}", @@ -14203,8 +14202,6 @@ "xpack.enterpriseSearch.content.indices.extractionRules.editRule.url.urlFiltersLink": "URLフィルターの詳細をご覧ください", "xpack.enterpriseSearch.content.indices.extractionRules.editRule.urlLabel": "URL", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.createErrors": "パイプラインの作成エラー", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.esDocs.link": "学習されたモデルの追加方法の詳細", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.imageAlt": "機械学習モデル例がありません", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.description": "メインパイプラインでプロセッサーとして使用される子パイプラインを作成または再利用します。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "フィールドが必要です。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipelineLabel": "既存の推論パイプラインを選択", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 70fe8f8c91298..ab8c10ed3ed97 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12873,7 +12873,6 @@ "xpack.enterpriseSearch.content.indices.connectorScheduling.page.description": "现已部署您的连接器。在此处计划重复内容和访问控制同步。如果要运行快速测试,请使用 {sync} 按钮启动一次性同步。", "xpack.enterpriseSearch.content.indices.connectorScheduling.schedulePanel.documentLevelSecurity.dlsDisabledCallout.text": "此连接器的 {link},用于激活这些选项。", "xpack.enterpriseSearch.content.indices.deleteIndex.successToast.title": "您的索引 {indexName} 和任何关联的采集配置已成功删除", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.description": "您没有可供推理管道使用的已训练 Machine Learning 模型。{documentationLink}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.missingSourceFieldsDescription": "此索引中缺少字段:{commaSeparatedMissingSourceFields}", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.name.helpText": "管道名称在部署内唯一,并且只能包含字母、数字、下划线和连字符。这会创建名为 {pipelineName} 的管道。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.fields.descriptionReview": "检查您选择的管道的字段映射,确保源和目标字段符合您的特定用例。{notEditable}", @@ -14297,8 +14296,6 @@ "xpack.enterpriseSearch.content.indices.extractionRules.editRule.url.urlFiltersLink": "详细了解 URL 筛选", "xpack.enterpriseSearch.content.indices.extractionRules.editRule.urlLabel": "URL", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.createErrors": "创建管道时出错", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.esDocs.link": "了解如何添加已训练模型", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.noModels.imageAlt": "无 Machine Learning 模型图示", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.description": "构建或重复使用将在您的主管道中用作处理器的子管道。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "“字段”必填。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipelineLabel": "选择现有推理管道", From cb5cf0ebc9b274c40795ea4859af36d9f0dd2db8 Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Thu, 8 Feb 2024 13:58:01 -0800 Subject: [PATCH 051/104] Upgrade EUI to v93.0.0 (#176246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `v92.2.1` ⏩ `v93.0.0` --- ## [`v93.0.0`](https://github.com/elastic/eui/releases/v93.0.0) **Bug fixes** - Fixed `EuiTextTruncate` component to clean up timer from side effect on unmount ([#7495](https://github.com/elastic/eui/pull/7495)) **Breaking changes** - Removed deprecated `anchorClassName` prop from `EuiPopover`. Use `className` instead ([#7488](https://github.com/elastic/eui/pull/7488)) - Removed deprecated `buttonRef` prop from `EuiPopover`. Use `popoverRef` instead ([#7488](https://github.com/elastic/eui/pull/7488)) - Removed deprecated `toolTipTitle` and `toolTipPosition` props from `EuiContextMenuItem`. Use `toolTipProps.title` and `toolTipProps.position` instead ([#7489](https://github.com/elastic/eui/pull/7489)) - Removed deprecated internal `setSelection` ref method from `EuiInMemoryTable` and `EuiBasicTable`. Use the new controlled `selection.selected` prop API instead. ([#7491](https://github.com/elastic/eui/pull/7491)) - `EuiTourStep`'s `className` and `style` props now apply to the anchoring element instead of to the popover panel, to match `EuiPopover` behavior. ([#7497](https://github.com/elastic/eui/pull/7497)) - Convert your existing usages to `panelClassName` and `panelStyle` respectively instead. **Performance** - Improved the amount of recomputed styles being generated by `EuiCode` and `EuiCodeBlock` ([#7486](https://github.com/elastic/eui/pull/7486)) **CSS-in-JS conversions** - Converted `EuiSearchBar` to Emotion ([#7490](https://github.com/elastic/eui/pull/7490)) - Converted `EuiEmptyPrompt` to Emotion ([#7494](https://github.com/elastic/eui/pull/7494)) - Added `euiBorderColor` and `useEuiBorderColorCSS` style utilities ([#7494](https://github.com/elastic/eui/pull/7494)) --------- Co-authored-by: Jon --- package.json | 2 +- .../__snapshots__/i18n_service.test.tsx.snap | 6 +- .../src/i18n_eui_mapping.tsx | 6 +- src/dev/license_checker/config.ts | 2 +- .../dashboard_empty_screen.test.tsx.snap | 264 ++++++++---------- .../__snapshots__/data_view.test.tsx.snap | 34 +-- .../discover_tour/discover_tour_provider.tsx | 6 +- .../visualization_noresults.test.js.snap | 18 +- .../public/components/search_bar.tsx | 2 +- .../__snapshots__/policy_table.test.tsx.snap | 70 +++-- .../__snapshots__/no_data.test.js.snap | 220 +++++++-------- .../__snapshots__/page_loading.test.js.snap | 16 +- .../roles_grid_page.test.tsx.snap | 38 ++- .../__snapshots__/prompt_page.test.tsx.snap | 4 +- .../unauthenticated_page.test.tsx.snap | 4 +- .../reset_session_page.test.tsx.snap | 4 +- .../landing_page/onboarding/toggle_panel.tsx | 2 +- .../translations/translations/fr-FR.json | 6 +- .../translations/translations/ja-JP.json | 6 +- .../translations/translations/zh-CN.json | 6 +- yarn.lock | 8 +- 21 files changed, 340 insertions(+), 384 deletions(-) diff --git a/package.json b/package.json index 4676515b4f889..05b09aa56196c 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.9.1-canary.1", "@elastic/ems-client": "8.5.1", - "@elastic/eui": "92.2.1", + "@elastic/eui": "93.0.0", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", diff --git a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap index 78bb5d5d7ea71..50b4b74b0f3e5 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap +++ b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap @@ -376,9 +376,9 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiToast.dismissToast": "Dismiss toast", "euiToast.newNotification": "A new notification appears", "euiToast.notification": "Notification", - "euiTourStep.closeTour": "Close tour", - "euiTourStep.endTour": "End tour", - "euiTourStep.skipTour": "Skip tour", + "euiTourFooter.closeTour": "Close tour", + "euiTourFooter.endTour": "End tour", + "euiTourFooter.skipTour": "Skip tour", "euiTourStepIndicator.ariaLabel": [Function], "euiTourStepIndicator.isActive": "active", "euiTourStepIndicator.isComplete": "complete", diff --git a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx index 8710a8640d747..a8c4db74ba406 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx +++ b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx @@ -1710,13 +1710,13 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Notification', description: 'ARIA label on an element containing a notification', }), - 'euiTourStep.endTour': i18n.translate('core.euiTourStep.endTour', { + 'euiTourFooter.endTour': i18n.translate('core.euiTourFooter.endTour', { defaultMessage: 'End tour', }), - 'euiTourStep.skipTour': i18n.translate('core.euiTourStep.skipTour', { + 'euiTourFooter.skipTour': i18n.translate('core.euiTourFooter.skipTour', { defaultMessage: 'Skip tour', }), - 'euiTourStep.closeTour': i18n.translate('core.euiTourStep.closeTour', { + 'euiTourFooter.closeTour': i18n.translate('core.euiTourFooter.closeTour', { defaultMessage: 'Close tour', }), 'euiTourStepIndicator.isActive': i18n.translate('core.euiTourStepIndicator.isActive', { diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 436fc25abf955..6b1be5c45934a 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -85,7 +85,7 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.5.1': ['Elastic License 2.0'], - '@elastic/eui@92.2.1': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@93.0.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry 'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary '@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause) diff --git a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/__snapshots__/dashboard_empty_screen.test.tsx.snap b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/__snapshots__/dashboard_empty_screen.test.tsx.snap index 6863540ad4a71..d478b18ef2ddb 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/__snapshots__/dashboard_empty_screen.test.tsx.snap +++ b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/__snapshots__/dashboard_empty_screen.test.tsx.snap @@ -20,13 +20,13 @@ exports[`DashboardEmptyScreen renders correctly with edit mode 1`] = ` class="emotion-euiPageSection__content-l-center" >
+

+ This dashboard is empty. Let’s fill it up! +

+
-

- This dashboard is empty. Let’s fill it up! -

-
-
- - Create a visualization of your data, or add one from the library. - -
+ + Create a visualization of your data, or add one from the library. +
+
+
+
-
-
- -
-
+ +
+
+ -
+ +
@@ -145,13 +141,13 @@ exports[`DashboardEmptyScreen renders correctly with readonly and edit mode 1`] class="emotion-euiPageSection__content-l-center" >
+

+ This dashboard is empty. +

+
-

- This dashboard is empty. -

-
-
- - You need additional privileges to edit this dashboard. - -
+ + You need additional privileges to edit this dashboard. +
@@ -219,13 +211,13 @@ exports[`DashboardEmptyScreen renders correctly with readonly mode 1`] = ` class="emotion-euiPageSection__content-l-center" >
+

+ This dashboard is empty. +

+
-

- This dashboard is empty. -

-
-
- - You need additional privileges to edit this dashboard. - -
+ + You need additional privileges to edit this dashboard. +
@@ -293,13 +281,13 @@ exports[`DashboardEmptyScreen renders correctly with view mode 1`] = ` class="emotion-euiPageSection__content-l-center" >
+

+ Add visualizations to your dashboard +

+
-

- Add visualizations to your dashboard -

-
-
- - Enter edit mode, and then start adding your visualizations. - -
+ + Enter edit mode, and then start adding your visualizations. +
-
- -
+ +
diff --git a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap index 8bd049df006fc..837cee1a78aff 100644 --- a/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/data/public/utils/table_inspector_view/components/__snapshots__/data_view.test.tsx.snap @@ -2,32 +2,28 @@ exports[`Inspector Data View component should render empty state 1`] = `
+

+ No data available +

+
-

- No data available -

-
-
-

- The element did not provide any data. -

-
+

+ The element did not provide any data. +

diff --git a/src/plugins/discover/public/components/discover_tour/discover_tour_provider.tsx b/src/plugins/discover/public/components/discover_tour/discover_tour_provider.tsx index 01aabdba43fc5..45a870fbc2806 100644 --- a/src/plugins/discover/public/components/discover_tour/discover_tour_provider.tsx +++ b/src/plugins/discover/public/components/discover_tour/discover_tour_provider.tsx @@ -295,7 +295,7 @@ export const DiscoverTourStepFooterAction: React.FC<{ onClick={onFinishTour} data-test-subj="discoverTourButtonSkip" > - {EuiI18n({ token: 'core.euiTourStep.skipTour', default: 'Skip tour' })} + {EuiI18n({ token: 'core.euiTourFooter.skipTour', default: 'Skip tour' })} )} @@ -306,7 +306,7 @@ export const DiscoverTourStepFooterAction: React.FC<{ onClick={onFinishTour} data-test-subj="discoverTourButtonEnd" > - {EuiI18n({ token: 'core.euiTourStep.endTour', default: 'End tour' })} + {EuiI18n({ token: 'core.euiTourFooter.endTour', default: 'End tour' })} ) : ( - {EuiI18n({ token: 'core.euiTourStep.nextStep', default: 'Next' })} + {EuiI18n({ token: 'core.euiTourFooter.nextStep', default: 'Next' })} )} diff --git a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap index fb9bdb537acf3..533cc7d1bba3f 100644 --- a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap +++ b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap @@ -6,14 +6,14 @@ exports[`VisualizationNoResults should render according to snapshot 1`] = ` data-test-subj="visNoResult" >
-
- No results found -
+ No results found
diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx index 821a6efad3491..991b7d6af6259 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx @@ -351,7 +351,7 @@ export const SearchBar: FC = (opts) => { 'data-test-subj': 'nav-search-popover', panelClassName: 'navSearch__panel', repositionOnScroll: true, - buttonRef: setButtonRef, + popoverRef: setButtonRef, panelStyle: { marginTop: '6px' }, }} popoverButton={ diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap index f9e7a78b3b44c..227f904ba7b57 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap +++ b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap @@ -44,13 +44,13 @@ exports[`policy table shows empty state when there are no policies 1`] = ` class="emotion-euiPageSection__content-l-center" >
+

+ Create your first index lifecycle policy +

+
-

- Create your first index lifecycle policy -

-
-
-

- An index lifecycle policy helps you manage your indices as they age. -

-
-
-
+
+ -
+ color="inherit" + data-euiicon-type="plusInCircle" + /> + Create policy + +
diff --git a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap index 500bcfdaaa3f2..2217c13f37ed2 100644 --- a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap @@ -21,91 +21,87 @@ exports[`NoData should show a default message if reason is unknown 1`] = ` class="emotion-euiPageSection__content-l-center" >
+

+ No monitoring data found +

+
-

- No monitoring data found -

-
-
-

- Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data. -

-

- If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. -

-
+

+ Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data. +

+

+ If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. +

+
+
+
-
-
- -
+ Set up monitoring with Metricbeat + +
-
- -
+ +
@@ -136,91 +132,87 @@ exports[`NoData should show text next to the spinner while checking a setting 1` class="emotion-euiPageSection__content-l-center" >
+

+ No monitoring data found +

+
-

- No monitoring data found -

-
-
-

- Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data. -

-

- If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. -

-
+

+ Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data. +

+

+ If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. +

+
+
+
-
-
- -
+ Set up monitoring with Metricbeat + +
-
- -
+ +
diff --git a/x-pack/plugins/monitoring/public/components/page_loading/__snapshots__/page_loading.test.js.snap b/x-pack/plugins/monitoring/public/components/page_loading/__snapshots__/page_loading.test.js.snap index e83555e1d5eb3..bfba0e77b29aa 100644 --- a/x-pack/plugins/monitoring/public/components/page_loading/__snapshots__/page_loading.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/page_loading/__snapshots__/page_loading.test.js.snap @@ -15,13 +15,13 @@ exports[`PageLoading should show a simple page loading component 1`] = ` class="emotion-euiPageSection__content-l-center" >
-
- Loading… -
+ Loading…
diff --git a/x-pack/plugins/security/public/management/roles/roles_grid/__snapshots__/roles_grid_page.test.tsx.snap b/x-pack/plugins/security/public/management/roles/roles_grid/__snapshots__/roles_grid_page.test.tsx.snap index f9de5da1a1467..fbf5c14bd351d 100644 --- a/x-pack/plugins/security/public/management/roles/roles_grid/__snapshots__/roles_grid_page.test.tsx.snap +++ b/x-pack/plugins/security/public/management/roles/roles_grid/__snapshots__/roles_grid_page.test.tsx.snap @@ -8,13 +8,13 @@ exports[` renders permission denied if required 1`] = ` class="emotion-euiPageSection__content-l-center" >
renders permission denied if required 1`] = ` />
+

+ You need permission to manage roles +

+
-

- You need permission to manage roles -

-
-
-

- Contact your system administrator. -

-
+ Contact your system administrator. +

diff --git a/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap b/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap index b6bb95e80744b..fe6552fa889af 100644 --- a/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap +++ b/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PromptPage renders as expected with additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; +exports[`PromptPage renders as expected with additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; -exports[`PromptPage renders as expected without additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; +exports[`PromptPage renders as expected without additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; diff --git a/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap b/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap index 8b78fb132c3f8..43f406782acc2 100644 --- a/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap +++ b/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`UnauthenticatedPage renders as expected 1`] = `"ElasticMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; +exports[`UnauthenticatedPage renders as expected 1`] = `"ElasticMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

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

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

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

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; diff --git a/x-pack/plugins/security/server/authorization/__snapshots__/reset_session_page.test.tsx.snap b/x-pack/plugins/security/server/authorization/__snapshots__/reset_session_page.test.tsx.snap index a2217e1acf40a..80155b3fde5ac 100644 --- a/x-pack/plugins/security/server/authorization/__snapshots__/reset_session_page.test.tsx.snap +++ b/x-pack/plugins/security/server/authorization/__snapshots__/reset_session_page.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ResetSessionPage renders as expected 1`] = `"ElasticMockedFonts

You do not have permission to access the requested page

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

"`; +exports[`ResetSessionPage renders as expected 1`] = `"ElasticMockedFonts

You do not have permission to access the requested page

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

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

You do not have permission to access the requested page

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

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

You do not have permission to access the requested page

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

"`; diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/toggle_panel.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/toggle_panel.tsx index 45b18d046a601..43a5ccfdef5a7 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/toggle_panel.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/onboarding/toggle_panel.tsx @@ -47,7 +47,7 @@ const TogglePanelComponent: React.FC<{ body={

{i18n.TOGGLE_PANEL_EMPTY_DESCRIPTION}

} css={css` padding: ${euiTheme.base * 5}px 0; - .euiEmptyPrompt__contentInner { + .euiEmptyPrompt__content { max-width: none; } `} diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index da642ec3e02ff..b35f69de50dbd 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -865,9 +865,9 @@ "core.euiToast.dismissToast": "Rejeter le toast", "core.euiToast.newNotification": "Une nouvelle notification apparaît.", "core.euiToast.notification": "Notification", - "core.euiTourStep.closeTour": "Fermer la visite", - "core.euiTourStep.endTour": "Terminer la visite", - "core.euiTourStep.skipTour": "Ignorer la visite", + "core.euiTourFooter.closeTour": "Fermer la visite", + "core.euiTourFooter.endTour": "Terminer la visite", + "core.euiTourFooter.skipTour": "Ignorer la visite", "core.euiTourStepIndicator.isActive": "active", "core.euiTourStepIndicator.isComplete": "terminée", "core.euiTourStepIndicator.isIncomplete": "incomplète", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a754e68664876..f1ad2adee7dd7 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -879,9 +879,9 @@ "core.euiToast.dismissToast": "トーストを閉じる", "core.euiToast.newNotification": "新しい通知が表示されます", "core.euiToast.notification": "通知", - "core.euiTourStep.closeTour": "ツアーを閉じる", - "core.euiTourStep.endTour": "ツアーを終了", - "core.euiTourStep.skipTour": "ツアーをスキップ", + "core.euiTourFooter.closeTour": "ツアーを閉じる", + "core.euiTourFooter.endTour": "ツアーを終了", + "core.euiTourFooter.skipTour": "ツアーをスキップ", "core.euiTourStepIndicator.isActive": "アクティブ", "core.euiTourStepIndicator.isComplete": "完了", "core.euiTourStepIndicator.isIncomplete": "未完了", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ab8c10ed3ed97..16c8656569620 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -879,9 +879,9 @@ "core.euiToast.dismissToast": "关闭 Toast", "core.euiToast.newNotification": "新通知出现", "core.euiToast.notification": "通知", - "core.euiTourStep.closeTour": "关闭教程", - "core.euiTourStep.endTour": "结束教程", - "core.euiTourStep.skipTour": "跳过教程", + "core.euiTourFooter.closeTour": "关闭教程", + "core.euiTourFooter.endTour": "结束教程", + "core.euiTourFooter.skipTour": "跳过教程", "core.euiTourStepIndicator.isActive": "活动", "core.euiTourStepIndicator.isComplete": "已完成", "core.euiTourStepIndicator.isIncomplete": "未完成", diff --git a/yarn.lock b/yarn.lock index 9764ec1d778d4..62b6925bfe980 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1739,10 +1739,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@92.2.1": - version "92.2.1" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-92.2.1.tgz#172b5122e1025307bbb8e2c6a115c3feb3a16f42" - integrity sha512-FujsbJtuh8mxG5mbqclQBdPoW1kn9kXd/hpaMXUJa7bb0bmqlJRmagULPTZ+5e60Q6PEQt+e7MFDsaq4elSthQ== +"@elastic/eui@93.0.0": + version "93.0.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-93.0.0.tgz#43ba256d94f3d3acddee23427c9fa5285a43d7e4" + integrity sha512-Q5gY9roWZsB1At0rxG5d9M5P7+J4hfv8fzvuqNHoVjIxbeibHRCSq2TtOQcSUjhKE5Tu/BIZijzuYX8vITGaSQ== dependencies: "@hello-pangea/dnd" "^16.3.0" "@types/lodash" "^4.14.198" From 77fe14e113867053a17ebbb69174de513ceae336 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Thu, 8 Feb 2024 15:20:54 -0700 Subject: [PATCH 052/104] [Obs] Fix bug a but with --ephemeral-project-ids and add metadata to Nginx Proxy logs (#176553) ## Summary This PR fixes a bug with the `--ephermal-project-ids` option. Instead of using now it should use the timestamp of the first event passed to it. This also adds `http.response.status_code` and `http.response.bytes` to the Nginx Proxy logs. --- .../fake_stack/message_processor/index.ts | 8 +++-- .../nginx_proxy/ecs/fields/subset.yml | 6 ++++ .../ecs/generated/beats/fields.ecs.yml | 20 ++++++++++++ .../nginx_proxy/ecs/generated/csv/fields.csv | 2 ++ .../ecs/generated/ecs/ecs_flat.yml | 22 +++++++++++++ .../ecs/generated/ecs/ecs_nested.yml | 32 +++++++++++++++++++ .../ecs/subset/nginx_proxy/ecs_flat.yml | 22 +++++++++++++ .../ecs/subset/nginx_proxy/ecs_nested.yml | 32 +++++++++++++++++++ .../composable/component/http.json | 26 +++++++++++++++ .../elasticsearch/composable/template.json | 1 + .../elasticsearch/legacy/template.json | 14 ++++++++ .../lib/events/create_nginx_log.ts | 1 + .../src/lib/add_ephemeral_project_id.ts | 3 +- 13 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/component/http.json diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/message_processor/index.ts b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/message_processor/index.ts index 346a7451a6364..3eb97560cad73 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/message_processor/index.ts +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/message_processor/index.ts @@ -12,6 +12,7 @@ import { badHost } from './lib/events/bad_host'; import { weightedSample } from '../common/weighted_sample'; import { Doc, GeneratorFunction, EventFunction, EventTemplate } from '../../../types'; +import { addEphemeralProjectId } from '../../../lib/add_ephemeral_project_id'; let firstRun = true; @@ -31,7 +32,7 @@ function getTemplate(name: string) { return GOOD_EVENT_TEMPLATES; } -export const generateEvent: GeneratorFunction = (_config, schedule, _index, timestamp) => { +export const generateEvent: GeneratorFunction = (config, schedule, _index, timestamp) => { let startupEvents: Doc[] = []; if (firstRun) { firstRun = false; @@ -40,7 +41,10 @@ export const generateEvent: GeneratorFunction = (_config, schedule, _index, time const template = getTemplate(schedule.template); const fn = weightedSample(template) as EventFunction; - const events = fn(schedule, timestamp).flat(); + const events = addEphemeralProjectId( + config.indexing.ephemeralProjectIds || 0, + fn(schedule, timestamp).flat() + ); return [...startupEvents, ...events]; }; diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/fields/subset.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/fields/subset.yml index dbc663c5949a1..87291dbb1a819 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/fields/subset.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/fields/subset.yml @@ -7,6 +7,12 @@ fields: fields: level: {} logger: {} + http: + fields: + response: + fields: + status_code: {} + bytes: {} host: fields: name: {} diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/beats/fields.ecs.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/beats/fields.ecs.yml index 9558edd94c2da..2dd03a644f0e4 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/beats/fields.ecs.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/beats/fields.ecs.yml @@ -72,6 +72,26 @@ It can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.' + - name: http + title: HTTP + group: 2 + description: Fields related to HTTP activity. Use the `url` field set to store + the url of the request. + type: group + default_field: true + fields: + - name: response.bytes + level: extended + type: long + format: bytes + description: Total size in bytes of the response (body and headers). + example: 1437 + - name: response.status_code + level: extended + type: long + format: string + description: HTTP response status code. + example: 404 - name: log title: Log group: 2 diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/csv/fields.csv b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/csv/fields.csv index e66fb987788df..4a8d0e8275426 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/csv/fields.csv +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/csv/fields.csv @@ -4,5 +4,7 @@ ECS_Version,Indexed,Field_Set,Field,Type,Level,Normalization,Example,Description 8.0.0,true,base,message,match_only_text,core,,Hello World,Log message optimized for viewing in a log viewer. 8.0.0,true,base,tags,keyword,core,array,"[""production"", ""env2""]",List of keywords used to tag each event. 8.0.0,true,host,host.name,keyword,core,,,Name of the host. +8.0.0,true,http,http.response.bytes,long,extended,,1437,Total size in bytes of the response (body and headers). +8.0.0,true,http,http.response.status_code,long,extended,,404,HTTP response status code. 8.0.0,true,log,log.level,keyword,core,,error,Log level of the log event. 8.0.0,true,log,log.logger,keyword,core,,org.elasticsearch.bootstrap.Bootstrap,Name of the logger. diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_flat.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_flat.yml index 3d22bd599c6ce..5fd84750e06d4 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_flat.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_flat.yml @@ -30,6 +30,28 @@ host.name: normalize: [] short: Name of the host. type: keyword +http.response.bytes: + dashed_name: http-response-bytes + description: Total size in bytes of the response (body and headers). + example: 1437 + flat_name: http.response.bytes + format: bytes + level: extended + name: response.bytes + normalize: [] + short: Total size in bytes of the response (body and headers). + type: long +http.response.status_code: + dashed_name: http-response-status-code + description: HTTP response status code. + example: 404 + flat_name: http.response.status_code + format: string + level: extended + name: response.status_code + normalize: [] + short: HTTP response status code. + type: long labels: dashed_name: labels description: 'Custom key/value pairs. diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_nested.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_nested.yml index 9066a8b73fcd7..b204a419a007d 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_nested.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/ecs_nested.yml @@ -109,6 +109,38 @@ host: short: Fields describing the relevant computing instance. title: Host type: group +http: + description: Fields related to HTTP activity. Use the `url` field set to store the + url of the request. + fields: + http.response.bytes: + dashed_name: http-response-bytes + description: Total size in bytes of the response (body and headers). + example: 1437 + flat_name: http.response.bytes + format: bytes + level: extended + name: response.bytes + normalize: [] + short: Total size in bytes of the response (body and headers). + type: long + http.response.status_code: + dashed_name: http-response-status-code + description: HTTP response status code. + example: 404 + flat_name: http.response.status_code + format: string + level: extended + name: response.status_code + normalize: [] + short: HTTP response status code. + type: long + group: 2 + name: http + prefix: http. + short: Fields describing an HTTP request. + title: HTTP + type: group log: description: 'Details about the event''s logging mechanism or logging transport. diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_flat.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_flat.yml index 3d22bd599c6ce..5fd84750e06d4 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_flat.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_flat.yml @@ -30,6 +30,28 @@ host.name: normalize: [] short: Name of the host. type: keyword +http.response.bytes: + dashed_name: http-response-bytes + description: Total size in bytes of the response (body and headers). + example: 1437 + flat_name: http.response.bytes + format: bytes + level: extended + name: response.bytes + normalize: [] + short: Total size in bytes of the response (body and headers). + type: long +http.response.status_code: + dashed_name: http-response-status-code + description: HTTP response status code. + example: 404 + flat_name: http.response.status_code + format: string + level: extended + name: response.status_code + normalize: [] + short: HTTP response status code. + type: long labels: dashed_name: labels description: 'Custom key/value pairs. diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_nested.yml b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_nested.yml index 9066a8b73fcd7..b204a419a007d 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_nested.yml +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/ecs/subset/nginx_proxy/ecs_nested.yml @@ -109,6 +109,38 @@ host: short: Fields describing the relevant computing instance. title: Host type: group +http: + description: Fields related to HTTP activity. Use the `url` field set to store the + url of the request. + fields: + http.response.bytes: + dashed_name: http-response-bytes + description: Total size in bytes of the response (body and headers). + example: 1437 + flat_name: http.response.bytes + format: bytes + level: extended + name: response.bytes + normalize: [] + short: Total size in bytes of the response (body and headers). + type: long + http.response.status_code: + dashed_name: http-response-status-code + description: HTTP response status code. + example: 404 + flat_name: http.response.status_code + format: string + level: extended + name: response.status_code + normalize: [] + short: HTTP response status code. + type: long + group: 2 + name: http + prefix: http. + short: Fields describing an HTTP request. + title: HTTP + type: group log: description: 'Details about the event''s logging mechanism or logging transport. diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/component/http.json b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/component/http.json new file mode 100644 index 0000000000000..819512388f79d --- /dev/null +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/component/http.json @@ -0,0 +1,26 @@ +{ + "_meta": { + "documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-http.html", + "ecs_version": "8.0.0" + }, + "template": { + "mappings": { + "properties": { + "http": { + "properties": { + "response": { + "properties": { + "bytes": { + "type": "long" + }, + "status_code": { + "type": "long" + } + } + } + } + } + } + } + } +} diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/template.json b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/template.json index 52c9d48879d1f..e598c3317a7b7 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/template.json +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/composable/template.json @@ -6,6 +6,7 @@ "composed_of": [ "ecs_8.0.0_base", "ecs_8.0.0_log", + "ecs_8.0.0_http", "ecs_8.0.0_host" ], "index_patterns": [ diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/legacy/template.json b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/legacy/template.json index 08a3534017b85..e8b04233d57e2 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/legacy/template.json +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/ecs/generated/elasticsearch/legacy/template.json @@ -36,6 +36,20 @@ } } }, + "http": { + "properties": { + "response": { + "properties": { + "bytes": { + "type": "long" + }, + "status_code": { + "type": "long" + } + } + } + } + }, "labels": { "type": "object" }, diff --git a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/lib/events/create_nginx_log.ts b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/lib/events/create_nginx_log.ts index b6af0163d4670..c202196370d09 100644 --- a/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/lib/events/create_nginx_log.ts +++ b/x-pack/packages/kbn-data-forge/src/data_sources/fake_stack/nginx_proxy/lib/events/create_nginx_log.ts @@ -37,6 +37,7 @@ export const createNginxLog = ( )} - ${userId} ${domain} to: ${hostWithPort}: "${method} ${path} HTTP/1.1" ${statusCode} ${bytes} "${url}" "${userAgent}"`, log: { level: 'INFO', logger: NGINX_PROXY }, host: { name: host }, + http: { response: { status_code: statusCode, bytes } }, }, ]; }; diff --git a/x-pack/packages/kbn-data-forge/src/lib/add_ephemeral_project_id.ts b/x-pack/packages/kbn-data-forge/src/lib/add_ephemeral_project_id.ts index 0ba789c5a50b0..4226c8da7cebc 100644 --- a/x-pack/packages/kbn-data-forge/src/lib/add_ephemeral_project_id.ts +++ b/x-pack/packages/kbn-data-forge/src/lib/add_ephemeral_project_id.ts @@ -6,6 +6,7 @@ */ import { random, times } from 'lodash'; +import moment from 'moment'; import { v4 } from 'uuid'; import { Doc } from '../types'; @@ -18,7 +19,7 @@ export function addEphemeralProjectId(totalProjectIds: number, events: Doc[]) { return events; } - const now = Date.now(); + const now = (events[0] && moment(events[0]['@timestamp']).valueOf()) || Date.now(); const workingIds = projectIds.filter(([_id, expirationDate]) => expirationDate > now); const numberOfIdsToCreate = totalProjectIds - workingIds.length; From 8e53ee3c7c136d42bc97d2835375cc98016c9cdf Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Thu, 8 Feb 2024 17:25:58 -0500 Subject: [PATCH 053/104] fix(slo): Optimistic updates (#176548) --- .../public/hooks/slo/use_create_slo.ts | 34 +--- .../public/hooks/slo/use_delete_slo.ts | 37 +---- .../public/hooks/slo/use_fetch_slo_inspect.ts | 60 +++++++ .../public/hooks/slo/use_inspect_slo.ts | 41 ----- .../public/hooks/slo/use_reset_slo.ts | 8 +- .../public/hooks/slo/use_update_slo.ts | 50 +----- .../common/equivalent_api_request.tsx | 32 ++-- .../components/common/inspect_slo_portal.tsx | 26 --- .../components/common/slo_inspect.tsx | 153 +++++++++--------- .../slo_edit/components/slo_edit_form.tsx | 9 +- .../public/pages/slo_edit/slo_edit.tsx | 19 +-- .../public/pages/slos/components/slo_list.tsx | 2 +- 12 files changed, 185 insertions(+), 286 deletions(-) create mode 100644 x-pack/plugins/observability/public/hooks/slo/use_fetch_slo_inspect.ts delete mode 100644 x-pack/plugins/observability/public/hooks/slo/use_inspect_slo.ts delete mode 100644 x-pack/plugins/observability/public/pages/slo_edit/components/common/inspect_slo_portal.tsx diff --git a/x-pack/plugins/observability/public/hooks/slo/use_create_slo.ts b/x-pack/plugins/observability/public/hooks/slo/use_create_slo.ts index 6921c1f68cb15..b702e153fba5b 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_create_slo.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_create_slo.ts @@ -10,7 +10,6 @@ import { i18n } from '@kbn/i18n'; import { encode } from '@kbn/rison'; import type { CreateSLOInput, CreateSLOResponse, FindSLOResponse } from '@kbn/slo-schema'; import { QueryKey, useMutation, useQueryClient } from '@tanstack/react-query'; -import { v4 as uuidv4 } from 'uuid'; import { paths } from '../../../common/locators/paths'; import { useKibana } from '../../utils/kibana_react'; import { sloKeys } from './query_key_factory'; @@ -37,46 +36,17 @@ export function useCreateSlo() { return http.post(`/api/observability/slos`, { body }); }, { - onMutate: async ({ slo }) => { - await queryClient.cancelQueries({ queryKey: sloKeys.lists(), exact: false }); - - const queriesData = queryClient.getQueriesData({ - queryKey: sloKeys.lists(), - exact: false, - }); - - const [queryKey, previousData] = queriesData?.at(0) ?? []; - - const newItem = { ...slo, id: uuidv4(), summary: undefined }; - - const optimisticUpdate = { - page: previousData?.page ?? 1, - perPage: previousData?.perPage ?? 25, - total: previousData?.total ? previousData.total + 1 : 1, - results: [...(previousData?.results ?? []), newItem], - }; - - if (queryKey) { - queryClient.setQueryData(queryKey, optimisticUpdate); - } - - return { queryKey, previousData }; - }, onSuccess: (_data, { slo }) => { + queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); + toasts.addSuccess( i18n.translate('xpack.observability.slo.create.successNotification', { defaultMessage: 'Successfully created {name}', values: { name: slo.name }, }) ); - - queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); }, onError: (error, { slo }, context) => { - if (context?.previousData && context?.queryKey) { - queryClient.setQueryData(context.queryKey, context.previousData); - } - toasts.addError(new Error(error.body?.message ?? error.message), { title: i18n.translate('xpack.observability.slo.create.errorNotification', { defaultMessage: 'Something went wrong while creating {name}', diff --git a/x-pack/plugins/observability/public/hooks/slo/use_delete_slo.ts b/x-pack/plugins/observability/public/hooks/slo/use_delete_slo.ts index 0ba0c93266bda..2e77623fc991f 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_delete_slo.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_delete_slo.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { QueryKey, useMutation, useQueryClient } from '@tanstack/react-query'; +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FindSLOResponse } from '@kbn/slo-schema'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { QueryKey, useMutation, useQueryClient } from '@tanstack/react-query'; import { useKibana } from '../../utils/kibana_react'; import { sloKeys } from './query_key_factory'; @@ -36,38 +36,7 @@ export function useDeleteSlo() { } }, { - onMutate: async (slo) => { - await queryClient.cancelQueries({ queryKey: sloKeys.lists(), exact: false }); - - const queriesData = queryClient.getQueriesData({ - queryKey: sloKeys.lists(), - exact: false, - }); - const [queryKey, previousData] = queriesData?.at(0) ?? []; - - // taking into account partitioned slo - const matchingSloCount = - previousData?.results?.filter((result) => result.id === slo.id)?.length ?? 0; - - const optimisticUpdate = { - page: previousData?.page ?? 1, - perPage: previousData?.perPage ?? 25, - total: previousData?.total ? previousData.total - matchingSloCount : 0, - results: previousData?.results?.filter((result) => result.id !== slo.id) ?? [], - }; - - if (queryKey) { - queryClient.setQueryData(queryKey, optimisticUpdate); - } - - return { previousData, queryKey }; - }, - // If the mutation fails, use the context returned from onMutate to roll back onError: (error, { name }, context) => { - if (context?.previousData && context?.queryKey) { - queryClient.setQueryData(context.queryKey, context.previousData); - } - toasts.addError(new Error(error.body?.message ?? error.message), { title: i18n.translate('xpack.observability.slo.slo.delete.errorNotification', { defaultMessage: 'Failed to delete {name}', @@ -76,6 +45,8 @@ export function useDeleteSlo() { }); }, onSuccess: (_data, { name }) => { + queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); + toasts.addSuccess( i18n.translate('xpack.observability.slo.slo.delete.successNotification', { defaultMessage: 'Deleted {name}', diff --git a/x-pack/plugins/observability/public/hooks/slo/use_fetch_slo_inspect.ts b/x-pack/plugins/observability/public/hooks/slo/use_fetch_slo_inspect.ts new file mode 100644 index 0000000000000..c83b398a8fb3b --- /dev/null +++ b/x-pack/plugins/observability/public/hooks/slo/use_fetch_slo_inspect.ts @@ -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 { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { CreateSLOInput, SLOResponse } from '@kbn/slo-schema'; +import { useQuery } from '@tanstack/react-query'; +import { useKibana } from '../../utils/kibana_react'; + +interface SLOInspectResponse { + slo: SLOResponse; + pipeline: Record; + rollUpTransform: TransformPutTransformRequest; + summaryTransform: TransformPutTransformRequest; + temporaryDoc: Record; +} + +export interface UseInspectSLOResponse { + data: SLOInspectResponse | undefined; + isLoading: boolean; + isSuccess: boolean; + isError: boolean; +} + +export function useFetchSloInspect(slo: CreateSLOInput, shouldInspect: boolean) { + const { http } = useKibana().services; + + const { isLoading, isError, isSuccess, data } = useQuery({ + queryKey: ['slo', 'inspect'], + queryFn: async ({ signal }) => { + try { + const body = JSON.stringify(slo); + const response = await http.post( + '/internal/api/observability/slos/_inspect', + { + body, + signal, + } + ); + + return response; + } catch (error) { + // ignore error + } + }, + enabled: shouldInspect, + refetchOnWindowFocus: false, + keepPreviousData: true, + }); + + return { + data, + isLoading, + isSuccess, + isError, + }; +} diff --git a/x-pack/plugins/observability/public/hooks/slo/use_inspect_slo.ts b/x-pack/plugins/observability/public/hooks/slo/use_inspect_slo.ts deleted file mode 100644 index 6eaa3165aee77..0000000000000 --- a/x-pack/plugins/observability/public/hooks/slo/use_inspect_slo.ts +++ /dev/null @@ -1,41 +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 { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; -import type { FindSLOResponse, SLOResponse } from '@kbn/slo-schema'; -import { QueryKey, useMutation } from '@tanstack/react-query'; -import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { CreateSLOInput } from '@kbn/slo-schema'; -import { useKibana } from '../../utils/kibana_react'; - -type ServerError = IHttpFetchError; - -interface SLOInspectResponse { - slo: SLOResponse; - pipeline: Record; - rollUpTransform: TransformPutTransformRequest; - summaryTransform: TransformPutTransformRequest; - temporaryDoc: Record; -} - -export function useInspectSlo() { - const { http } = useKibana().services; - - return useMutation< - SLOInspectResponse, - ServerError, - { slo: CreateSLOInput }, - { previousData?: FindSLOResponse; queryKey?: QueryKey } - >( - ['inspectSlo'], - ({ slo }) => { - const body = JSON.stringify(slo); - return http.post(`/internal/api/observability/slos/_inspect`, { body }); - }, - {} - ); -} diff --git a/x-pack/plugins/observability/public/hooks/slo/use_reset_slo.ts b/x-pack/plugins/observability/public/hooks/slo/use_reset_slo.ts index 35f166e89b766..9f67c5efe3972 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_reset_slo.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_reset_slo.ts @@ -4,10 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useMutation } from '@tanstack/react-query'; -import { i18n } from '@kbn/i18n'; import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { i18n } from '@kbn/i18n'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useKibana } from '../../utils/kibana_react'; +import { sloKeys } from './query_key_factory'; type ServerError = IHttpFetchError; @@ -16,6 +17,8 @@ export function useResetSlo() { http, notifications: { toasts }, } = useKibana().services; + const queryClient = useQueryClient(); + return useMutation( ['resetSlo'], ({ id, name }) => { @@ -40,6 +43,7 @@ export function useResetSlo() { }); }, onSuccess: (_data, { name }) => { + queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); toasts.addSuccess( i18n.translate('xpack.observability.slo.slo.reset.successNotification', { defaultMessage: '{name} reset successfully', diff --git a/x-pack/plugins/observability/public/hooks/slo/use_update_slo.ts b/x-pack/plugins/observability/public/hooks/slo/use_update_slo.ts index 8f81075f0f2df..ff12ab2acdfe2 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_update_slo.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_update_slo.ts @@ -7,11 +7,11 @@ import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; +import { encode } from '@kbn/rison'; import type { FindSLOResponse, UpdateSLOInput, UpdateSLOResponse } from '@kbn/slo-schema'; import { QueryKey, useMutation, useQueryClient } from '@tanstack/react-query'; -import { encode } from '@kbn/rison'; -import { useKibana } from '../../utils/kibana_react'; import { paths } from '../../../common/locators/paths'; +import { useKibana } from '../../utils/kibana_react'; import { sloKeys } from './query_key_factory'; type ServerError = IHttpFetchError; @@ -36,47 +36,17 @@ export function useUpdateSlo() { return http.put(`/api/observability/slos/${sloId}`, { body }); }, { - onMutate: async ({ sloId, slo }) => { - await queryClient.cancelQueries({ queryKey: sloKeys.lists(), exact: false }); - - const queriesData = queryClient.getQueriesData({ - queryKey: sloKeys.lists(), - exact: false, - }); - const [queryKey, previousData] = queriesData?.at(0) ?? []; - - const updatedItem = { ...slo, id: sloId }; - const optimisticUpdate = { - page: previousData?.page ?? 1, - perPage: previousData?.perPage ?? 25, - total: previousData?.total ? previousData.total : 1, - results: [ - ...(previousData?.results?.filter((result) => result.id !== sloId) ?? []), - updatedItem, - ], - }; - - if (queryKey) { - queryClient.setQueryData(queryKey, optimisticUpdate); - } - - return { previousData, queryKey, sloId }; - }, onSuccess: (_data, { slo: { name } }) => { + queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); + toasts.addSuccess( i18n.translate('xpack.observability.slo.update.successNotification', { defaultMessage: 'Successfully updated {name}', values: { name }, }) ); - - queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); }, - onError: (error, { slo }, context) => { - if (context?.previousData && context?.queryKey) { - queryClient.setQueryData(context.queryKey, context.previousData); - } - + onError: (error, { slo, sloId }, context) => { toasts.addError(new Error(error.body?.message ?? error.message), { title: i18n.translate('xpack.observability.slo.update.errorNotification', { defaultMessage: 'Something went wrong when updating {name}', @@ -84,13 +54,9 @@ export function useUpdateSlo() { }), }); - if (context?.sloId) { - navigateToUrl( - http.basePath.prepend( - paths.observability.sloEditWithEncodedForm(context.sloId, encode(slo)) - ) - ); - } + navigateToUrl( + http.basePath.prepend(paths.observability.sloEditWithEncodedForm(sloId, encode(slo))) + ); }, } ); diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx index 6bf597b12d9a9..3f76c0df540e5 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx @@ -4,9 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { i18n } from '@kbn/i18n'; - -import React, { useEffect, useState } from 'react'; import { EuiButtonEmpty, EuiCodeBlock, @@ -18,29 +15,30 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; -import { useFormContext } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { CreateSLOInput } from '@kbn/slo-schema'; -import { CreateSLOForm } from '../../types'; +import { CreateSLOInput, GetSLOResponse } from '@kbn/slo-schema'; +import React, { useEffect, useState } from 'react'; +import { useFormContext } from 'react-hook-form'; import { transformCreateSLOFormToCreateSLOInput } from '../../helpers/process_slo_form_values'; +import { CreateSLOForm } from '../../types'; -export function EquivalentApiRequest({ - isCreateSloLoading, - isUpdateSloLoading, -}: { - isCreateSloLoading: boolean; - isUpdateSloLoading: boolean; -}) { - const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); +interface Props { + isEditMode: boolean; + disabled: boolean; + slo?: GetSLOResponse; +} +export function EquivalentApiRequest({ disabled, isEditMode, slo }: Props) { + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); const { getValues, trigger } = useFormContext(); - const [sloData, setSloData] = useState(); useEffect(() => { if (!isFlyoutVisible) { return; } + trigger().then((isValid) => { if (isValid) { setSloData(transformCreateSLOFormToCreateSLOInput(getValues())); @@ -72,7 +70,7 @@ export function EquivalentApiRequest({ - {'POST /api/observability/slos'} + {isEditMode ? `PUT /api/observability/slos/${slo!.id}` : 'POST /api/observability/slos'} @@ -115,7 +113,7 @@ export function EquivalentApiRequest({ color="primary" iconType="copyClipboard" data-test-subj="sloFormCopyJsonButton" - disabled={isCreateSloLoading || isUpdateSloLoading} + disabled={disabled} onClick={() => setIsFlyoutVisible(true)} > {i18n.translate('xpack.observability.slo.sloEdit.equivalentApiRequest', { diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/inspect_slo_portal.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/inspect_slo_portal.tsx deleted file mode 100644 index d03772c9bf4ce..0000000000000 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/inspect_slo_portal.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { InPortal } from 'react-reverse-portal'; -import { GetSLOResponse } from '@kbn/slo-schema'; -import { CreateSLOForm } from '../../types'; -import { SLOInspectWrapper } from './slo_inspect'; -import { InspectSLOPortalNode } from '../../slo_edit'; - -export interface SloInspectPortalProps { - getValues: () => CreateSLOForm; - trigger: () => Promise; - slo?: GetSLOResponse; -} -export function InspectSLOPortal(props: SloInspectPortalProps) { - return ( - - - - ); -} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/slo_inspect.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/slo_inspect.tsx index 2c96c0d2d05bc..9f911bb1787ea 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/slo_inspect.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/slo_inspect.tsx @@ -4,109 +4,114 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { i18n } from '@kbn/i18n'; - -import React, { ReactNode, useState } from 'react'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useFetcher } from '@kbn/observability-shared-plugin/public'; import { - EuiFlyout, + EuiAccordion, EuiButton, + EuiButtonEmpty, + EuiButtonIcon, EuiCodeBlock, - EuiFlyoutHeader, - EuiTitle, - EuiFlyoutFooter, - EuiSpacer, - EuiFlyoutBody, - EuiToolTip, EuiFlexGroup, EuiFlexItem, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, EuiLoadingSpinner, - EuiAccordion, - EuiButtonIcon, + EuiSpacer, + EuiTitle, + EuiToolTip, } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { + IngestPipelinesListParams, INGEST_PIPELINES_APP_LOCATOR, INGEST_PIPELINES_PAGES, - IngestPipelinesListParams, } from '@kbn/ingest-pipelines-plugin/public'; -import { SloInspectPortalProps } from './inspect_slo_portal'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useFetcher } from '@kbn/observability-shared-plugin/public'; +import { GetSLOResponse } from '@kbn/slo-schema'; +import React, { ReactNode, useState } from 'react'; +import { useFormContext } from 'react-hook-form'; import { ObservabilityPublicPluginsStart } from '../../../..'; -import { useInspectSlo } from '../../../../hooks/slo/use_inspect_slo'; -import { transformCreateSLOFormToCreateSLOInput } from '../../helpers/process_slo_form_values'; import { enableInspectEsQueries } from '../../../../../common'; +import { useFetchSloInspect } from '../../../../hooks/slo/use_fetch_slo_inspect'; import { usePluginContext } from '../../../../hooks/use_plugin_context'; +import { transformCreateSLOFormToCreateSLOInput } from '../../helpers/process_slo_form_values'; +import { CreateSLOForm } from '../../types'; + +interface Props { + slo?: GetSLOResponse; + disabled: boolean; +} -export function SLOInspectWrapper(props: SloInspectPortalProps) { +export function SLOInspectWrapper({ slo, disabled }: Props) { const { services: { uiSettings }, } = useKibana(); const { isDev } = usePluginContext(); - const isInspectorEnabled = uiSettings?.get(enableInspectEsQueries); - return isDev || isInspectorEnabled ? : null; + return isDev || isInspectorEnabled ? : null; } -function SLOInspect({ getValues, trigger, slo }: SloInspectPortalProps) { +function SLOInspect({ slo, disabled }: Props) { const { share, http } = useKibana().services; + const { trigger, getValues } = useFormContext(); + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); - const { mutateAsync: inspectSlo, data, isLoading } = useInspectSlo(); + const [isFormValid, setFormValid] = useState(false); - const { data: sloData } = useFetcher(async () => { - if (!isFlyoutVisible) { - return; - } - const isValid = await trigger(); - if (!isValid) { - return; - } - const sloForm = transformCreateSLOFormToCreateSLOInput(getValues()); - inspectSlo({ slo: { ...sloForm, id: slo?.id, revision: slo?.revision } }); - return sloForm; - }, [isFlyoutVisible, trigger, getValues, inspectSlo, slo]); + const sloFormValues = transformCreateSLOFormToCreateSLOInput(getValues()); + const { data: inspectSloData, isLoading } = useFetchSloInspect( + { ...sloFormValues, id: slo?.id, revision: slo?.revision }, + isFlyoutVisible && isFormValid + ); const { data: pipeLineUrl } = useFetcher(async () => { const ingestPipeLocator = share.url.locators.get( INGEST_PIPELINES_APP_LOCATOR ); - const ingestPipeLineId = data?.pipeline?.id; + const ingestPipeLineId = inspectSloData?.pipeline?.id; return ingestPipeLocator?.getUrl({ pipelineId: ingestPipeLineId, page: INGEST_PIPELINES_PAGES.LIST, }); - }, [data?.pipeline?.id, share.url.locators]); + }, [inspectSloData?.pipeline?.id, share.url.locators]); const closeFlyout = () => { setIsFlyoutVisible(false); - setIsInspecting(false); + setFormValid(false); }; - const [isInspecting, setIsInspecting] = useState(false); - const onButtonClick = () => { - trigger().then((isValid) => { - if (isValid) { - setIsInspecting(() => !isInspecting); - setIsFlyoutVisible(() => !isFlyoutVisible); - } - }); + const handleInspectButtonClick = async () => { + const valid = await trigger(); + if (!valid) { + setFormValid(false); + return; + } + + setFormValid(true); + setIsFlyoutVisible(true); }; let flyout; - if (isFlyoutVisible) { flyout = ( -

{CONFIG_LABEL}

+

+ {i18n.translate('xpack.observability.monitorInspect.configLabel', { + defaultMessage: 'SLO Configurations', + })} +

{isLoading && } - {data && ( + {inspectSloData && ( <> } - json={data.pipeline} + json={inspectSloData.pipeline} /> @@ -174,7 +179,7 @@ function SLOInspect({ getValues, trigger, slo }: SloInspectPortalProps) { 'xpack.observability.sLOInspect.codeBlockAccordion.temporaryDocumentLabel', { defaultMessage: 'Temporary document' } )} - json={data.temporaryDoc} + json={inspectSloData.temporaryDoc} /> )} @@ -193,20 +198,33 @@ function SLOInspect({ getValues, trigger, slo }: SloInspectPortalProps) {
); } + return ( <> - - {SLO_INSPECT_LABEL} - + {i18n.translate('xpack.observability.sLOInspect.sLOInspectButtonLabel', { + defaultMessage: 'SLO Inspect', + })} + {flyout} @@ -251,20 +269,3 @@ export function LoadingState() { ); } - -const SLO_INSPECT_LABEL = i18n.translate('xpack.observability.sLOInspect.sLOInspectButtonLabel', { - defaultMessage: 'SLO Inspect', -}); - -const VIEW_FORMATTED_CONFIG_LABEL = i18n.translate( - 'xpack.observability.slo.viewFormattedResourcesConfigsButtonLabel', - { defaultMessage: 'View formatted resources configs for SLO' } -); - -const VALID_CONFIG_LABEL = i18n.translate('xpack.observability.slo.formattedConfigLabel.valid', { - defaultMessage: 'Only valid form configurations can be inspected.', -}); - -const CONFIG_LABEL = i18n.translate('xpack.observability.monitorInspect.configLabel', { - defaultMessage: 'SLO Configurations', -}); diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx index dfc5fb1a6f563..9b5ddfc29b07d 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx @@ -10,7 +10,6 @@ import { i18n } from '@kbn/i18n'; import type { GetSLOResponse } from '@kbn/slo-schema'; import React, { useCallback } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { InspectSLOPortal } from './common/inspect_slo_portal'; import { EquivalentApiRequest } from './common/equivalent_api_request'; import { paths } from '../../../../common/locators/paths'; import { useCreateSlo } from '../../../hooks/slo/use_create_slo'; @@ -32,6 +31,7 @@ import { SloEditFormObjectiveSection } from './slo_edit_form_objective_section'; import { useCreateRule } from '../../../hooks/use_create_rule'; import { createBurnRateRuleRequestBody } from '../helpers/create_burn_rate_rule_request_body'; import { BurnRateRuleParams } from '../../../typings'; +import { SLOInspectWrapper } from './common/slo_inspect'; export interface Props { slo?: GetSLOResponse; @@ -165,12 +165,13 @@ export function SloEditForm({ slo }: Props) { + - ); diff --git a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx index f14f1d7a1446e..09eafbfdcc8c7 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx @@ -5,23 +5,19 @@ * 2.0. */ -import React from 'react'; -import { useParams } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public'; - -import { createHtmlPortalNode, OutPortal } from 'react-reverse-portal'; +import React from 'react'; +import { useParams } from 'react-router-dom'; import { paths } from '../../../common/locators/paths'; -import { useKibana } from '../../utils/kibana_react'; -import { usePluginContext } from '../../hooks/use_plugin_context'; -import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details'; -import { useLicense } from '../../hooks/use_license'; import { useCapabilities } from '../../hooks/slo/use_capabilities'; import { useFetchSloGlobalDiagnosis } from '../../hooks/slo/use_fetch_global_diagnosis'; -import { SloEditForm } from './components/slo_edit_form'; +import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details'; +import { useLicense } from '../../hooks/use_license'; +import { usePluginContext } from '../../hooks/use_plugin_context'; +import { useKibana } from '../../utils/kibana_react'; import { HeaderMenu } from '../overview/components/header_menu/header_menu'; - -export const InspectSLOPortalNode = createHtmlPortalNode(); +import { SloEditForm } from './components/slo_edit_form'; export function SloEditPage() { const { @@ -78,7 +74,6 @@ export function SloEditPage() { : i18n.translate('xpack.observability.sloCreatePageTitle', { defaultMessage: 'Create new SLO', }), - rightSideItems: [], bottomBorder: false, }} data-test-subj="slosEditPage" diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx index 19617273659b1..66a8ea84fcce8 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx @@ -76,7 +76,7 @@ export function SloList() { itemsPerPage={perPage} itemsPerPageOptions={[10, 25, 50, 100]} onChangeItemsPerPage={(newPerPage) => { - storeState({ perPage: newPerPage, page: 0 }); + onStateChange({ perPage: newPerPage }); }} /> From 16787801f8343b95486107cfe1f9194df2829385 Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Thu, 8 Feb 2024 15:46:33 -0700 Subject: [PATCH 054/104] [Managed content] readonly in library views (#176263) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Close https://github.com/elastic/kibana/issues/172387 This PR stops users from doing two things in the library views 1. deleting managed content 2. editing metadata of managed content It also includes a refactor to the `TableListView` interface to replace the `isItemEditable` callback with a row-level action. Screenshot 2024-02-06 at 3 03 06 PM Screenshot 2024-02-06 at 3 03 24 PM ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials — will be completed in https://github.com/elastic/kibana/issues/175150 - [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 - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed — https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5087 - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Stratoula Kalafateli --- .../src/components/editor_flyout_content.tsx | 8 +++ .../editor_flyout_content_container.tsx | 9 ++- .../src/components/metadata_form.tsx | 11 ++- .../src/open_content_editor.tsx | 2 +- .../table_list_view/src/table_list_view.tsx | 3 - .../src/table_list_view_table.tsx | 68 +++++++++++-------- .../table_list_view_table/src/types.ts | 2 +- .../dashboard_listing.test.tsx | 1 - .../use_dashboard_listing_table.test.tsx | 1 - .../hooks/use_dashboard_listing_table.tsx | 1 - .../public/utils/saved_visualize_utils.ts | 4 ++ .../components/visualize_listing.tsx | 6 +- test/functional/services/listing_table.ts | 24 ++++++- x-pack/plugins/lens/public/vis_type_alias.ts | 3 +- .../maps/public/maps_vis_type_alias.ts | 3 +- .../apps/managed_content/managed_content.ts | 41 +++++++++++ 16 files changed, 137 insertions(+), 50 deletions(-) diff --git a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx index a760ec5f5d1a9..007cc58c4e5ad 100644 --- a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx +++ b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx @@ -45,6 +45,7 @@ export interface Props { item: Item; entityName: string; isReadonly?: boolean; + readonlyReason?: string; services: Pick; onSave?: (args: { id: string; @@ -62,6 +63,7 @@ export const ContentEditorFlyoutContent: FC = ({ item, entityName, isReadonly = true, + readonlyReason, services: { TagSelector, TagList, notifyError }, onSave, onCancel, @@ -136,6 +138,12 @@ export const ContentEditorFlyoutContent: FC = ({ ; export type Props = CommonProps; diff --git a/packages/content-management/content_editor/src/components/metadata_form.tsx b/packages/content-management/content_editor/src/components/metadata_form.tsx index 42e06671bc7a8..26b433edcd161 100644 --- a/packages/content-management/content_editor/src/components/metadata_form.tsx +++ b/packages/content-management/content_editor/src/components/metadata_form.tsx @@ -27,6 +27,7 @@ interface Props { isSubmitted: boolean; }; isReadonly: boolean; + readonlyReason: string; tagsReferences: SavedObjectsReference[]; TagList?: Services['TagList']; TagSelector?: Services['TagSelector']; @@ -40,6 +41,7 @@ export const MetadataForm: FC = ({ TagList, TagSelector, isReadonly, + readonlyReason, }) => { const { title, @@ -54,11 +56,6 @@ export const MetadataForm: FC = ({ getWarnings, } = form; - const readOnlyToolTip = i18n.translate( - 'contentManagement.contentEditor.metadataForm.readOnlyToolTip', - { defaultMessage: 'To edit these details, contact your administrator for access.' } - ); - return ( @@ -73,7 +70,7 @@ export const MetadataForm: FC = ({ > = ({ > ; export function useOpenContentEditor() { diff --git a/packages/content-management/table_list_view/src/table_list_view.tsx b/packages/content-management/table_list_view/src/table_list_view.tsx index 081b837c93ed6..7270fd953a83e 100644 --- a/packages/content-management/table_list_view/src/table_list_view.tsx +++ b/packages/content-management/table_list_view/src/table_list_view.tsx @@ -37,7 +37,6 @@ export type TableListViewProps & { title: string; description?: string; @@ -74,7 +73,6 @@ export const TableListView = ({ titleColumnName, additionalRightSideActions, withoutPageTemplateWrapper, - itemIsEditable, }: TableListViewProps) => { const PageTemplate = withoutPageTemplateWrapper ? (React.Fragment as unknown as typeof KibanaPageTemplate) @@ -120,7 +118,6 @@ export const TableListView = ({ id={listingId} contentEditor={contentEditor} titleColumnName={titleColumnName} - itemIsEditable={itemIsEditable} withoutPageTemplateWrapper={withoutPageTemplateWrapper} onFetchSuccess={onFetchSuccess} setPageDataTestSubject={setPageDataTestSubject} diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx index 20509bab2ee56..24f9e9db2b564 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx @@ -95,11 +95,6 @@ export interface TableListViewTableProps< */ editItem?(item: T): void; - /** - * Handler to set edit action visiblity, and content editor readonly state per item. If not provided all non-managed items are considered editable. Note: Items with the managed property set to true will always be non-editable. - */ - itemIsEditable?(item: T): boolean; - /** * Name for the column containing the "title" value. */ @@ -259,7 +254,6 @@ function TableListViewTableComp({ findItems, createItem, editItem, - itemIsEditable, deleteItems, getDetailViewLink, onClickTitle, @@ -440,14 +434,34 @@ function TableListViewTableComp({ items, }); - const isEditable = useCallback( - (item: T) => { - // If the So is `managed` it is never editable. - if (item.managed) return false; - return itemIsEditable?.(item) ?? true; - }, - [itemIsEditable] - ); + const tableItemsRowActions = useMemo(() => { + return items.reduce((acc, item) => { + const ret = { + ...acc, + [item.id]: rowItemActions ? rowItemActions(item) : undefined, + }; + + if (item.managed) { + ret[item.id] = { + ...ret[item.id], + delete: { + enabled: false, + reason: i18n.translate('contentManagement.tableList.managedItemNoDelete', { + defaultMessage: 'This item is managed by Elastic. It cannot be deleted.', + }), + }, + edit: { + enabled: false, + reason: i18n.translate('contentManagement.tableList.managedItemNoEdit', { + defaultMessage: 'This item is managed by Elastic. Clone it before making changes.', + }), + }, + }; + } + + return ret; + }, {}); + }, [items, rowItemActions]); const inspectItem = useCallback( (item: T) => { @@ -464,7 +478,9 @@ function TableListViewTableComp({ }, entityName, ...contentEditor, - isReadonly: contentEditor.isReadonly || !isEditable(item), + isReadonly: + contentEditor.isReadonly || tableItemsRowActions[item.id]?.edit?.enabled === false, + readonlyReason: tableItemsRowActions[item.id]?.edit?.reason, onSave: contentEditor.onSave && (async (args) => { @@ -475,7 +491,14 @@ function TableListViewTableComp({ }), }); }, - [getTagIdsFromReferences, openContentEditor, entityName, contentEditor, isEditable, fetchItems] + [ + getTagIdsFromReferences, + openContentEditor, + entityName, + contentEditor, + tableItemsRowActions, + fetchItems, + ] ); const tableColumns = useMemo(() => { @@ -549,7 +572,7 @@ function TableListViewTableComp({ ), icon: 'pencil', type: 'icon', - available: (item) => isEditable(item), + available: (item) => Boolean(tableItemsRowActions[item.id]?.edit?.enabled), enabled: (v) => !(v as unknown as { error: string })?.error, onClick: editItem, 'data-test-subj': `edit-action`, @@ -605,7 +628,7 @@ function TableListViewTableComp({ addOrRemoveExcludeTagFilter, addOrRemoveIncludeTagFilter, DateFormatterComp, - isEditable, + tableItemsRowActions, inspectItem, ]); @@ -617,15 +640,6 @@ function TableListViewTableComp({ return selectedIds.map((selectedId) => itemsById[selectedId]); }, [selectedIds, itemsById]); - const tableItemsRowActions = useMemo(() => { - return items.reduce((acc, item) => { - return { - ...acc, - [item.id]: rowItemActions ? rowItemActions(item) : undefined, - }; - }, {}); - }, [items, rowItemActions]); - // ------------ // Callbacks // ------------ diff --git a/packages/content-management/table_list_view_table/src/types.ts b/packages/content-management/table_list_view_table/src/types.ts index c8e734a289451..90729464288be 100644 --- a/packages/content-management/table_list_view_table/src/types.ts +++ b/packages/content-management/table_list_view_table/src/types.ts @@ -13,7 +13,7 @@ export interface Tag { color: string; } -export type TableRowAction = 'delete'; +export type TableRowAction = 'delete' | 'edit'; export type RowActions = { [action in TableRowAction]?: { diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx index e7a26c4a6bcd2..4da2d77825f47 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.test.tsx @@ -88,7 +88,6 @@ test('when showWriteControls is true, table list view is passed editing function createItem: expect.any(Function), deleteItems: expect.any(Function), editItem: expect.any(Function), - itemIsEditable: expect.any(Function), }), expect.any(Object) // react context ); diff --git a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx index f30ed1b21f1d9..5eb0d661ef473 100644 --- a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx @@ -147,7 +147,6 @@ describe('useDashboardListingTable', () => { initialPageSize: 5, listingLimit: 20, onFetchSuccess: expect.any(Function), - itemIsEditable: expect.any(Function), setPageDataTestSubject: expect.any(Function), title: 'Dashboard List', urlStateEnabled: false, diff --git a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx index 80b39ff0e9d62..92856edf92881 100644 --- a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx @@ -283,7 +283,6 @@ export const useDashboardListingTable = ({ createItem: !showWriteControls || !showCreateDashboardButton ? undefined : createItem, deleteItems: !showWriteControls ? undefined : deleteItems, editItem: !showWriteControls ? undefined : editItem, - itemIsEditable: () => showWriteControls, emptyPrompt, entityName, entityNamePlural, diff --git a/src/plugins/visualizations/public/utils/saved_visualize_utils.ts b/src/plugins/visualizations/public/utils/saved_visualize_utils.ts index 7ef70fb8fc9b6..b8fc2c3f1032a 100644 --- a/src/plugins/visualizations/public/utils/saved_visualize_utils.ts +++ b/src/plugins/visualizations/public/utils/saved_visualize_utils.ts @@ -61,16 +61,19 @@ export function mapHitSource( id, references, updatedAt, + managed, }: { attributes: SavedObjectAttributes; id: string; references: SavedObjectReference[]; updatedAt?: string; + managed?: boolean; } ) { const newAttributes: { id: string; references: SavedObjectReference[]; + managed?: boolean; url: string; savedObjectType?: string; editor?: { editUrl?: string }; @@ -86,6 +89,7 @@ export function mapHitSource( references, url: urlFor(id), updatedAt, + managed, ...attributes, }; diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index 4145612132259..bf07e1151c298 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -64,6 +64,7 @@ const toTableListViewSavedObject = (savedObject: Record): Visua return { id: savedObject.id as string, updatedAt: savedObject.updatedAt as string, + managed: savedObject.managed as boolean, references: savedObject.references as Array<{ id: string; type: string; name: string }>, type: savedObject.savedObjectType as string, icon: savedObject.icon as string, @@ -90,7 +91,7 @@ type CustomTableViewProps = Pick< | 'editItem' | 'contentEditor' | 'emptyPrompt' - | 'itemIsEditable' + | 'rowItemActions' >; const useTableListViewProps = ( @@ -260,7 +261,8 @@ const useTableListViewProps = ( editItem, emptyPrompt: noItemsFragment, createItem: createNewVis, - itemIsEditable: ({ attributes: { readOnly } }) => visualizeCapabilities.save && !readOnly, + rowItemActions: ({ attributes: { readOnly } }) => + !visualizeCapabilities.save || readOnly ? { edit: { enabled: false } } : undefined, }; return props; diff --git a/test/functional/services/listing_table.ts b/test/functional/services/listing_table.ts index f83de38fb468b..220abf4f41fc3 100644 --- a/test/functional/services/listing_table.ts +++ b/test/functional/services/listing_table.ts @@ -69,9 +69,14 @@ export class ListingTableService extends FtrService { private async getAllSelectableItemsNamesOnCurrentPage(): Promise { const visualizationNames = []; - const links = await this.find.allByCssSelector('.euiTableRow-isSelectable .euiLink'); - for (let i = 0; i < links.length; i++) { - visualizationNames.push(await links[i].getVisibleText()); + // TODO - use .euiTableRow-isSelectable when it's working again (https://github.com/elastic/eui/issues/7515) + const rows = await this.find.allByCssSelector('.euiTableRow'); + for (let i = 0; i < rows.length; i++) { + const checkbox = await rows[i].findByCssSelector('.euiCheckbox__input'); + if (await checkbox.isEnabled()) { + const link = await rows[i].findByCssSelector('.euiLink'); + visualizationNames.push(await link.getVisibleText()); + } } this.log.debug(`Found ${visualizationNames.length} selectable visualizations on current page`); return visualizationNames; @@ -165,6 +170,19 @@ export class ListingTableService extends FtrService { await inspectButtons[index].click(); } + public async inspectorFieldsReadonly() { + const disabledValues = await Promise.all([ + this.testSubjects.getAttribute('nameInput', 'readonly'), + this.testSubjects.getAttribute('descriptionInput', 'readonly'), + ]); + + return disabledValues.every((value) => value === 'true'); + } + + public async closeInspector() { + await this.testSubjects.click('closeFlyoutButton'); + } + /** * Edit Visualization title and description in the flyout */ diff --git a/x-pack/plugins/lens/public/vis_type_alias.ts b/x-pack/plugins/lens/public/vis_type_alias.ts index 20822ee76a094..e20b60a11c57a 100644 --- a/x-pack/plugins/lens/public/vis_type_alias.ts +++ b/x-pack/plugins/lens/public/vis_type_alias.ts @@ -36,13 +36,14 @@ export const getLensAliasConfig = (): VisTypeAlias => ({ clientOptions: { update: { overwrite: true } }, client: getLensClient, toListItem(savedObject) { - const { id, type, updatedAt, attributes } = savedObject; + const { id, type, updatedAt, attributes, managed } = savedObject; const { title, description } = attributes as { title: string; description?: string }; return { id, title, description, updatedAt, + managed, editor: { editUrl: getEditPath(id), editApp: 'lens' }, icon: 'lensApp', stage: 'production', diff --git a/x-pack/plugins/maps/public/maps_vis_type_alias.ts b/x-pack/plugins/maps/public/maps_vis_type_alias.ts index e161689643612..48a96a2d0f988 100644 --- a/x-pack/plugins/maps/public/maps_vis_type_alias.ts +++ b/x-pack/plugins/maps/public/maps_vis_type_alias.ts @@ -39,7 +39,7 @@ export function getMapsVisTypeAlias() { searchFields: ['title^3'], client: getMapClient, toListItem(mapItem: MapItem) { - const { id, type, updatedAt, attributes } = mapItem; + const { id, type, updatedAt, attributes, managed } = mapItem; const { title, description } = attributes; return { @@ -47,6 +47,7 @@ export function getMapsVisTypeAlias() { title, description, updatedAt, + managed, editor: { editUrl: getEditPath(id), editApp: APP_ID, diff --git a/x-pack/test/functional/apps/managed_content/managed_content.ts b/x-pack/test/functional/apps/managed_content/managed_content.ts index 545d7ad1c4dee..c50a0c4d27571 100644 --- a/x-pack/test/functional/apps/managed_content/managed_content.ts +++ b/x-pack/test/functional/apps/managed_content/managed_content.ts @@ -16,12 +16,15 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'common', 'discover', 'maps', + 'visualize', 'dashboard', ]); const kibanaServer = getService('kibanaServer'); const esArchiver = getService('esArchiver'); const testSubjects = getService('testSubjects'); const dashboardAddPanel = getService('dashboardAddPanel'); + const listingTable = getService('listingTable'); + const log = getService('log'); describe('Managed Content', () => { before(async () => { @@ -32,6 +35,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { after(async () => { esArchiver.unload('x-pack/test/functional/es_archives/logstash_functional'); kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/managed_content'); + kibanaServer.importExport.savedObjects.clean({ types: ['dashboard'] }); // we do create a new dashboard in this test }); describe('preventing the user from overwriting managed content', () => { @@ -122,6 +126,43 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); + describe('library views', () => { + const assertInspectorReadonly = async (name: string) => { + log.debug(`making sure table list inspector for ${name} is read-only`); + await listingTable.searchForItemWithName(name); + await listingTable.waitUntilTableIsLoaded(); + await listingTable.inspectVisualization(); + expect(await listingTable.inspectorFieldsReadonly()).to.be(true); + await listingTable.closeInspector(); + }; + + it('visualize library: managed content is read-only', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + + const deletableItems = await listingTable.getAllSelectableItemsNames(); + + expect(deletableItems).to.eql([ + 'Unmanaged lens vis', + 'Unmanaged legacy visualization', + 'Unmanaged map', + ]); + + await assertInspectorReadonly('Managed lens vis'); + await assertInspectorReadonly('Managed legacy visualization'); + await assertInspectorReadonly('Managed map'); + }); + + it('dashboard library: managed content is read-only', async () => { + await PageObjects.dashboard.gotoDashboardListingURL(); + + const deletableItems = await listingTable.getAllSelectableItemsNames(); + + expect(deletableItems).to.eql([]); + + await assertInspectorReadonly('Managed dashboard'); + }); + }); + describe('managed panels in dashboards', () => { it('inlines panels when managed dashboard cloned', async () => { await PageObjects.common.navigateToActualUrl( From 15c99635f10542829177ab33ec9c59ed08fece85 Mon Sep 17 00:00:00 2001 From: Adam Demjen Date: Thu, 8 Feb 2024 21:25:04 -0500 Subject: [PATCH 055/104] [Search] Remove pass-through values/actions from model select logic (#176551) ## Summary Remove pure pass-through actions and selectors from `model_select_logic.ts`. No functional changes. --- .../ml_inference/model_select_logic.test.ts | 8 +-- .../ml_inference/model_select_logic.ts | 55 ++++--------------- 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts index 8af7d59a1ceec..6a20629de4d43 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts @@ -56,13 +56,13 @@ describe('ModelSelectLogic', () => { expect(ModelSelectLogic.actions.startPollingModels).toHaveBeenCalled(); }); it('sets selected model as non-placeholder', () => { - jest.spyOn(ModelSelectLogic.actions, 'clearModelPlaceholderFlagFromMLInferenceLogic'); + jest.spyOn(ModelSelectLogic.actions, 'clearModelPlaceholderFlag'); ModelSelectLogic.actions.createModelSuccess(CREATE_MODEL_API_RESPONSE); - expect( - ModelSelectLogic.actions.clearModelPlaceholderFlagFromMLInferenceLogic - ).toHaveBeenCalledWith(CREATE_MODEL_API_RESPONSE.modelId); + expect(ModelSelectLogic.actions.clearModelPlaceholderFlag).toHaveBeenCalledWith( + CREATE_MODEL_API_RESPONSE.modelId + ); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts index 09fd2e0ae8f54..a6be0e921b358 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts @@ -8,7 +8,6 @@ import { kea, MakeLogicType } from 'kea'; import { HttpError, Status } from '../../../../../../../common/types/api'; -import { MlModel } from '../../../../../../../common/types/ml'; import { getErrorsFromHttpResponse } from '../../../../../shared/flash_messages/handle_api_errors'; import { CreateModelApiLogic, @@ -27,13 +26,12 @@ import { } from './ml_inference_logic'; export interface ModelSelectActions { - clearModelPlaceholderFlagFromMLInferenceLogic: MLInferenceProcessorsActions['clearModelPlaceholderFlag']; + clearModelPlaceholderFlag: MLInferenceProcessorsActions['clearModelPlaceholderFlag']; createModel: (modelId: string) => { modelId: string }; createModelError: CreateModelApiLogicActions['apiError']; createModelMakeRequest: CreateModelApiLogicActions['makeRequest']; createModelSuccess: CreateModelApiLogicActions['apiSuccess']; setInferencePipelineConfiguration: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; - setInferencePipelineConfigurationFromMLInferenceLogic: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; startModel: (modelId: string) => { modelId: string }; startModelError: CreateModelApiLogicActions['apiError']; startModelMakeRequest: StartModelApiLogicActions['makeRequest']; @@ -43,19 +41,14 @@ export interface ModelSelectActions { export interface ModelSelectValues { addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal']; - addInferencePipelineModalFromMLInferenceLogic: MLInferenceProcessorsValues['addInferencePipelineModal']; areActionButtonsDisabled: boolean; createModelError: HttpError | undefined; createModelStatus: Status; ingestionMethod: string; - ingestionMethodFromIndexViewLogic: string; isLoading: boolean; - isModelsInitialLoadingFromMLInferenceLogic: boolean; modelStateChangeError: string | undefined; - selectableModels: MlModel[]; - selectableModelsFromMLInferenceLogic: MlModel[]; - selectedModel: MlModel | undefined; - selectedModelFromMLInferenceLogic: MlModel | undefined; + selectableModels: MLInferenceProcessorsValues['selectableModels']; + selectedModel: MLInferenceProcessorsValues['selectedModel']; startModelError: HttpError | undefined; startModelStatus: Status; } @@ -63,7 +56,6 @@ export interface ModelSelectValues { export const ModelSelectLogic = kea>({ actions: { createModel: (modelId: string) => ({ modelId }), - setInferencePipelineConfiguration: (configuration) => ({ configuration }), startModel: (modelId: string) => ({ modelId }), }, connect: { @@ -75,11 +67,7 @@ export const ModelSelectLogic = kea { actions.startPollingModels(); // The create action succeeded, so the model is no longer a placeholder - actions.clearModelPlaceholderFlagFromMLInferenceLogic(response.modelId); - }, - setInferencePipelineConfiguration: ({ configuration }) => { - actions.setInferencePipelineConfigurationFromMLInferenceLogic(configuration); + actions.clearModelPlaceholderFlag(response.modelId); }, startModel: ({ modelId }) => { actions.startModelMakeRequest({ modelId }); @@ -124,19 +109,11 @@ export const ModelSelectLogic = kea ({ - addInferencePipelineModal: [ - () => [selectors.addInferencePipelineModalFromMLInferenceLogic], - (modal) => modal, // Pass-through - ], areActionButtonsDisabled: [ () => [selectors.createModelStatus, selectors.startModelStatus], (createModelStatus: Status, startModelStatus: Status) => createModelStatus === Status.LOADING || startModelStatus === Status.LOADING, ], - ingestionMethod: [ - () => [selectors.ingestionMethodFromIndexViewLogic], - (ingestionMethod) => ingestionMethod, // Pass-through - ], modelStateChangeError: [ () => [selectors.createModelError, selectors.startModelError], (createModelError?: HttpError, startModelError?: HttpError) => { @@ -145,17 +122,5 @@ export const ModelSelectLogic = kea [selectors.selectableModelsFromMLInferenceLogic], - (selectableModels) => selectableModels, // Pass-through - ], - selectedModel: [ - () => [selectors.selectedModelFromMLInferenceLogic], - (selectedModel) => selectedModel, // Pass-through - ], - isLoading: [ - () => [selectors.isModelsInitialLoadingFromMLInferenceLogic], - (isModelsInitialLoading) => isModelsInitialLoading, // Pass-through - ], }), }); From 5ab0240b11e410df0f21ad647e1ecb5387247737 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 9 Feb 2024 01:14:43 -0500 Subject: [PATCH 056/104] [api-docs] 2024-02-09 Daily api_docs build (#176558) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/608 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_observability.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/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.devdocs.json | 52 ++++++ api_docs/console.mdx | 4 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 6 +- api_docs/deprecations_by_team.mdx | 4 +- api_docs/dev_tools.devdocs.json | 74 ++++++++- api_docs/dev_tools.mdx | 12 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_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/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.devdocs.json | 14 ++ api_docs/index_management.mdx | 4 +- api_docs/infra.mdx | 2 +- api_docs/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- .../kbn_alerting_api_integration_helpers.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_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_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_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mock.mdx | 2 +- api_docs/kbn_code_owners.mdx | 2 +- api_docs/kbn_coloring.devdocs.json | 155 +++++++++++++++--- api_docs/kbn_coloring.mdx | 4 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- ...ent_management_content_editor.devdocs.json | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...nt_management_table_list_view.devdocs.json | 6 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...agement_table_list_view_table.devdocs.json | 38 +---- ...ntent_management_table_list_view_table.mdx | 4 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 4 + api_docs/kbn_core_http_server.mdx | 2 +- 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_status_common.mdx | 2 +- ...n_core_status_common_internal.devdocs.json | 14 ++ api_docs/kbn_core_status_common_internal.mdx | 4 +- 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_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_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_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_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.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_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_utils.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 +- .../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_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- ...anguage_documentation_popover.devdocs.json | 4 +- .../kbn_language_documentation_popover.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 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...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_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.devdocs.json | 16 ++ api_docs/kbn_ml_anomaly_utils.mdx | 4 +- 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_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_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.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_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.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_library.mdx | 2 +- api_docs/kbn_presentation_publishing.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_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_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_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 +- api_docs/kbn_rison.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_search_api_panels.devdocs.json | 33 +++- api_docs/kbn_search_api_panels.mdx | 4 +- api_docs/kbn_search_connectors.devdocs.json | 70 ++++++++ api_docs/kbn_search_connectors.mdx | 4 +- 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_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- api_docs/kbn_security_plugin_types_server.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 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_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_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_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_eui_helpers.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.devdocs.json | 50 +++++- api_docs/kbn_text_based_editor.mdx | 4 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.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_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.devdocs.json | 35 ++++ api_docs/kbn_utils.mdx | 4 +- 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_helpers.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 12 ++ 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.devdocs.json | 6 +- api_docs/licensing.mdx | 2 +- api_docs/links.mdx | 2 +- api_docs/lists.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.mdx | 2 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_logs_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.devdocs.json | 4 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 28 ++-- 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/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.devdocs.json | 33 +++- api_docs/text_based_languages.mdx | 4 +- 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.mdx | 2 +- 669 files changed, 1221 insertions(+), 765 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 2e5a688aadf5c..115f4386aef48 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-02-08 +date: 2024-02-09 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 c4f09f5856a44..019bd15d3c325 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index fa3a76f742ff2..42c4c6692a2f9 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index f03427a765ea1..b5aac507e2bc6 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-02-08 +date: 2024-02-09 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 a2ecdca05e508..97a8f45bb01b5 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-02-08 +date: 2024-02-09 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 a7e39b0784003..e251380a6e34a 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-02-08 +date: 2024-02-09 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 cb88e4b523e3c..90bbd56a8b528 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-02-08 +date: 2024-02-09 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 0db7c0441306c..f569b025a53d1 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 72dd300e3f6ab..26e4b3d1f1295 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 6e679de83bfc2..94c523989c981 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-02-08 +date: 2024-02-09 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 b1eff88214d4e..dfba05dd87628 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-02-08 +date: 2024-02-09 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 6c8a7b48a899f..dd38559e6ac22 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-02-08 +date: 2024-02-09 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 b0b4dac09d20f..1982280402cd7 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-02-08 +date: 2024-02-09 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 6155cfbba8614..5116e22a5bb19 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-02-08 +date: 2024-02-09 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 d141f83ff45a9..42c64e2a21d52 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-02-08 +date: 2024-02-09 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 55a52449f1718..b658f61b0ab24 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-02-08 +date: 2024-02-09 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 93a43658a51fe..3c785379ddab5 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 5915c7ca85ded..42481abc23db6 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 3114799838b01..9e19fe61e9b9f 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.devdocs.json b/api_docs/console.devdocs.json index b12dc9c4e02bb..7e5fa3d5a39a6 100644 --- a/api_docs/console.devdocs.json +++ b/api_docs/console.devdocs.json @@ -577,6 +577,58 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "console", + "id": "def-public.ConsolePluginStart.isEmbeddedConsoleAvailable", + "type": "Function", + "tags": [], + "label": "isEmbeddedConsoleAvailable", + "description": [ + "\nisEmbeddedConsoleAvailable is available if the embedded console can be rendered. Returns true when\ncalled if the Embedded Console is currently rendered." + ], + "signature": [ + "(() => boolean) | undefined" + ], + "path": "src/plugins/console/public/types/plugin_dependencies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "console", + "id": "def-public.ConsolePluginStart.openEmbeddedConsole", + "type": "Function", + "tags": [], + "label": "openEmbeddedConsole", + "description": [ + "\nopenEmbeddedConsole is available if the embedded console can be rendered. Calling\nthis function will open the embedded console on the page if it is currently rendered." + ], + "signature": [ + "((content?: string | undefined) => void) | undefined" + ], + "path": "src/plugins/console/public/types/plugin_dependencies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "console", + "id": "def-public.ConsolePluginStart.openEmbeddedConsole.$1", + "type": "string", + "tags": [], + "label": "content", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/console/public/types/plugin_dependencies.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 527e60940783b..6daef6dae1c72 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 29 | 0 | 23 | 0 | +| 32 | 0 | 24 | 0 | ## Client diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 0588bc2a0bf97..063190e1275d6 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-02-08 +date: 2024-02-09 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 926346635e430..fad05eb06b5f6 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-02-08 +date: 2024-02-09 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 8e5c36fbc0747..9d8e1861c2b9f 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-02-08 +date: 2024-02-09 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 7d5bedf0444df..5b73b2cd7e084 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-02-08 +date: 2024-02-09 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 791ceaa540a1d..c132a96596292 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-02-08 +date: 2024-02-09 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 0266dc6c63480..05d8e7ccb8511 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 6d57ee43cdb19..a9e51e62bad4f 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-02-08 +date: 2024-02-09 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 6cf0ec8b332ee..b46338404c5ca 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index a986ac73a1a4a..b62b7e22f2a87 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-02-08 +date: 2024-02-09 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 b51cccc090336..b93b69758028d 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-02-08 +date: 2024-02-09 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 2448185780faf..0806b5b3e3085 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-02-08 +date: 2024-02-09 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 84e6eae5ffd18..00dc6ebb0e065 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-02-08 +date: 2024-02-09 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 b09f9dd8a0a27..bec2c355c602d 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-02-08 +date: 2024-02-09 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 27f53e5af8347..b45fb5963c7ce 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-02-08 +date: 2024-02-09 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 a433ea47849f4..a6831274020f7 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 3d5d34b7d900c..23a002e9e0158 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1084,7 +1084,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [register_ml_alerts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/alerting/register_ml_alerts.ts#:~:text=registerNavigation) | - | -| | [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=KibanaThemeProvider)+ 2 more | - | +| | [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [single_metric_viewer_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx#:~:text=KibanaThemeProvider), [single_metric_viewer_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx#:~:text=KibanaThemeProvider), [single_metric_viewer_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider)+ 5 more | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/plugin.ts#:~:text=license%24) | 8.8.0 | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/plugin.ts#:~:text=license%24) | 8.8.0 | | | [annotations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/routes/annotations.ts#:~:text=authc) | - | @@ -1339,7 +1339,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider) | - | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | -| | [create_threat_signal.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts#:~:text=license%24), [create_event_signal.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts#:~:text=license%24), [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/query.ts#:~:text=license%24), [threshold.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts#:~:text=license%24) | 8.8.0 | +| | [create_threat_signals.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts#:~:text=license%24), [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/query.ts#:~:text=license%24), [threshold.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts#:~:text=license%24) | 8.8.0 | | | [request_context_factory.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts#:~:text=authc), [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedCellValueElementProps), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedCellValueElementProps) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedRowRenderer), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedRowRenderer) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index e41eae851ed2d..1270524fcc80b 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -165,4 +165,4 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | --------|-------|-----------|-----------| | securitySolution | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | | securitySolution | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | -| securitySolution | | [create_threat_signal.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts#:~:text=license%24), [create_event_signal.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts#:~:text=license%24), [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/query.ts#:~:text=license%24), [threshold.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts#:~:text=license%24) | 8.8.0 | \ No newline at end of file +| securitySolution | | [create_threat_signals.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts#:~:text=license%24), [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/query.ts#:~:text=license%24), [threshold.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts#:~:text=license%24) | 8.8.0 | \ No newline at end of file diff --git a/api_docs/dev_tools.devdocs.json b/api_docs/dev_tools.devdocs.json index 624340d7d5db6..effd1a91e5271 100644 --- a/api_docs/dev_tools.devdocs.json +++ b/api_docs/dev_tools.devdocs.json @@ -197,7 +197,42 @@ "functions": [], "interfaces": [], "enums": [], - "misc": [], + "misc": [ + { + "parentPluginId": "devTools", + "id": "def-public.DEV_TOOLS_FEATURE_ID", + "type": "string", + "tags": [], + "label": "DEV_TOOLS_FEATURE_ID", + "description": [ + "\nThe UI Setting prefix and category for dev tools UI Settings" + ], + "signature": [ + "\"devTools\"" + ], + "path": "src/plugins/dev_tools/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "devTools", + "id": "def-public.ENABLE_DOCKED_CONSOLE_UI_SETTING_ID", + "type": "string", + "tags": [], + "label": "ENABLE_DOCKED_CONSOLE_UI_SETTING_ID", + "description": [ + "\nUI Setting ID for enabling / disabling the docked console in Kibana" + ], + "signature": [ + "\"devTools:enableDockedConsole\"" + ], + "path": "src/plugins/dev_tools/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "objects": [], "setup": { "parentPluginId": "devTools", @@ -267,7 +302,42 @@ "functions": [], "interfaces": [], "enums": [], - "misc": [], + "misc": [ + { + "parentPluginId": "devTools", + "id": "def-common.DEV_TOOLS_FEATURE_ID", + "type": "string", + "tags": [], + "label": "DEV_TOOLS_FEATURE_ID", + "description": [ + "\nThe UI Setting prefix and category for dev tools UI Settings" + ], + "signature": [ + "\"devTools\"" + ], + "path": "src/plugins/dev_tools/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "devTools", + "id": "def-common.ENABLE_DOCKED_CONSOLE_UI_SETTING_ID", + "type": "string", + "tags": [], + "label": "ENABLE_DOCKED_CONSOLE_UI_SETTING_ID", + "description": [ + "\nUI Setting ID for enabling / disabling the docked console in Kibana" + ], + "signature": [ + "\"devTools:enableDockedConsole\"" + ], + "path": "src/plugins/dev_tools/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "objects": [] } } \ No newline at end of file diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 359ab0e7288e9..037d373715e25 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 12 | 0 | 10 | 3 | +| 16 | 0 | 10 | 3 | ## Client @@ -31,3 +31,11 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti ### Classes +### Consts, variables and types + + +## Common + +### Consts, variables and types + + diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 962b6c9db5e41..f434343e332e2 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-02-08 +date: 2024-02-09 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 db0763d64fdb3..d5f7d8d841fae 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 0a9d3737f22cd..b6a0f43059884 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 62ab029aa3e2f..647b512be90ca 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index e4757ac0fa026..da131042b7f00 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-02-08 +date: 2024-02-09 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 edacdc9d052fa..458a49dc4576f 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-02-08 +date: 2024-02-09 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 53d150a26ef56..660f63491f660 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-02-08 +date: 2024-02-09 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 31ce75f352a2b..690c1dc9867f6 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index cebbea3aa42b1..cd3829569f92a 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index cc9070788f35c..19ec9e3ad6569 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-02-08 +date: 2024-02-09 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 059381734ebd4..9650bb4ef17ea 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-02-08 +date: 2024-02-09 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 bc0599a12a058..c3ab21ffe81ba 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-02-08 +date: 2024-02-09 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 0c5e1b26620d6..ff3c3ca179435 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-02-08 +date: 2024-02-09 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 910ad5fcb79dc..d81a36f9bafdc 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-02-08 +date: 2024-02-09 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 6c9ac5adda786..06e9f6e9e81a8 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-02-08 +date: 2024-02-09 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 192bc924a0157..a71631695a985 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-02-08 +date: 2024-02-09 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 b24dc2180c5ff..3df160887b6cf 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-02-08 +date: 2024-02-09 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 847888ad3d734..67be9823478cb 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-02-08 +date: 2024-02-09 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 05e169cdacb4f..d8c286d4ce4d3 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-02-08 +date: 2024-02-09 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 b84b768bd7765..157ffba8020d8 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-02-08 +date: 2024-02-09 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 e9741fccf718a..1cd75f9f63cdc 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-02-08 +date: 2024-02-09 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 ef330144a3107..17ef809d3d559 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-02-08 +date: 2024-02-09 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 e29d8c3310626..9c6500812fa1b 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-02-08 +date: 2024-02-09 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 951cb74b24a4b..f54bec29cb634 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-02-08 +date: 2024-02-09 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 f8dd39ea344b2..22b3345eab76c 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-02-08 +date: 2024-02-09 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 6a8c5d756baeb..78e0702f056da 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-02-08 +date: 2024-02-09 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 56fd7d9a3e9e2..f466543b12002 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-02-08 +date: 2024-02-09 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 cce1d5fed656e..75b19c5e1f8a7 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-02-08 +date: 2024-02-09 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 671764bec61f0..6cd1d8e033548 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 836a66f011251..b35505afaed9a 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-02-08 +date: 2024-02-09 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 51c67ed1e825d..fc6f0f3b05ecc 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-02-08 +date: 2024-02-09 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 9b30702e06533..201c6e551838a 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-02-08 +date: 2024-02-09 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 c9116c07c7ca6..928790bcaf80b 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-02-08 +date: 2024-02-09 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 80c2deb4cd624..270fbb4bb8353 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-02-08 +date: 2024-02-09 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 a4d1a189f4d6f..c2c90ef74c41a 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-02-08 +date: 2024-02-09 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 2d95568af2c61..9b9d0e634a94c 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-02-08 +date: 2024-02-09 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 58557d1df0f81..754bedf184518 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 605daf26ab6e8..32705d1648210 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.devdocs.json b/api_docs/index_management.devdocs.json index 930f9a12fe45b..d22836d359b90 100644 --- a/api_docs/index_management.devdocs.json +++ b/api_docs/index_management.devdocs.json @@ -3089,6 +3089,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "indexManagement", + "id": "def-common.TemplateListItem.composedOf", + "type": "Array", + "tags": [], + "label": "composedOf", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/templates.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "indexManagement", "id": "def-common.TemplateListItem._kbnMeta", diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 84ce30e93ad1e..3a768e9967fb3 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 223 | 0 | 218 | 4 | +| 224 | 0 | 219 | 4 | ## Client diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 4f031fef2daf0..0ec57d3bcd354 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-02-08 +date: 2024-02-09 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 1e230e88c34f0..ae98136b761f6 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-02-08 +date: 2024-02-09 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 2df6572eec141..853138009d5b5 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index e8dd04b37bde9..08702c811890d 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 1f8f965aae613..f91d33074701f 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 0763ecf7f78ca..5a78384eace86 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index c6126bde35517..4ca8e049e499e 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 2362583ae493e..455bafc674a7a 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index adae00f67b092..86710beeb4c81 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-02-08 +date: 2024-02-09 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_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 6cf39a09235b2..d57a7feb85b32 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-02-08 +date: 2024-02-09 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 dd559ffd26fe5..4183413afad5a 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-02-08 +date: 2024-02-09 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 0808269e690c2..1fc684bd544bc 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 4456a7af94562..0ba0b2620abb2 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-02-08 +date: 2024-02-09 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 2c154af34afe2..bb46d2676e515 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 3a3ddaf341bb6..9a8c352cc395e 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 938d7d35faf27..cd1d33b6ffd8e 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 6429e4fd664f6..54b348796dd46 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 1dd782b9c7090..20073dce81e16 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 7dfc5486d4500..e0ef711289a41 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 96aa885356288..e320a6b3510f8 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index ed1531ec2001b..7b43a1afd58fc 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 3e1e47dfb25ef..a37531a769212 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-02-08 +date: 2024-02-09 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 25d3e9cc79ec3..557ba7d958a56 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 0ac7a3a59f241..04080a1dc6294 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index f75fe45564b3b..a0f0b3ea219ba 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-02-08 +date: 2024-02-09 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 d46de8af8627c..a57184782862a 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-02-08 +date: 2024-02-09 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 602a8996070c3..2a00f975cc1b8 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-02-08 +date: 2024-02-09 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 f861e1c0050c4..620fe0d81ee7a 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-02-08 +date: 2024-02-09 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 1767a5304bdc0..d409d4dff41ee 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 1ec35fd6fe8f5..1ea558d1c0fe0 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-02-08 +date: 2024-02-09 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 b771c0d3d6920..298730948f679 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-02-08 +date: 2024-02-09 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 cd2a38645c91e..c6742a81d759c 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-02-08 +date: 2024-02-09 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 0b55255cef877..4d9b4ddb42cdb 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-02-08 +date: 2024-02-09 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 58fb180401961..5c7538b48e25f 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-02-08 +date: 2024-02-09 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 b9335f88725a8..7853d329c44cd 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-02-08 +date: 2024-02-09 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 c9c712c09b190..c0d42c521e8ae 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 320fcdf6a12d8..d2bf8edbb215d 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-02-08 +date: 2024-02-09 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 6353e16c8bcfa..9e1d5657ac9ee 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-02-08 +date: 2024-02-09 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 b500748561914..771065ee21a7a 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.devdocs.json b/api_docs/kbn_coloring.devdocs.json index 64eb4e83e7721..16719bc0c8a0e 100644 --- a/api_docs/kbn_coloring.devdocs.json +++ b/api_docs/kbn_coloring.devdocs.json @@ -486,7 +486,9 @@ "ColorCode", " | ", "GradientColor", - ", getPaletteFn: (paletteId: string) => ", + " | (", + "LoopColor", + " & { paletteId: string; colorIndex: number; }), getPaletteFn: (paletteId: string) => ", "CategoricalPalette", ", isDarkMode: boolean, index: number, total: number) => string" ], @@ -523,7 +525,10 @@ " | ", "ColorCode", " | ", - "GradientColor" + "GradientColor", + " | (", + "LoopColor", + " & { paletteId: string; colorIndex: number; })" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts", "deprecated": false, @@ -607,7 +612,9 @@ "CategoricalColor", " | ", "ColorCode", - ", getPaletteFn: (paletteId: string) => ", + " | (", + "LoopColor", + " & { paletteId: string; colorIndex: number; }), getPaletteFn: (paletteId: string) => ", "CategoricalPalette", ", isDarkMode: boolean) => string" ], @@ -625,7 +632,10 @@ "signature": [ "CategoricalColor", " | ", - "ColorCode" + "ColorCode", + " | (", + "LoopColor", + " & { paletteId: string; colorIndex: number; })" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/color/color_handling.ts", "deprecated": false, @@ -708,7 +718,7 @@ "label": "getColorFactory", "description": [], "signature": [ - "(model: ", + "({ assignments, specialAssignments, colorMode, paletteId }: ", "Config", ", getPaletteFn: (paletteId: string) => ", "CategoricalPalette", @@ -731,7 +741,7 @@ "id": "def-common.getColorFactory.$1", "type": "Object", "tags": [], - "label": "model", + "label": "{ assignments, specialAssignments, colorMode, paletteId }", "description": [], "signature": [ "Config" @@ -2892,6 +2902,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_OTHER_ASSIGNMENT_INDEX", + "type": "number", + "tags": [], + "label": "DEFAULT_OTHER_ASSIGNMENT_INDEX", + "description": [], + "signature": [ + "0" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/coloring", "id": "def-common.DEFAULT_PALETTE_NAME", @@ -3113,20 +3138,6 @@ "deprecated": false, "trackAdoption": false, "children": [ - { - "parentPluginId": "@kbn/coloring", - "id": "def-common.DEFAULT_COLOR_MAPPING_CONFIG.assignmentMode", - "type": "string", - "tags": [], - "label": "assignmentMode", - "description": [], - "signature": [ - "\"auto\"" - ], - "path": "packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "@kbn/coloring", "id": "def-common.DEFAULT_COLOR_MAPPING_CONFIG.assignments", @@ -3149,7 +3160,7 @@ "label": "specialAssignments", "description": [], "signature": [ - "{ rule: { type: \"other\"; }; color: { type: \"categorical\"; paletteId: string; colorIndex: number; }; touched: false; }[]" + "{ rule: { type: \"other\"; }; color: { type: \"loop\"; }; touched: false; }[]" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/config/default_color_mapping.ts", "deprecated": false, @@ -3262,7 +3273,7 @@ "label": "getColor", "description": [], "signature": [ - "(valueInRange: number) => string" + "(indexInRange: number, isDarkMode: boolean, loop: boolean) => string" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts", "deprecated": false, @@ -3273,7 +3284,7 @@ "id": "def-common.ElasticBrandPalette.getColor.$1", "type": "number", "tags": [], - "label": "valueInRange", + "label": "indexInRange", "description": [], "signature": [ "number" @@ -3282,6 +3293,36 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ElasticBrandPalette.getColor.$2", + "type": "boolean", + "tags": [], + "label": "isDarkMode", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ElasticBrandPalette.getColor.$3", + "type": "boolean", + "tags": [], + "label": "loop", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/elastic_brand.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -3355,7 +3396,7 @@ "label": "getColor", "description": [], "signature": [ - "(valueInRange: number) => string" + "(indexInRange: number, isDarkMode: boolean, loop: boolean) => string" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts", "deprecated": false, @@ -3366,7 +3407,7 @@ "id": "def-common.EUIAmsterdamColorBlindPalette.getColor.$1", "type": "number", "tags": [], - "label": "valueInRange", + "label": "indexInRange", "description": [], "signature": [ "number" @@ -3375,6 +3416,36 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.EUIAmsterdamColorBlindPalette.getColor.$2", + "type": "boolean", + "tags": [], + "label": "isDarkMode", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.EUIAmsterdamColorBlindPalette.getColor.$3", + "type": "boolean", + "tags": [], + "label": "loop", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/eui_amsterdam.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -3448,7 +3519,7 @@ "label": "getColor", "description": [], "signature": [ - "(valueInRange: number) => string" + "(indexInRange: number, isDarkMode: boolean, loop: boolean) => string" ], "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts", "deprecated": false, @@ -3459,7 +3530,7 @@ "id": "def-common.KibanaV7LegacyPalette.getColor.$1", "type": "number", "tags": [], - "label": "valueInRange", + "label": "indexInRange", "description": [], "signature": [ "number" @@ -3468,6 +3539,36 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.KibanaV7LegacyPalette.getColor.$2", + "type": "boolean", + "tags": [], + "label": "isDarkMode", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.KibanaV7LegacyPalette.getColor.$3", + "type": "boolean", + "tags": [], + "label": "loop", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-coloring/src/shared_components/color_mapping/palettes/kibana_legacy.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index f675651096bce..38598c5806820 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.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 | |-------------------|-----------|------------------------|-----------------| -| 211 | 0 | 174 | 8 | +| 217 | 0 | 180 | 9 | ## Common diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 352c9fbf5774d..98d8920cb1742 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-02-08 +date: 2024-02-09 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 b8fa2ab445158..d24ad40a1c4ab 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-02-08 +date: 2024-02-09 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 9bf2e8798378d..04f71faabdb8c 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-02-08 +date: 2024-02-09 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.devdocs.json b/api_docs/kbn_content_management_content_editor.devdocs.json index 63a1e49929db0..45ec5e84ec7c4 100644 --- a/api_docs/kbn_content_management_content_editor.devdocs.json +++ b/api_docs/kbn_content_management_content_editor.devdocs.json @@ -184,7 +184,7 @@ "signature": [ "{ onSave?: ((args: { id: string; title: string; description?: string | undefined; tags: string[]; }) => Promise) | undefined; item: ", "Item", - "; isReadonly?: boolean | undefined; entityName: string; customValidators?: ", + "; isReadonly?: boolean | undefined; readonlyReason?: string | undefined; entityName: string; customValidators?: ", "CustomValidators", " | undefined; }" ], diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 288b0cd8429f2..32d4045f30fd2 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 83f0afa466430..f70c70ab7759f 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-02-08 +date: 2024-02-09 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.devdocs.json b/api_docs/kbn_content_management_table_list_view.devdocs.json index 6710f11d5bd94..99b7b1265d65d 100644 --- a/api_docs/kbn_content_management_table_list_view.devdocs.json +++ b/api_docs/kbn_content_management_table_list_view.devdocs.json @@ -19,7 +19,7 @@ "section": "def-common.UserContentCommonSchema", "text": "UserContentCommonSchema" }, - ">({ title, description, entityName, entityNamePlural, initialFilter, headingId, initialPageSize, listingLimit, urlStateEnabled, customTableColumn, emptyPrompt, findItems, createItem, editItem, deleteItems, getDetailViewLink, onClickTitle, rowItemActions, id: listingId, contentEditor, children, titleColumnName, additionalRightSideActions, withoutPageTemplateWrapper, itemIsEditable, }: ", + ">({ title, description, entityName, entityNamePlural, initialFilter, headingId, initialPageSize, listingLimit, urlStateEnabled, customTableColumn, emptyPrompt, findItems, createItem, editItem, deleteItems, getDetailViewLink, onClickTitle, rowItemActions, id: listingId, contentEditor, children, titleColumnName, additionalRightSideActions, withoutPageTemplateWrapper, }: ", { "pluginId": "@kbn/content-management-table-list-view", "scope": "public", @@ -38,7 +38,7 @@ "id": "def-public.TableListView.$1", "type": "CompoundType", "tags": [], - "label": "{\n title,\n description,\n entityName,\n entityNamePlural,\n initialFilter,\n headingId,\n initialPageSize,\n listingLimit,\n urlStateEnabled = true,\n customTableColumn,\n emptyPrompt,\n findItems,\n createItem,\n editItem,\n deleteItems,\n getDetailViewLink,\n onClickTitle,\n rowItemActions,\n id: listingId,\n contentEditor,\n children,\n titleColumnName,\n additionalRightSideActions,\n withoutPageTemplateWrapper,\n itemIsEditable,\n}", + "label": "{\n title,\n description,\n entityName,\n entityNamePlural,\n initialFilter,\n headingId,\n initialPageSize,\n listingLimit,\n urlStateEnabled = true,\n customTableColumn,\n emptyPrompt,\n findItems,\n createItem,\n editItem,\n deleteItems,\n getDetailViewLink,\n onClickTitle,\n rowItemActions,\n id: listingId,\n contentEditor,\n children,\n titleColumnName,\n additionalRightSideActions,\n withoutPageTemplateWrapper,\n}", "description": [], "signature": [ { @@ -79,7 +79,7 @@ "section": "def-public.TableListViewTableProps", "text": "TableListViewTableProps" }, - ", \"id\" | \"entityName\" | \"entityNamePlural\" | \"initialFilter\" | \"headingId\" | \"initialPageSize\" | \"listingLimit\" | \"urlStateEnabled\" | \"customTableColumn\" | \"emptyPrompt\" | \"findItems\" | \"createItem\" | \"editItem\" | \"deleteItems\" | \"getDetailViewLink\" | \"onClickTitle\" | \"rowItemActions\" | \"contentEditor\" | \"titleColumnName\" | \"withoutPageTemplateWrapper\" | \"itemIsEditable\"> & { title: string; description?: string | undefined; additionalRightSideActions?: React.ReactNode[] | undefined; children?: React.ReactNode; }" + ", \"id\" | \"entityName\" | \"entityNamePlural\" | \"initialFilter\" | \"headingId\" | \"initialPageSize\" | \"listingLimit\" | \"urlStateEnabled\" | \"customTableColumn\" | \"emptyPrompt\" | \"findItems\" | \"createItem\" | \"editItem\" | \"deleteItems\" | \"getDetailViewLink\" | \"onClickTitle\" | \"rowItemActions\" | \"contentEditor\" | \"titleColumnName\" | \"withoutPageTemplateWrapper\"> & { title: string; description?: string | undefined; additionalRightSideActions?: React.ReactNode[] | undefined; children?: React.ReactNode; }" ], "path": "packages/content-management/table_list_view/src/table_list_view.tsx", "deprecated": false, diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 29e3e3fb6e9de..a03dfbcadec25 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-02-08 +date: 2024-02-09 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 3caf4dedb360d..fb71a63ef5225 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-02-08 +date: 2024-02-09 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.devdocs.json b/api_docs/kbn_content_management_table_list_view_table.devdocs.json index a35fd912e140e..218d6016ccdee 100644 --- a/api_docs/kbn_content_management_table_list_view_table.devdocs.json +++ b/api_docs/kbn_content_management_table_list_view_table.devdocs.json @@ -109,7 +109,7 @@ "section": "def-common.UserContentCommonSchema", "text": "UserContentCommonSchema" }, - ">({ tableCaption, entityName, entityNamePlural, initialFilter: initialQuery, headingId, initialPageSize, listingLimit, urlStateEnabled, customTableColumn, emptyPrompt, rowItemActions, findItems, createItem, editItem, itemIsEditable, deleteItems, getDetailViewLink, onClickTitle, id: listingId, contentEditor, titleColumnName, withoutPageTemplateWrapper, onFetchSuccess, refreshListBouncer, setPageDataTestSubject, }: ", + ">({ tableCaption, entityName, entityNamePlural, initialFilter: initialQuery, headingId, initialPageSize, listingLimit, urlStateEnabled, customTableColumn, emptyPrompt, rowItemActions, findItems, createItem, editItem, deleteItems, getDetailViewLink, onClickTitle, id: listingId, contentEditor, titleColumnName, withoutPageTemplateWrapper, onFetchSuccess, refreshListBouncer, setPageDataTestSubject, }: ", { "pluginId": "@kbn/content-management-table-list-view-table", "scope": "public", @@ -775,40 +775,6 @@ ], "returnComment": [] }, - { - "parentPluginId": "@kbn/content-management-table-list-view-table", - "id": "def-public.TableListViewTableProps.itemIsEditable", - "type": "Function", - "tags": [], - "label": "itemIsEditable", - "description": [ - "\nHandler to set edit action visiblity, and content editor readonly state per item. If not provided all non-managed items are considered editable. Note: Items with the managed property set to true will always be non-editable." - ], - "signature": [ - "((item: T) => boolean) | undefined" - ], - "path": "packages/content-management/table_list_view_table/src/table_list_view_table.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/content-management-table-list-view-table", - "id": "def-public.TableListViewTableProps.itemIsEditable.$1", - "type": "Uncategorized", - "tags": [], - "label": "item", - "description": [], - "signature": [ - "T" - ], - "path": "packages/content-management/table_list_view_table/src/table_list_view_table.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, { "parentPluginId": "@kbn/content-management-table-list-view-table", "id": "def-public.TableListViewTableProps.titleColumnName", @@ -961,7 +927,7 @@ "label": "RowActions", "description": [], "signature": [ - "{ delete?: { enabled: boolean; reason?: string | undefined; } | undefined; }" + "{ delete?: { enabled: boolean; reason?: string | undefined; } | undefined; edit?: { enabled: boolean; reason?: string | undefined; } | undefined; }" ], "path": "packages/content-management/table_list_view_table/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 43b3aa976cf31..34dd186d926a8 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 52 | 0 | 34 | 3 | +| 50 | 0 | 33 | 3 | ## Client diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 0f4c9036bee49..549bb2feb6b94 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 5c4feb84eb1ba..3926d5e25fed3 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-02-08 +date: 2024-02-09 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 07136a907a3bf..3215bb87f5926 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-02-08 +date: 2024-02-09 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 63258f3c47d15..721124b4b77fc 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 695d28c0134d8..f0f6680eb7959 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-02-08 +date: 2024-02-09 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 a2b32db67bddb..a032d14985995 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-02-08 +date: 2024-02-09 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 244fcfaf34db5..e0fecfbb149e7 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-02-08 +date: 2024-02-09 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 39ee36437db30..ad08f59c4f9cc 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-02-08 +date: 2024-02-09 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 78467a9be966a..2da9061231c2c 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-02-08 +date: 2024-02-09 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 c943b2ba31290..9a31b8d50eb72 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-02-08 +date: 2024-02-09 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 9c6a61750d08a..fcf53dae6e5f8 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-02-08 +date: 2024-02-09 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 925f06201ac93..9ab432d212789 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-02-08 +date: 2024-02-09 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 007e706834014..ece12e4c90739 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-02-08 +date: 2024-02-09 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 822678a4634ca..36256d83d3945 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-02-08 +date: 2024-02-09 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 de1c6e41bde19..78712eef526ae 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-02-08 +date: 2024-02-09 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 487ca8516e901..179383d10382f 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-02-08 +date: 2024-02-09 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 8f3d657ed031f..9431b2fd4e656 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-02-08 +date: 2024-02-09 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 13aaee49fb3d6..e9aaaee4327bd 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-02-08 +date: 2024-02-09 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 87400852bf5ba..a188198b4e65a 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-02-08 +date: 2024-02-09 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 155e3d1ab32c1..c52b13ffc8c48 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-02-08 +date: 2024-02-09 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 cf9a67511dbd2..2e5d216f9a75c 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-02-08 +date: 2024-02-09 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 29018e77c93a7..f71762235774c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 7e248c277a53a..59e557067b445 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-02-08 +date: 2024-02-09 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 c11368f3af3d9..88537178c2361 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-02-08 +date: 2024-02-09 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 4ae9332297a09..741948997874d 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-02-08 +date: 2024-02-09 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 2facaddb22fdc..b134ded6593c1 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-02-08 +date: 2024-02-09 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 ab719f09e2c63..86f6394a55002 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-02-08 +date: 2024-02-09 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 b2f84279964e6..05043323e4a66 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-02-08 +date: 2024-02-09 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 d70220d140f0e..037d8f6cd1264 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-02-08 +date: 2024-02-09 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 5d8aa78a7d4a6..db199721b502d 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-02-08 +date: 2024-02-09 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 6007871fbeb4f..91b14abb2b14e 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-02-08 +date: 2024-02-09 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 b12a9b9373f49..de58bc1a17dee 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-02-08 +date: 2024-02-09 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 fc28e7abd3ced..db905326022ba 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-02-08 +date: 2024-02-09 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 d8e9e2e70cb95..6b2428410abf4 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-02-08 +date: 2024-02-09 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 06793bda57298..28ef5672af61c 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-02-08 +date: 2024-02-09 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 97b6a368d6205..df802ff949c9e 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-02-08 +date: 2024-02-09 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 06a9e3bc8b2aa..36fecd26abcf3 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-02-08 +date: 2024-02-09 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 484362bc9717c..39779844c22de 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-02-08 +date: 2024-02-09 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 2b1496836fd14..f89980ad40395 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-02-08 +date: 2024-02-09 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 da4db3f2e5a39..ed53110d28841 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-02-08 +date: 2024-02-09 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 4deae23e311bb..acb646eb7df7d 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-02-08 +date: 2024-02-09 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 a96a8402e95b2..ad742f24447d6 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-02-08 +date: 2024-02-09 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 7dafc9670937a..3df137049f5cf 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-02-08 +date: 2024-02-09 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 00e21b7c8c4cd..46f0408843556 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-02-08 +date: 2024-02-09 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 61096379c1a35..74b7d2a56b9c6 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-02-08 +date: 2024-02-09 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 914a607ba4510..7a74e136b28b2 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-02-08 +date: 2024-02-09 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 f9b7fc07ef57f..0684ee5f25010 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-02-08 +date: 2024-02-09 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 f45c0e2ba281b..1c1311a46cf70 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-02-08 +date: 2024-02-09 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 fe2b0d418efe9..4fccd42c66a51 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-02-08 +date: 2024-02-09 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 de245988d874d..49729176401fe 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-02-08 +date: 2024-02-09 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 2e24c70d937cc..eec37cda36f8c 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-02-08 +date: 2024-02-09 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 3eeefff838d59..d5f6f29f47082 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-02-08 +date: 2024-02-09 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 6aa09d853c97b..6e28ddfdcb30b 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-02-08 +date: 2024-02-09 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 74f788fde9c4a..169e776b9b921 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-02-08 +date: 2024-02-09 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 4d9bad9a99e2a..6488421234530 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-02-08 +date: 2024-02-09 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 f3bcc14e633c8..5679ce0a19b48 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-02-08 +date: 2024-02-09 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 5fc3117502e5c..3eef2e014d239 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-02-08 +date: 2024-02-09 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 1627580848aa5..b181e9e577e90 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-02-08 +date: 2024-02-09 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 df4b66973facb..4909257a2057f 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index a612f81fdcfd3..96127c88f1674 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-02-08 +date: 2024-02-09 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 f2e5236be83a0..c44ce193a5555 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-02-08 +date: 2024-02-09 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 f6eee4cf9a021..155d3a416f6d5 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-02-08 +date: 2024-02-09 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 c376893e3d624..26de513980693 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-02-08 +date: 2024-02-09 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 b362fe116e723..07f0b3a64377b 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-02-08 +date: 2024-02-09 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 eeb0f260e6409..0ea61e132a342 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-02-08 +date: 2024-02-09 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 d26c55f0fb0df..38c7833b394b7 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-02-08 +date: 2024-02-09 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 21c62de395267..6973f29ce606b 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-02-08 +date: 2024-02-09 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 d211d7411945e..ba0f75ac4ff7e 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-02-08 +date: 2024-02-09 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 4250092d3f05a..090643b7a3add 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-02-08 +date: 2024-02-09 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 08f56b9a1ac97..7db0224162ae7 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-02-08 +date: 2024-02-09 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 230ca9ab5e1f1..a7075e5be6a9f 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -14860,6 +14860,10 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts" }, + { + "plugin": "dataVisualizer", + "path": "x-pack/plugins/data_visualizer/server/routes.ts" + }, { "plugin": "ecsDataQualityDashboard", "path": "x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_unallowed_field_values.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 12f1edda40a9e..164d8a2f63807 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-02-08 +date: 2024-02-09 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 82af6b2aefb75..06ba81eb1e681 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-02-08 +date: 2024-02-09 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 b2ae7d0501047..838b18e3259ad 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-02-08 +date: 2024-02-09 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 fbfeee4e498df..fbea4395a9efa 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-02-08 +date: 2024-02-09 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 07d9ee7b67473..d39c5b096f786 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-02-08 +date: 2024-02-09 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 18fa18602d6a1..3f6c3f7513069 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-02-08 +date: 2024-02-09 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 850d7e006f30f..0fe3e0bd9dbe0 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-02-08 +date: 2024-02-09 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 0972b169c5a25..305abf2116b7f 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-02-08 +date: 2024-02-09 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 2b50f03d992a4..121fc65b893f8 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-02-08 +date: 2024-02-09 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 42b46c147d31e..af5ce48ece29c 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-02-08 +date: 2024-02-09 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 44c1b89989262..61c681743d11c 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-02-08 +date: 2024-02-09 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 e36ba5bb25295..6aa40c5376992 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-02-08 +date: 2024-02-09 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 08f8b2d90a84f..644d4785a4068 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-02-08 +date: 2024-02-09 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 f627928546900..17e9f15ce7541 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-02-08 +date: 2024-02-09 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 8189b61131732..3e5a308d98c4a 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-02-08 +date: 2024-02-09 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 a59624cb0fd83..38f1ce3e8da21 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-02-08 +date: 2024-02-09 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 2c3e194d00012..baa95ebf354d9 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-02-08 +date: 2024-02-09 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 0032ef1fd1c51..fe99caeafa0d9 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-02-08 +date: 2024-02-09 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 fffc8316e29ef..f1d3d0bcfe842 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-02-08 +date: 2024-02-09 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 a7649ca3c12c4..79dc33320d520 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-02-08 +date: 2024-02-09 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 cb58b91d8279b..3b55b56aa9a2d 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-02-08 +date: 2024-02-09 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 a540b9c91e0fe..cdf2cd510154f 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-02-08 +date: 2024-02-09 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 e864cb1853d72..39bdac22a4417 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-02-08 +date: 2024-02-09 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 f1e1c04e375f0..ad81b9d80215e 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-02-08 +date: 2024-02-09 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 9149c2a0260ce..1b8ba4628c55c 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-02-08 +date: 2024-02-09 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 28b259f64a7e0..6e9fd81c053eb 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-02-08 +date: 2024-02-09 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 c5f37a08e2077..5dec14f1bcdf3 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-02-08 +date: 2024-02-09 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 d8c4209967acd..c6979b3c692c6 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-02-08 +date: 2024-02-09 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 29c98e37a41b4..135648aa4ca1e 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-02-08 +date: 2024-02-09 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 4942c22792c4b..13530b487ca38 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-02-08 +date: 2024-02-09 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 183059e2b9c44..ca94dd5d0dbf4 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-02-08 +date: 2024-02-09 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 65d79f76f326b..be8ce3c257010 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-02-08 +date: 2024-02-09 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 f14305177173d..51697b434c7c0 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-02-08 +date: 2024-02-09 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 68fbe4722aa42..0dc144b888cf2 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-02-08 +date: 2024-02-09 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 de475e9439f19..cdc66b902f4d7 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-02-08 +date: 2024-02-09 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 aa25bdb614f52..7f2e4c0092d01 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-02-08 +date: 2024-02-09 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 c40f4014e7dee..628e2a2271362 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-02-08 +date: 2024-02-09 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 dce50c7b8d4b4..9c71bbfcf8020 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-02-08 +date: 2024-02-09 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 a4994bb77f7cf..fdeefddaa5224 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-02-08 +date: 2024-02-09 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 773b22d72fcd4..57ff37290f3b9 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-02-08 +date: 2024-02-09 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 2fc858e27c4e1..0ccc818ea2b74 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-02-08 +date: 2024-02-09 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 02bff0d8eb5ba..ca5c6fede86a6 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-02-08 +date: 2024-02-09 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 37b5fc25c742d..82f332ce95c36 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-02-08 +date: 2024-02-09 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 8b50f4429447b..e5930f159137f 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-02-08 +date: 2024-02-09 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 34f73f83f0084..ca862bafd9098 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-02-08 +date: 2024-02-09 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 7e1df39b46b9e..d94caa14c08e7 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-02-08 +date: 2024-02-09 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 1cef382393e48..6bc07bde6e37d 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-02-08 +date: 2024-02-09 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 c2f86bc71c50a..b3cb7976fd1b8 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-02-08 +date: 2024-02-09 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 849a6191f315c..b9b8fb0061e11 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-02-08 +date: 2024-02-09 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 a2414bf2257d1..a0881f056f5a8 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-02-08 +date: 2024-02-09 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 a9556624a28db..d0292510f0938 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-02-08 +date: 2024-02-09 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 e819f6d63ee60..dd046a7eb50b8 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-02-08 +date: 2024-02-09 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 72d3e66799c0e..d0371c3351ea3 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-02-08 +date: 2024-02-09 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 dde0423a7b1f0..19e1ecdf93383 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-02-08 +date: 2024-02-09 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 fb21471738800..438065b0806bd 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-02-08 +date: 2024-02-09 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 8f585e5ef712f..5b062b88dc643 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-02-08 +date: 2024-02-09 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 fdc82f9342200..110326acbce69 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-02-08 +date: 2024-02-09 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 1de73758515db..bbb694f4aab14 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-02-08 +date: 2024-02-09 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 d4a1266600e85..de9470a5565a7 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-02-08 +date: 2024-02-09 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 75ddbd88cf648..a190ee5a379e1 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-02-08 +date: 2024-02-09 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 cce430fed1399..a746d4ba451ae 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-02-08 +date: 2024-02-09 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 72f69ff5d1f65..7bc2b8c957867 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-02-08 +date: 2024-02-09 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 471aff347ea74..41e3e34710bd1 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-02-08 +date: 2024-02-09 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 512129b09266e..4dc9d755faf02 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 5b8d798c407d0..649a6ffb06e95 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-02-08 +date: 2024-02-09 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.devdocs.json b/api_docs/kbn_core_status_common_internal.devdocs.json index 819813f5db06c..6128be9e72179 100644 --- a/api_docs/kbn_core_status_common_internal.devdocs.json +++ b/api_docs/kbn_core_status_common_internal.devdocs.json @@ -75,6 +75,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/core-status-common-internal", + "id": "def-common.ServerVersion.build_flavor", + "type": "CompoundType", + "tags": [], + "label": "build_flavor", + "description": [], + "signature": [ + "\"serverless\" | \"traditional\"" + ], + "path": "packages/core/status/core-status-common-internal/src/status.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/core-status-common-internal", "id": "def-common.ServerVersion.build_date", diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index cce9d26f94913..637e6dfb7dbac 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 20 | 0 | 19 | 0 | +| 21 | 0 | 20 | 0 | ## Common diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index 7fd60d80240de..10da6e76e9204 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-02-08 +date: 2024-02-09 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 463681e928ae6..aa23dbbc647a6 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-02-08 +date: 2024-02-09 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 dce6072b82290..4b4b87fb68cb6 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-02-08 +date: 2024-02-09 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 99627f59d3149..4b90da9f68263 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-02-08 +date: 2024-02-09 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 346820e660d43..c73e5ec0d18a4 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-02-08 +date: 2024-02-09 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 552509037b92f..4840d82595729 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-02-08 +date: 2024-02-09 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 8adfff27843f4..4c041e86ae8be 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-02-08 +date: 2024-02-09 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 3c59ed1ca2557..e2615cea23202 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-02-08 +date: 2024-02-09 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 a97bf61389c41..31d8fdb184af5 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-02-08 +date: 2024-02-09 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 47bd2019d6f23..219afd3592a34 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-02-08 +date: 2024-02-09 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 546aa1e3ad155..7b5f61237f6b3 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-02-08 +date: 2024-02-09 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 445a4607c33b7..81678e0102d2b 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-02-08 +date: 2024-02-09 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 bdc5bac248b26..fbfe4a6552b0a 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-02-08 +date: 2024-02-09 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 065d2b61009fd..c9db37f430de7 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-02-08 +date: 2024-02-09 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 fa9458171836b..4bf085ebc208b 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-02-08 +date: 2024-02-09 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 2424aa3084e03..4a389f2898ae4 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-02-08 +date: 2024-02-09 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 5519d8549a24d..d424d2962ab17 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-02-08 +date: 2024-02-09 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 0b9921e8b4b8e..efe4f84af141c 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-02-08 +date: 2024-02-09 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 d49d7904218a5..93c4d56f40bde 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-02-08 +date: 2024-02-09 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 0326c774328d4..bf6ebbdfd47ed 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-02-08 +date: 2024-02-09 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 e740880bd1efa..97389e4d22d49 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index b5b1ce3403713..5b4115cac027c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 32551520e4e30..75cdce9b521fb 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 9c9d4ff2d66c9..6f56a7755e053 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-02-08 +date: 2024-02-09 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 52f35791bc0d8..4715f12fc898f 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-02-08 +date: 2024-02-09 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 2b1aca5dd33a1..bbcb348c42f2f 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-02-08 +date: 2024-02-09 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 d68ec3c8684c4..57e748d0e694f 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-02-08 +date: 2024-02-09 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 c434cfaa99173..d50514650aea1 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-02-08 +date: 2024-02-09 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 44523ffdea60f..18d7e6c7c8cf1 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-02-08 +date: 2024-02-09 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 f0f5bcc9a6ab8..6f339d1160567 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-02-08 +date: 2024-02-09 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 7bcd2e0327054..e4d95b99fe97d 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-02-08 +date: 2024-02-09 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 a34fb29fe90da..9ad6e7f84fef9 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-02-08 +date: 2024-02-09 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 28e39104f298c..974f54465d54e 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-02-08 +date: 2024-02-09 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 6ff71cdf16d4a..d3adf40c8b6b3 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-02-08 +date: 2024-02-09 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 00cc1d8fbbb53..4889f73413526 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-02-08 +date: 2024-02-09 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 325a4b8832556..6e955779ed799 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index b9ac7bcaf6310..e7dfe6c394eec 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-02-08 +date: 2024-02-09 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 5ff4c557a9c95..5f1e20e5f7a75 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-02-08 +date: 2024-02-09 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 679ebd3a0add7..7f56fac1bf2f7 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index ad3405da94a4b..0dd14ff590145 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 4e1e2c5a71ea0..bf24f7bda0859 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-02-08 +date: 2024-02-09 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 e41a566fe8330..644a61188b0c6 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-02-08 +date: 2024-02-09 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 81289dd94896f..d7d9e2cfc5b90 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-02-08 +date: 2024-02-09 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 e6780c0a641ee..596b634de26e9 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-02-08 +date: 2024-02-09 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 52f072784425e..c10b7d64cc687 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-02-08 +date: 2024-02-09 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 e0ca875007e2d..f6872868fc1b5 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-02-08 +date: 2024-02-09 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 6ee34d508a935..fee77dc627bc7 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-02-08 +date: 2024-02-09 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 e2300f64cec1f..9a121b7f37f1d 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index a294b1b364648..23b0fcf2d7472 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-02-08 +date: 2024-02-09 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 6c0133256e1a6..dacdafd0d7933 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-02-08 +date: 2024-02-09 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 5563163397c3f..832fd32f4c0e3 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-02-08 +date: 2024-02-09 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 e561046d0a619..433c22857f16a 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-02-08 +date: 2024-02-09 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 6a4d8f5d5c467..3e71821e69440 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index e55daa4491bd5..340b7a8f82eea 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 0dbf96f3bb33a..0019af3c0b3e3 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-02-08 +date: 2024-02-09 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 1938fa33966bf..3c343b5e649da 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-02-08 +date: 2024-02-09 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 51f32807cd412..6a715ffc42ee8 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-02-08 +date: 2024-02-09 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 0042f37af440d..6845221fe0690 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 6d5ec7bcc31ea..9e4242719e17c 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-02-08 +date: 2024-02-09 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 0c03444a4d58d..dfaee0807c644 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-02-08 +date: 2024-02-09 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 7fed094aab4ea..1670a936a123d 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-02-08 +date: 2024-02-09 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 53a9a212ec39f..7bc0a39300a47 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 43511f9acdd78..82ac58554ea3a 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-02-08 +date: 2024-02-09 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 63f4eb4749b36..a182a48b1df15 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-02-08 +date: 2024-02-09 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_utils.mdx b/api_docs/kbn_esql_utils.mdx index 9c9bdd7bb241b..b7d1ae017993f 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index d7d786256db97..ae04a3e63b504 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-02-08 +date: 2024-02-09 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 fda3348004c8d..a50b28c3fd8bc 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-02-08 +date: 2024-02-09 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 4363ed3e4e425..6830e740cb539 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-02-08 +date: 2024-02-09 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 0218d7f7eaded..9b698333817f8 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-02-08 +date: 2024-02-09 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 b3bfd9889784f..860dac5479cef 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-02-08 +date: 2024-02-09 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 57f1805355cf4..3a86c1288dca9 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 68f5fc6d85cc9..e43f17049f58c 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-02-08 +date: 2024-02-09 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 eab2893cc20ce..f6e883fc5fc30 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-02-08 +date: 2024-02-09 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 d51ef4b1f2f9f..0c691111495b9 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-02-08 +date: 2024-02-09 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 65a4dd253a177..81303fb5bfdb5 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-02-08 +date: 2024-02-09 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 b5ad08a5e6b67..f57873ff5cc13 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 86cf924d9594a..f58d0a99cc952 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-02-08 +date: 2024-02-09 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 873becaaa3c6d..e31d2633e8caf 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-02-08 +date: 2024-02-09 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 a58b35e04ece3..8f5ea622d0c23 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-02-08 +date: 2024-02-09 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 0e97adc32653c..3b7917c4114f9 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-02-08 +date: 2024-02-09 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 065be3e64ed6f..5e1c688419154 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-02-08 +date: 2024-02-09 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 ccf93e82a0582..724597fb023b8 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-02-08 +date: 2024-02-09 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 5a53175fa1945..aa1d392350d5c 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-02-08 +date: 2024-02-09 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 66fc7bb0560f3..54761ab07b92a 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-02-08 +date: 2024-02-09 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 1e39fcce2541b..e10b74b3a9ea4 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index aab201a3c8563..9453bed176fe7 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-02-08 +date: 2024-02-09 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 012bb189e5ff8..80081f5a58c47 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 0f8b980a24240..abd58762cf676 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 132d9f355ee3d..ea92d30647b04 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-02-08 +date: 2024-02-09 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 3cd69c0fc4342..f5453250cae94 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-02-08 +date: 2024-02-09 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 3bcf9f12b6e30..acb470ccf8bbf 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index ed78d6a9512fb..3ce69024d5af7 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.devdocs.json b/api_docs/kbn_language_documentation_popover.devdocs.json index d15c3a47f0f0b..19da7e82a44df 100644 --- a/api_docs/kbn_language_documentation_popover.devdocs.json +++ b/api_docs/kbn_language_documentation_popover.devdocs.json @@ -27,7 +27,7 @@ "label": "LanguageDocumentationPopover", "description": [], "signature": [ - "React.NamedExoticComponent & { readonly type: ({ language, sections, buttonProps, searchInDescription, }: DocumentationPopoverProps) => JSX.Element; }" + "React.NamedExoticComponent & { readonly type: ({ language, sections, buttonProps, searchInDescription, linkToDocumentation, }: DocumentationPopoverProps) => JSX.Element; }" ], "path": "packages/kbn-language-documentation-popover/src/components/documentation_popover.tsx", "deprecated": false, @@ -59,7 +59,7 @@ "label": "LanguageDocumentationPopoverContent", "description": [], "signature": [ - "React.NamedExoticComponent & { readonly type: ({ language, sections, searchInDescription }: DocumentationProps) => JSX.Element; }" + "React.NamedExoticComponent & { readonly type: ({ language, sections, searchInDescription, linkToDocumentation, }: DocumentationProps) => JSX.Element; }" ], "path": "packages/kbn-language-documentation-popover/src/components/documentation_content.tsx", "deprecated": false, diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index cb325cbe392e7..a9a23030bce58 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 46c888808ca1a..f895243486d91 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-02-08 +date: 2024-02-09 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 6f06e654f12ac..14d319659f955 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-02-08 +date: 2024-02-09 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 905c9ddcffe9e..c3e43c4d9eb07 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-02-08 +date: 2024-02-09 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 a228ab8dcffa2..9013c0a06c2af 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-02-08 +date: 2024-02-09 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 0a00ed61adf2c..6ce15ed5d3ba1 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-02-08 +date: 2024-02-09 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 376460cea2fa2..e2b0cb397ed18 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-02-08 +date: 2024-02-09 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 59c942dba2995..49fbd2bb35d4c 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-02-08 +date: 2024-02-09 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 85ea9b96d8256..54bcf7fe38852 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-02-08 +date: 2024-02-09 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 ff5d6dea8b50f..7b4191fd5c974 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-02-08 +date: 2024-02-09 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 90fb27b1e2bb9..09757628406a8 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-02-08 +date: 2024-02-09 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 edb11ca03ab36..c03b60b5dc8a8 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-02-08 +date: 2024-02-09 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 e9faba609ea93..356c59938594f 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-02-08 +date: 2024-02-09 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 a0dac7eb74904..67d4191caa010 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-02-08 +date: 2024-02-09 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.mdx b/api_docs/kbn_management_settings_ids.mdx index 6dd9c686a2139..5cbf2abc0637d 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index e10a606cfd471..c3f80eae37345 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-02-08 +date: 2024-02-09 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 6b3eda5d4d11e..d4a8c96a4a094 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-02-08 +date: 2024-02-09 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 0d06fa62e786f..3c4410b2d931a 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-02-08 +date: 2024-02-09 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 faa06e322f0c6..bd5d0d5def8cc 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 9756652261749..a80e8f0636d52 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-02-08 +date: 2024-02-09 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 f07b3f23721e8..91de893be38d5 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-02-08 +date: 2024-02-09 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 08ac74052b564..0b8e91eb61e57 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-02-08 +date: 2024-02-09 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.devdocs.json b/api_docs/kbn_ml_anomaly_utils.devdocs.json index f45552d3eb1bb..95a47b1ac3b0d 100644 --- a/api_docs/kbn_ml_anomaly_utils.devdocs.json +++ b/api_docs/kbn_ml_anomaly_utils.devdocs.json @@ -2378,6 +2378,22 @@ "path": "x-pack/packages/ml/anomaly_utils/anomaly_utils.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-anomaly-utils", + "id": "def-common.MlEntityField.cardinality", + "type": "number", + "tags": [], + "label": "cardinality", + "description": [ + "\nOptional cardinality of field" + ], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/ml/anomaly_utils/anomaly_utils.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 774067d7e36e4..74d8ea24672a3 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 206 | 3 | 1 | 0 | +| 207 | 3 | 1 | 0 | ## Common diff --git a/api_docs/kbn_ml_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index 4680fe1735266..0d186e4183b11 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-02-08 +date: 2024-02-09 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 0110e170d6d8c..edc7012c2448e 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-02-08 +date: 2024-02-09 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 36d705f16e8d5..428d38e28c5ff 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-02-08 +date: 2024-02-09 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 18b082154f11b..68eee9bd8281e 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-02-08 +date: 2024-02-09 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 285e171db74c1..1c6f0b034bd33 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-02-08 +date: 2024-02-09 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 176825dee4909..4dadf76fabd07 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-02-08 +date: 2024-02-09 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 96654663d2dea..68d3df41c4e93 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-02-08 +date: 2024-02-09 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 d510a01909ee2..d28ad43347891 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-02-08 +date: 2024-02-09 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_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index d8f360f77f5ed..aae6decdaf4fd 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-02-08 +date: 2024-02-09 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 c84ce256821d1..50c46a4d04dfc 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-02-08 +date: 2024-02-09 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 5d6af66f4ba23..290364bf33f4b 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-02-08 +date: 2024-02-09 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 7da63204ac6ad..1c29d414162fc 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-02-08 +date: 2024-02-09 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 a3bd012059125..925da237c7270 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-02-08 +date: 2024-02-09 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 391277b2a3e8e..c359f7cea57ec 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-02-08 +date: 2024-02-09 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 c4fdf69dcbd0d..42ad74d1ab9a6 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 182b27b80693a..e31fcd3eac71b 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-02-08 +date: 2024-02-09 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 ebb6a2c6a8288..7c41ac7618bcf 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-02-08 +date: 2024-02-09 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 817979a11aa55..6c2129a7b0056 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-02-08 +date: 2024-02-09 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 2ae01ab9f2ee5..90cdcf3ebdfad 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-02-08 +date: 2024-02-09 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 351b2223df9a1..9f23fd4b7a52e 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 071b1e8d92816..1ee0417cbafda 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-02-08 +date: 2024-02-09 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 f981f2a24364e..e7fae22d79324 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-02-08 +date: 2024-02-09 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 b46b1794d4dc6..d5b86983d2ce1 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 05675bd96a17d..42e1d77db95c9 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-02-08 +date: 2024-02-09 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 b5dcc8f0fedbb..46479d9620064 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-02-08 +date: 2024-02-09 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 c80254b71493d..cd3ad9877f2d4 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 47543a13fa62d..27cc471ac1dd9 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-02-08 +date: 2024-02-09 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_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 0d33b61044a5a..28ace32bbf314 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-02-08 +date: 2024-02-09 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 330ea9dfda1d7..4cb49328e1acc 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-02-08 +date: 2024-02-09 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_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 03c0bcf965fec..67b1a0995b9b5 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-02-08 +date: 2024-02-09 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 64095a40985f4..f96e4f7376401 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-02-08 +date: 2024-02-09 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 7567697ecd729..2fa8e11cfa5f3 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-02-08 +date: 2024-02-09 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 49238d50aae42..f15e1b04be33b 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-02-08 +date: 2024-02-09 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 94df5b5c4ffb5..3d98ef63326ec 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-02-08 +date: 2024-02-09 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 2acfa54ff357f..e7fe358e8f0e1 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-02-08 +date: 2024-02-09 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 94248a84fd64d..f691c9367f949 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-02-08 +date: 2024-02-09 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 8fa09593837ee..2edcef082754d 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-02-08 +date: 2024-02-09 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 a3f2320baff97..71acc06032cab 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-02-08 +date: 2024-02-09 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 3bcf0ddf1337d..956eb7cf98306 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-02-08 +date: 2024-02-09 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 3bd18d6afa2c9..1c9ee92a203dc 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_library.mdx b/api_docs/kbn_presentation_library.mdx index 6c622d763a4e7..75a6f0986e1ac 100644 --- a/api_docs/kbn_presentation_library.mdx +++ b/api_docs/kbn_presentation_library.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-library title: "@kbn/presentation-library" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-library plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-library'] --- import kbnPresentationLibraryObj from './kbn_presentation_library.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 7e7196d62bf2d..920475b2095d8 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 34f387cf84709..27cd3c7362bd7 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-02-08 +date: 2024-02-09 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 3f57ed02c9933..90d4eb015bd77 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-02-08 +date: 2024-02-09 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 3f790740f0cd1..3ab1b0e9664eb 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 486ef63511d1a..3e5624a9ba203 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-02-08 +date: 2024-02-09 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 fdf93464c5e05..9dcbe35e729ae 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-02-08 +date: 2024-02-09 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 57ae6ed612015..e1e320be960c9 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-02-08 +date: 2024-02-09 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 1d1c69c0d89d2..78cf3f5edab55 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-02-08 +date: 2024-02-09 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 280bff6ef8090..91ec11254eeba 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-02-08 +date: 2024-02-09 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 49bf6c3a2c3ac..fe5ecd360abc4 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index f0eaa388ddb2f..c7d9c52aa1bc0 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-02-08 +date: 2024-02-09 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 bd7cccacd1727..0e84c518a81da 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-02-08 +date: 2024-02-09 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 e9377fcac668f..c7e9953315746 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-02-08 +date: 2024-02-09 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 bd87e83a30dfa..0a688e60215c3 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-02-08 +date: 2024-02-09 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 762b1fecab40a..c6546d91721a9 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 91959d82f64b0..6f282553f9064 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-02-08 +date: 2024-02-09 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 c1962febea500..fd520d768996e 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-02-08 +date: 2024-02-09 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 376668862c72e..eeed542b7c4c3 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-02-08 +date: 2024-02-09 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 67e0f71c7c96d..58e5c952e70b4 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-02-08 +date: 2024-02-09 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 9b14ad11f446f..e1245c4fdde09 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-02-08 +date: 2024-02-09 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 391dde6c3a857..567d170dcf8ee 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-02-08 +date: 2024-02-09 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 4832a30ad3cd2..8738e6fc2e6d8 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-02-08 +date: 2024-02-09 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 ff59b8aca02ee..ea6d388d61028 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-02-08 +date: 2024-02-09 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 54d69eb52ce60..0be10a6c9bdca 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-02-08 +date: 2024-02-09 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 e73a8f6a7a9c1..10e14055a71af 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index fdb2f18b13f33..26f9c1ddab44c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index b0ef1a9daa8a8..a923785179c9c 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-02-08 +date: 2024-02-09 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 6912366076fa1..8a008f9ec306b 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-02-08 +date: 2024-02-09 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 8ef629c666c19..2f351c8679c4e 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-02-08 +date: 2024-02-09 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 04e814aafa245..206564c557df7 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.devdocs.json b/api_docs/kbn_search_api_panels.devdocs.json index a55ccad88b62e..c6fd706ade36f 100644 --- a/api_docs/kbn_search_api_panels.devdocs.json +++ b/api_docs/kbn_search_api_panels.devdocs.json @@ -74,7 +74,7 @@ "label": "CodeBox", "description": [], "signature": [ - "({ application, codeSnippet, languageType, languages, assetBasePath, selectedLanguage, setSelectedLanguage, sharePlugin, consoleRequest, }: React.PropsWithChildren) => JSX.Element" + "({ application, codeSnippet, consolePlugin, languageType, languages, assetBasePath, selectedLanguage, setSelectedLanguage, sharePlugin, consoleRequest, }: React.PropsWithChildren) => JSX.Element" ], "path": "packages/kbn-search-api-panels/components/code_box.tsx", "deprecated": false, @@ -85,7 +85,7 @@ "id": "def-common.CodeBox.$1", "type": "CompoundType", "tags": [], - "label": "{\n application,\n codeSnippet,\n languageType,\n languages,\n assetBasePath,\n selectedLanguage,\n setSelectedLanguage,\n sharePlugin,\n consoleRequest,\n}", + "label": "{\n application,\n codeSnippet,\n consolePlugin,\n languageType,\n languages,\n assetBasePath,\n selectedLanguage,\n setSelectedLanguage,\n sharePlugin,\n consoleRequest,\n}", "description": [], "signature": [ "React.PropsWithChildren" @@ -326,7 +326,7 @@ "label": "IngestData", "description": [], "signature": [ - "({ codeSnippet, selectedLanguage, setSelectedLanguage, docLinks, assetBasePath, application, sharePlugin, languages, consoleRequest, additionalIngestionPanel, }: React.PropsWithChildren) => JSX.Element" + "({ codeSnippet, selectedLanguage, setSelectedLanguage, docLinks, assetBasePath, application, consolePlugin, sharePlugin, languages, consoleRequest, additionalIngestionPanel, }: React.PropsWithChildren) => JSX.Element" ], "path": "packages/kbn-search-api-panels/components/ingest_data.tsx", "deprecated": false, @@ -337,7 +337,7 @@ "id": "def-common.IngestData.$1", "type": "CompoundType", "tags": [], - "label": "{\n codeSnippet,\n selectedLanguage,\n setSelectedLanguage,\n docLinks,\n assetBasePath,\n application,\n sharePlugin,\n languages,\n consoleRequest,\n additionalIngestionPanel,\n}", + "label": "{\n codeSnippet,\n selectedLanguage,\n setSelectedLanguage,\n docLinks,\n assetBasePath,\n application,\n consolePlugin,\n sharePlugin,\n languages,\n consoleRequest,\n additionalIngestionPanel,\n}", "description": [], "signature": [ "React.PropsWithChildren" @@ -573,7 +573,7 @@ "label": "TryInConsoleButton", "description": [], "signature": [ - "({ request, application, sharePlugin, }: ", + "({ request, application, consolePlugin, sharePlugin, }: ", { "pluginId": "@kbn/search-api-panels", "scope": "common", @@ -592,7 +592,7 @@ "id": "def-common.TryInConsoleButton.$1", "type": "Object", "tags": [], - "label": "{\n request,\n application,\n sharePlugin,\n}", + "label": "{\n request,\n application,\n consolePlugin,\n sharePlugin,\n}", "description": [], "signature": [ { @@ -1214,6 +1214,27 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/search-api-panels", + "id": "def-common.TryInConsoleButtonProps.consolePlugin", + "type": "Object", + "tags": [], + "label": "consolePlugin", + "description": [], + "signature": [ + { + "pluginId": "console", + "scope": "public", + "docId": "kibConsolePluginApi", + "section": "def-public.ConsolePluginStart", + "text": "ConsolePluginStart" + }, + " | undefined" + ], + "path": "packages/kbn-search-api-panels/components/try_in_console_button.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/search-api-panels", "id": "def-common.TryInConsoleButtonProps.sharePlugin", diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 9f1324396706f..3c29b75b23734 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 75 | 0 | 75 | 0 | +| 76 | 0 | 76 | 0 | ## Common diff --git a/api_docs/kbn_search_connectors.devdocs.json b/api_docs/kbn_search_connectors.devdocs.json index c10a612df9100..17607f6d88980 100644 --- a/api_docs/kbn_search_connectors.devdocs.json +++ b/api_docs/kbn_search_connectors.devdocs.json @@ -676,6 +676,76 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.deleteConnectorSecret", + "type": "Function", + "tags": [], + "label": "deleteConnectorSecret", + "description": [], + "signature": [ + "(client: ", + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "common", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-common.ElasticsearchClient", + "text": "ElasticsearchClient" + }, + ", id: string) => Promise<", + { + "pluginId": "@kbn/search-connectors", + "scope": "common", + "docId": "kibKbnSearchConnectorsPluginApi", + "section": "def-common.ConnectorsAPIUpdateResponse", + "text": "ConnectorsAPIUpdateResponse" + }, + ">" + ], + "path": "packages/kbn-search-connectors/lib/delete_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.deleteConnectorSecret.$1", + "type": "Object", + "tags": [], + "label": "client", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "common", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-common.ElasticsearchClient", + "text": "ElasticsearchClient" + } + ], + "path": "packages/kbn-search-connectors/lib/delete_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.deleteConnectorSecret.$2", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-search-connectors/lib/delete_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/search-connectors", "id": "def-common.fetchConnectorById", diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 24aedb4a3b174..1d0f6b2a1be27 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2805 | 0 | 2805 | 0 | +| 2808 | 0 | 2808 | 0 | ## Common diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 40f59bcfabf5d..72cde44afdf93 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-02-08 +date: 2024-02-09 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 1990cfdeb5163..67f42a7f70395 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-02-08 +date: 2024-02-09 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 d1025cbf86dfd..86c4b13c37584 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 8bbb0930a8218..9cad86b1a78fe 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-02-08 +date: 2024-02-09 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 118471660e70d..cb3bf6aab0b13 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-02-08 +date: 2024-02-09 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 e61141b0b426d..a038ad956ea4d 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-02-08 +date: 2024-02-09 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_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 54e7340cc6579..5cc0918e330da 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-02-08 +date: 2024-02-09 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 6dbbe7716d967..7c699ebbc46b5 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-02-08 +date: 2024-02-09 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 57f3d6f24ee87..acd84283b362a 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-02-08 +date: 2024-02-09 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 2d83c4bb266e9..24638c19bbf63 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 35b773bd297f0..7310f90f44660 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-02-08 +date: 2024-02-09 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 f683ceae72346..a2fc7a19cc55b 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-02-08 +date: 2024-02-09 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 cc3531d6cf540..7e3626771820c 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-02-08 +date: 2024-02-09 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 66e2708e164f5..510d4eb34422b 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-02-08 +date: 2024-02-09 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 d6cd59f427a39..10d25c2402388 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 0af21b9b73ea4..17b907e4d4a46 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 3ee2cecf5d408..ad66efdb05ee0 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-02-08 +date: 2024-02-09 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 e991bd2333ada..d4e516c74b824 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-02-08 +date: 2024-02-09 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 e58c5f649e3aa..2e62f802f819a 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-02-08 +date: 2024-02-09 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 571cdd7653e65..f25508fcab162 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-02-08 +date: 2024-02-09 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 1568546f020a7..0490e602cb1ce 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-02-08 +date: 2024-02-09 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 94d99d3f48855..12e859629150a 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-02-08 +date: 2024-02-09 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 9b91fd6f84972..dd5112c1cf932 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-02-08 +date: 2024-02-09 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 568ae81bcf156..5bf87a9774813 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-02-08 +date: 2024-02-09 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 bca66ee2fd246..337925fef6f6f 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-02-08 +date: 2024-02-09 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 4752383b3776e..8b9dad87e8003 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-02-08 +date: 2024-02-09 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 f9901c6a12902..2dc140f925cc4 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-02-08 +date: 2024-02-09 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 5eae52bb780a9..b97f1e8f7bf13 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-02-08 +date: 2024-02-09 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 e8c3056a52793..b9dbd270ce52e 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-02-08 +date: 2024-02-09 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 bee9f0812f016..7feaf19a95e8b 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index cdbfd3d68e37b..f018a2e3b9656 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-02-08 +date: 2024-02-09 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 2c96dd4d9b872..3f3d901c7cf75 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-02-08 +date: 2024-02-09 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 75bd2722d6ab9..64795324e792e 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-02-08 +date: 2024-02-09 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 6b9fbf1de092d..88d1a01b04be3 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-02-08 +date: 2024-02-09 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 d929e1e89989f..064175db7f4fe 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-02-08 +date: 2024-02-09 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 48df79ee00ea0..34a0a94e1ed2b 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-02-08 +date: 2024-02-09 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 f5d6ddd4b25f2..22043f8e8c03f 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-02-08 +date: 2024-02-09 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 53a2ac8605a49..5ba189e377bb2 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-02-08 +date: 2024-02-09 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 20b99674a4571..f1184f3cfb24d 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-02-08 +date: 2024-02-09 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 d2db7457735cc..b6dde00e8894c 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-02-08 +date: 2024-02-09 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 bbe9827527c08..830337cda693a 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-02-08 +date: 2024-02-09 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 ca2d51f33d433..ce80864d20ac7 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-02-08 +date: 2024-02-09 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 72984a79628c9..d8e299e235cd6 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-02-08 +date: 2024-02-09 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 7306bfa692ba3..c7ffb75058f20 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-02-08 +date: 2024-02-09 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 e058d1c8b8290..54c1b10171ec6 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-02-08 +date: 2024-02-09 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 992eb3e689b5d..cd66c18326c9e 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-02-08 +date: 2024-02-09 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 4e6ad6347430c..28bc960da99a3 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-02-08 +date: 2024-02-09 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 63a08508889d2..21169e23a6ecf 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-02-08 +date: 2024-02-09 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 1795b1df6a204..9b8384b75561e 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-02-08 +date: 2024-02-09 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 29af4c9c2e6a9..ecb1385323bba 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-02-08 +date: 2024-02-09 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 615fe97f99855..c09747ae9c41f 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-02-08 +date: 2024-02-09 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 98bf551cc063e..22108696eb39e 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-02-08 +date: 2024-02-09 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 4672e3cadc3f3..8c4d3b7415419 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-02-08 +date: 2024-02-09 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 f224d4bbdbf58..aca11de2a9402 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-02-08 +date: 2024-02-09 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 db23219fc66e7..f6cf68cddae21 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-02-08 +date: 2024-02-09 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 8414d3ea81a5a..997540a9e15e2 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-02-08 +date: 2024-02-09 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 08600d4bc6105..e632593c9f1a5 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-02-08 +date: 2024-02-09 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 72b4ed2b8bb39..7910921c7735c 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-02-08 +date: 2024-02-09 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 59cff789af06f..a29cc08b66b72 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-02-08 +date: 2024-02-09 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 381ff98989c67..5a88e00a52dc8 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-02-08 +date: 2024-02-09 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 7f2c7e99f60da..de58330840431 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-02-08 +date: 2024-02-09 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 d7ec3d8a1248c..a3ec366c136e4 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-02-08 +date: 2024-02-09 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 f28cbb449f751..e0c1c06a45e7a 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-02-08 +date: 2024-02-09 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 80319b95ccc12..c530b568e9778 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-02-08 +date: 2024-02-09 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 c46e95f44d545..716f08306abb8 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-02-08 +date: 2024-02-09 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 1c8091f51f630..a799d6796e1a4 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-02-08 +date: 2024-02-09 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 e9076403f55a5..57460b637ce96 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-02-08 +date: 2024-02-09 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 360b21120b24b..86df3a12667ea 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-02-08 +date: 2024-02-09 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 8a3f7a4b769c4..89da3d1e37a7c 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-02-08 +date: 2024-02-09 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 fccba7369485f..5dd3b3f126c79 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-02-08 +date: 2024-02-09 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 82de16bce0f07..1b90310eb4165 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-02-08 +date: 2024-02-09 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 2d669881993a9..522b22ee840bf 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-02-08 +date: 2024-02-09 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 460a6f08b0aa0..30a9f9a6fd175 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-02-08 +date: 2024-02-09 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 a9a0565ebd1b5..c7c14d7bdf28c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 137443224d0f9..48d8a1fac87c3 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-02-08 +date: 2024-02-09 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 5df4a1b683e46..5d5bcfcfe8bd1 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-02-08 +date: 2024-02-09 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 2d26ddb0e327a..bd8d1177c366a 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-02-08 +date: 2024-02-09 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 d53154842565a..6273163237752 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 23b583fd3f147..885961a8ce008 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-02-08 +date: 2024-02-09 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 4b315de93040b..9d34f76f45c24 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-02-08 +date: 2024-02-09 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 81cda58b60340..333e0c02d1f2b 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index e2a14e589aad0..d51561586eae3 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-02-08 +date: 2024-02-09 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 75c1741fe9c68..5decb133671ed 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-02-08 +date: 2024-02-09 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 3dbba0f9da53a..9a36f2b93d427 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-02-08 +date: 2024-02-09 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.mdx b/api_docs/kbn_test_jest_helpers.mdx index 644acddd8a2c7..a1819a2c16a1a 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index e106e07806f97..fd2dc01162d1d 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.devdocs.json b/api_docs/kbn_text_based_editor.devdocs.json index 8e1737f376a91..8331afd578b82 100644 --- a/api_docs/kbn_text_based_editor.devdocs.json +++ b/api_docs/kbn_text_based_editor.devdocs.json @@ -43,7 +43,7 @@ "section": "def-common.TimeRange", "text": "TimeRange" }, - " | undefined, dataView: ", + " | undefined, abortController: AbortController | undefined, dataView: ", { "pluginId": "dataViews", "scope": "common", @@ -142,6 +142,21 @@ "id": "def-public.fetchFieldsFromESQL.$4", "type": "Object", "tags": [], + "label": "abortController", + "description": [], + "signature": [ + "AbortController | undefined" + ], + "path": "packages/kbn-text-based-editor/src/fetch_fields_from_esql.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.fetchFieldsFromESQL.$5", + "type": "Object", + "tags": [], "label": "dataView", "description": [], "signature": [ @@ -298,7 +313,7 @@ "section": "def-common.AggregateQuery", "text": "AggregateQuery" }, - " | undefined) => void" + " | undefined, abortController?: AbortController | undefined) => Promise" ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, @@ -325,6 +340,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.onTextLangQuerySubmit.$2", + "type": "Object", + "tags": [], + "label": "abortController", + "description": [], + "signature": [ + "AbortController | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] @@ -549,6 +579,22 @@ "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.allowQueryCancellation", + "type": "CompoundType", + "tags": [], + "label": "allowQueryCancellation", + "description": [ + "when set to true enables query cancellation" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index b0fb3bb352a99..c5dba70544f5c 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.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 | |-------------------|-----------|------------------------|-----------------| -| 27 | 0 | 11 | 0 | +| 30 | 0 | 13 | 0 | ## Client diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 622af471c1655..80818df04b78f 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index fe430c80f73d0..3f55a6e3760da 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 53416cc864850..b44cebad7cefb 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 621a40aae4f3e..bd28ce25b703f 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 124335ac7e4ff..aefed1ce38c87 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 315b924ee1a62..476641692bc2a 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index a79dace22912d..d0bd82faf9f07 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index b2ca4078f000e..8efc0907d12f8 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 97aca7830d5fd..0997d3e5b491d 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index f391ea773eff5..3f0bb7b6eb169 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 3abbb2ea45377..dc399e490d595 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 8ebfbe2031e54..4f0f914cbc28f 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 782d00d6fe62a..3bf0853bf5cfd 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 97ce29df9137f..8c91b96db58c8 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 90c8a0db6d324..5f54692963633 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.devdocs.json b/api_docs/kbn_utils.devdocs.json index c2f4eefd1be61..f7fff669338a0 100644 --- a/api_docs/kbn_utils.devdocs.json +++ b/api_docs/kbn_utils.devdocs.json @@ -451,6 +451,41 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/utils", + "id": "def-common.prettyPrintAndSortKeys", + "type": "Function", + "tags": [], + "label": "prettyPrintAndSortKeys", + "description": [ + "\nGiven a JS object, will return a JSON.stringified result with consistently\nsorted keys." + ], + "signature": [ + "(object: object) => string" + ], + "path": "packages/kbn-utils/src/json/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/utils", + "id": "def-common.prettyPrintAndSortKeys.$1", + "type": "Uncategorized", + "tags": [], + "label": "object", + "description": [], + "signature": [ + "object" + ], + "path": "packages/kbn-utils/src/json/index.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index be4a8165a1c63..4ee5c359123d9 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kiban | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 24 | 0 | 14 | 0 | +| 26 | 0 | 15 | 0 | ## Common diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index eceeab039ad9e..d6f66d5dfcce2 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 5e69d60e1e6e8..5421e51a45e70 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 6726f8c356c04..9f881b8d3b8f9 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 918b50bdfd850..3ed9f16993c07 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index 9a13d897879e9..c939ddaf42b91 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index b10842d919fd0..00f079c1cec35 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 2dbf5cea1cffe..9fb8755ec56d4 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -1163,6 +1163,18 @@ "plugin": "ml", "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx" }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx" + }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx" + }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable.tsx" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx" diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index fa15a93b184f3..c3e14a5ad511d 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 748135aea0663..6040c26ab1283 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 70eafb707a20d..3efe37426e656 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 44ad4585cc74e..27f646f8e2888 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index d89fdf7c99069..5e034defbda14 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index ed5b3c8507658..1f1d43b4efd6e 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.devdocs.json b/api_docs/licensing.devdocs.json index 0d43c4c2d00dc..5a54a44d81030 100644 --- a/api_docs/licensing.devdocs.json +++ b/api_docs/licensing.devdocs.json @@ -2220,11 +2220,7 @@ }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signal.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_event_signal.ts" + "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/threat_mapping/create_threat_signals.ts" }, { "plugin": "securitySolution", diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index dd236acd18f20..310f7471591ff 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index b7300edc6bdbb..8daa7853d911a 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 95cd4b04df419..b39f38ec83a2c 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 385bc61ba95ec..45c74f3e2bd88 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index d2f8d50cc8f01..ff2eef1c37860 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index fba676f19aecd..2b1cb49d1c497 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index b08020847ad0f..6fb945cba13d8 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index c31e0e69c8098..fe919f1927551 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 625ffebb489f3..2958317d49194 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 7e9e89ae9fe6c..b020690729abe 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 7926d1a9b9d7c..18ae7b2b8e8c4 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 975e5081aa0c3..b8c5491cd823d 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 7a6ccb760d179..2b300a9f6547c 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index f1e78a2a0d848..0cb07067798e5 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 1ac248f0f8035..d0a0472c8d09a 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 6b7425d854413..14a098785df63 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 134a6b479f43e..a4e214e009129 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 00a2701daf52c..a7aba7f3a7bf1 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-02-08 +date: 2024-02-09 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 f28cde02e43cd..d5df9f9282a6c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index d47958c2a8078..188f3bd0ebddd 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-02-08 +date: 2024-02-09 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 ccd4ba146fa33..f0ad4ee30d757 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.devdocs.json b/api_docs/observability_shared.devdocs.json index 3d85c4cdca8b7..1867134f22f2e 100644 --- a/api_docs/observability_shared.devdocs.json +++ b/api_docs/observability_shared.devdocs.json @@ -522,7 +522,7 @@ "label": "FeatureFeedbackButton", "description": [], "signature": [ - "({ formUrl, \"data-test-subj\": dts, onClickCapture, defaultButton, kibanaVersion, isCloudEnv, isServerlessEnv, sanitizedPath, surveyButtonText, }: FeatureFeedbackButtonProps) => JSX.Element" + "({ formUrl, formConfig, \"data-test-subj\": dts, onClickCapture, defaultButton, kibanaVersion, isCloudEnv, isServerlessEnv, sanitizedPath, surveyButtonText, }: FeatureFeedbackButtonProps) => JSX.Element" ], "path": "x-pack/plugins/observability_shared/public/components/feature_feedback_button/feature_feedback_button.tsx", "deprecated": false, @@ -533,7 +533,7 @@ "id": "def-public.FeatureFeedbackButton.$1", "type": "Object", "tags": [], - "label": "{\n formUrl,\n 'data-test-subj': dts,\n onClickCapture,\n defaultButton,\n kibanaVersion,\n isCloudEnv,\n isServerlessEnv,\n sanitizedPath,\n surveyButtonText = (\n \n ),\n}", + "label": "{\n formUrl,\n formConfig,\n 'data-test-subj': dts,\n onClickCapture,\n defaultButton,\n kibanaVersion,\n isCloudEnv,\n isServerlessEnv,\n sanitizedPath,\n surveyButtonText = (\n \n ),\n}", "description": [], "signature": [ "FeatureFeedbackButtonProps" diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 6321d889038b1..b9555c1d41507 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-02-08 +date: 2024-02-09 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 aabeb22ebcdc9..1eb3c60c9157a 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-02-08 +date: 2024-02-09 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 e993b1aa9f688..d2eb14b7bec84 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-02-08 +date: 2024-02-09 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 721ce92b3aa70..b5ecf96fd46c6 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 79771 | 228 | 68327 | 1735 | +| 79796 | 228 | 68343 | 1736 | ## Plugin Directory @@ -49,7 +49,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | cloudFullStory | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | When Kibana runs on Elastic Cloud, this plugin registers FullStory as a shipper for telemetry. | 0 | 0 | 0 | 0 | | cloudLinks | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Adds the links to the Elastic Cloud console | 0 | 0 | 0 | 0 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | The cloud security posture plugin | 14 | 0 | 2 | 2 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 29 | 0 | 23 | 0 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 32 | 0 | 24 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Content management app | 149 | 0 | 125 | 6 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 323 | 0 | 315 | 16 | | crossClusterReplication | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | @@ -64,7 +64,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 943 | 0 | 276 | 4 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 10 | 0 | 10 | 5 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 16 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 151 | 0 | 104 | 22 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 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 | @@ -108,7 +108,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 151 | 0 | 111 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 3 | 0 | 3 | 1 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 223 | 0 | 218 | 4 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 224 | 0 | 219 | 4 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 32 | 0 | 29 | 8 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | | inputControlVis | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 | @@ -184,7 +184,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 31 | 0 | 26 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 0 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 24 | 0 | 9 | 0 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 26 | 0 | 10 | 0 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 30 | 0 | 14 | 5 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 240 | 1 | 196 | 17 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | @@ -256,7 +256,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 37 | 0 | 15 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 8 | 0 | 4 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 211 | 0 | 174 | 8 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 217 | 0 | 180 | 9 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 77 | 0 | 48 | 9 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 24 | 0 | 24 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 140 | 3 | 137 | 18 | @@ -264,7 +264,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 8 | 0 | 8 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 7 | 0 | 7 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 52 | 0 | 34 | 3 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 50 | 0 | 33 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 191 | 1 | 125 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 7 | 1 | @@ -400,7 +400,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 14 | 0 | 14 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 0 | 6 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 12 | 0 | 2 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 20 | 0 | 19 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 21 | 0 | 20 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 20 | 0 | 3 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 24 | 0 | 24 | 3 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 0 | @@ -515,7 +515,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 592 | 1 | 1 | 0 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 2 | 0 | 2 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 95 | 2 | 0 | 0 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 206 | 3 | 1 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 207 | 3 | 1 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 8 | 0 | 8 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 37 | 0 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 12 | 0 | 0 | 0 | @@ -587,8 +587,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 16 | 0 | 16 | 1 | | | [@elastic/security-detections-response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 120 | 0 | 117 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | -| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 75 | 0 | 75 | 0 | -| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2805 | 0 | 2805 | 0 | +| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 76 | 0 | 76 | 0 | +| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2808 | 0 | 2808 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 1 | 17 | 1 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 25 | 0 | 25 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 20 | 0 | 18 | 1 | @@ -675,7 +675,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 14 | 0 | 8 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 137 | 5 | 105 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 27 | 0 | 11 | 0 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 30 | 0 | 13 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 72 | 0 | 55 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 11 | 0 | 11 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 39 | 0 | 25 | 1 | @@ -691,7 +691,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 80 | 1 | 21 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 37 | 0 | 16 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 24 | 0 | 14 | 0 | +| | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 26 | 0 | 15 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 152 | 0 | 149 | 3 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 10 | 0 | 9 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 13 | 0 | 13 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index e3aee7f0bfb71..1cbe9f66219e5 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-02-08 +date: 2024-02-09 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 e405fca86a3d1..c33fe9dba795b 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-02-08 +date: 2024-02-09 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 d4cfe28b7e8aa..fa0e0d377aac8 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-02-08 +date: 2024-02-09 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 0e56d9598fef2..1778a3d0f2eff 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-02-08 +date: 2024-02-09 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 c55f1a935cf9e..79331f765151e 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-02-08 +date: 2024-02-09 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 d26e76e7ce488..e53111e6cb383 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-02-08 +date: 2024-02-09 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 ef919e8821540..ff43fbc1fd8c3 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-02-08 +date: 2024-02-09 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 2e198ed3ddc25..6d7808fa27342 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-02-08 +date: 2024-02-09 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 91d4e323253ab..98483807c2012 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-02-08 +date: 2024-02-09 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 4126438f28ced..709d8717bcc7e 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-02-08 +date: 2024-02-09 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 e12526f9c89bc..61632c9c3d1f1 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-02-08 +date: 2024-02-09 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 1ebf4383f706f..a93e05b53a32f 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-02-08 +date: 2024-02-09 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 beb0e74f46dd4..2fe6ea9943582 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-02-08 +date: 2024-02-09 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 e9ea1260a755d..fd1b3a8a717eb 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-02-08 +date: 2024-02-09 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 413055e82c1ce..09645999bfe41 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-02-08 +date: 2024-02-09 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 07273e1cf9127..21bbba8cd8614 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-02-08 +date: 2024-02-09 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 a8685fcc16fcd..9f71cdf86860d 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 3dca4d8a056eb..a8e082ce22623 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-02-08 +date: 2024-02-09 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 851069752f8ad..9bc95f3f861f1 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-02-08 +date: 2024-02-09 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 7d6805ad32c9b..17529da5c99d7 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-02-08 +date: 2024-02-09 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 6fb77f7079ab5..d36557e040a7d 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-02-08 +date: 2024-02-09 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 09bf0ab95e78c..a85ead41c14c4 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-02-08 +date: 2024-02-09 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 80845375fa25e..5d32477f4eac4 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-02-08 +date: 2024-02-09 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 5f5879eeabe24..e33912fbbc1ee 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-02-08 +date: 2024-02-09 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 56946b555e2f2..6943ffb606a7b 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-02-08 +date: 2024-02-09 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 a8786c8438ef2..5ffd9c2ebb41d 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 3fce052eddefb..2561f9a498d45 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-02-08 +date: 2024-02-09 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 89ec19c9d8155..5638834710267 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-02-08 +date: 2024-02-09 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 145306cf77dec..d0e6474172f12 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-02-08 +date: 2024-02-09 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 cef40b7b09a6a..b71322b858533 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-02-08 +date: 2024-02-09 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 a151419fe32f7..df77276d04166 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-02-08 +date: 2024-02-09 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 b4fcc79079d2c..821fde6c89393 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-02-08 +date: 2024-02-09 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 e1b5a553f14c0..1adeabf51c66c 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index d65290e05ca4e..cc8a901cd3e54 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 09f984ea18369..cc074ffd86ab3 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.devdocs.json b/api_docs/text_based_languages.devdocs.json index 35e649a14f3f2..be42f4c6c2369 100644 --- a/api_docs/text_based_languages.devdocs.json +++ b/api_docs/text_based_languages.devdocs.json @@ -145,7 +145,7 @@ "section": "def-common.AggregateQuery", "text": "AggregateQuery" }, - " | undefined) => void" + " | undefined, abortController?: AbortController | undefined) => Promise" ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, @@ -172,6 +172,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.onTextLangQuerySubmit.$2", + "type": "Object", + "tags": [], + "label": "abortController", + "description": [], + "signature": [ + "AbortController | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] @@ -396,6 +411,22 @@ "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.allowQueryCancellation", + "type": "CompoundType", + "tags": [], + "label": "allowQueryCancellation", + "description": [ + "when set to true enables query cancellation" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index e6dc10f5a9565..3860868eae9f1 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2024-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.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 | |-------------------|-----------|------------------------|-----------------| -| 24 | 0 | 9 | 0 | +| 26 | 0 | 10 | 0 | ## Client diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 72fe54da292e5..871552ef580ce 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-02-08 +date: 2024-02-09 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 51379efcc39aa..62ce6e024de5a 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-02-08 +date: 2024-02-09 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 a5efbd6742623..e78e77f0b683d 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-02-08 +date: 2024-02-09 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 7f22a66a59803..54ed2e7424e04 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-02-08 +date: 2024-02-09 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 1ef2d79fb3bc5..7046d38f255df 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-02-08 +date: 2024-02-09 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 4c659d410fcbe..90387f0a9e623 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-02-08 +date: 2024-02-09 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 7e89032b71d6b..8cdbab8d29bc2 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-02-08 +date: 2024-02-09 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 9690c84929005..ab6b3b425db60 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-02-08 +date: 2024-02-09 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 1465ebdda2291..e576c5172b1a3 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-02-08 +date: 2024-02-09 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 90172fc462ad1..ca2b7fc38dff3 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-02-08 +date: 2024-02-09 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 79e7ca4b21364..ab0476a55f036 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-02-08 +date: 2024-02-09 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 9e90600856309..503035cc178a0 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-02-08 +date: 2024-02-09 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 0d44be7793e6a..fd1e2fd3252f1 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-02-08 +date: 2024-02-09 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 36f67fe934a29..8ded43633aa1b 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-02-08 +date: 2024-02-09 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 2b55d86ea4cb4..1598fad99c4dc 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-02-08 +date: 2024-02-09 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 2c07f3ec3582e..788dbe3e1405b 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-02-08 +date: 2024-02-09 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 2feb7aa00cc8e..89b29bbd5d193 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-02-08 +date: 2024-02-09 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 eb97b5b933dbc..d293b4f77202d 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-02-08 +date: 2024-02-09 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 600d5be2346b4..4971257adbca1 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-02-08 +date: 2024-02-09 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 7fe24b693cb89..eb9d104460c95 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-02-08 +date: 2024-02-09 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 7ed7ba8f3f4fc..cb4c784432c4f 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-02-08 +date: 2024-02-09 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 ca95e9f9fa272..b3ad6181b27a0 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-02-08 +date: 2024-02-09 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 bbad04fca0ceb..14928ff239e0e 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-02-08 +date: 2024-02-09 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 39c2e0ca0b9a7..435c72bbc9e98 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 186762e92bbc1..9fb2997892af0 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-02-08 +date: 2024-02-09 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 239b9571917a113a00270e1f2572f011e11441da Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Fri, 9 Feb 2024 07:06:06 +0000 Subject: [PATCH 057/104] [Logs Explorer] Add ability to create alerts within the Explorer app (#175777) ## Summary Users in Logs Explorer should be able to define rules that will create alerts when the number of logs passes a certain threshold. As part of this issue, support for the new custom threshold rule will be added in the header. ## Screenshot Screenshot 2024-01-29 at 12 48 28 ## Notes for reviewers Apologies for the noise across multiple plugins but I tried to update the `RuleAddProps` type since it offered no type safety making it incredibly difficult and error prone to understand what properties are required for the selected rule type. The lack of type safety in the exposed alerting/rules related public APIs caused various bugs during integration, each dependant on specific conditions and requiring a lot of manual testing. I have tried to fix as many of these bugs as possible but had to base it mainly on trial and error due to the lack of correct typing with too many optional (but in reality required) properties. An example of this are filter badges in the universal search component. These were not displayed correctly due to missing props on the `FilterMeta` interface which are all marked as optional but somehow assumed to be there by the UI components that render them. Another issue was caused by implicit service dependencies with no validation in place by consuming components. An example of this is the `triggersActionsUi.getAddRuleFlyout` method which requires `unifiedSearch`, `dataViews`, `dataViewEditor` and `lens` services in React context but for the majority silently fails causing bugs only under specific conditions or when trying to carry out specific actions. Integration is made even more difficult since these can differ between different rule types. It would be great if these are made either explicit or if validation is put in place to warn developers of integration issues. There is also an existing bug in that filters displayed by the universal search component provide the ability to edit the filter but when attempting to do so and clicking "Update filter" to confirm nothing happens despite the `SearchBar.onFiltersUpdated` being defined. I have tested this behaviour in other integrations which all have the same bugs so am treating these as existing issues. ## Acceptance criteria - Add an `Alerts` item to the header that will include two options: - `Create rule` that will open the custom threshold rule flyout - `Manage rules` that will link to the observability rules management page (`app/observability/alerts/rules`) - Set default configuration that will be used in the flyout - The Ad Hoc data view that is created as part of the selector - The query from the KQL bar - Role visibility should be hidden --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Maryam Saeidi --- .../top_nav/open_alerts_popover.tsx | 7 +- .../public/filter_badge/filter_badge.tsx | 2 +- x-pack/plugins/alerting/common/rule.ts | 1 + ...s_upgrade_and_rollback_checks.test.ts.snap | 95 ++++++++++++ .../ui_components/alerting_flyout/index.tsx | 10 +- .../components/alerting/utils/helper.ts | 4 +- .../alert_details_app_section.test.tsx.snap | 8 +- .../alert_details_app_section.tsx | 10 +- .../rule_condition_chart.test.tsx | 3 +- .../rule_condition_chart.tsx | 20 ++- .../custom_threshold_rule_expression.tsx | 14 +- .../lib/check_missing_group.ts | 35 +++-- .../custom_threshold/lib/evaluate_rule.ts | 4 +- .../rules/custom_threshold/lib/get_data.ts | 7 +- .../custom_threshold/lib/metric_query.test.ts | 87 ++++++++++- .../custom_threshold/lib/metric_query.ts | 46 +++--- .../register_custom_threshold_rule_type.ts | 8 + .../server/utils/get_parsed_filtered_query.ts | 30 +++- .../utils/convert_discover_app_state.ts | 91 ++++++----- .../observability_logs_explorer/kibana.jsonc | 7 +- .../observability_logs_explorer.tsx | 20 ++- .../public/components/alerts_popover.tsx | 142 ++++++++++++++++++ .../public/components/discover_link.tsx | 18 ++- .../components/logs_explorer_top_nav_menu.tsx | 5 + .../public/types.ts | 10 ++ .../observability_logs_explorer/tsconfig.json | 7 + .../application/sections/rule_form/index.tsx | 11 +- .../sections/rule_form/rule_add.tsx | 10 +- .../sections/rule_form/rule_edit.tsx | 11 +- .../public/common/get_add_rule_flyout.tsx | 9 +- .../public/common/get_edit_rule_flyout.tsx | 9 +- .../triggers_actions_ui/public/mocks.ts | 6 +- .../triggers_actions_ui/public/plugin.ts | 26 ++-- .../triggers_actions_ui/public/types.ts | 30 +++- 34 files changed, 650 insertions(+), 153 deletions(-) create mode 100644 x-pack/plugins/observability_solution/observability_logs_explorer/public/components/alerts_popover.tsx diff --git a/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx index 985b0c303cd21..ee80e467e7fb4 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx @@ -19,6 +19,7 @@ import { RuleCreationValidConsumer, STACK_ALERTS_FEATURE_ID, } from '@kbn/rule-data-utils'; +import { RuleTypeMetaData } from '@kbn/alerting-plugin/common'; import { DiscoverStateContainer } from '../../services/discover_state'; import { DiscoverServices } from '../../../../build_services'; @@ -42,7 +43,7 @@ interface AlertsPopoverProps { isPlainRecord?: boolean; } -interface EsQueryAlertMetaData { +interface EsQueryAlertMetaData extends RuleTypeMetaData { isManagementPage?: boolean; adHocDataViewList: DataView[]; } @@ -110,11 +111,11 @@ export function AlertsPopover({ metadata: discoverMetadata, consumer: 'alerts', onClose: (_, metadata) => { - onFinishFlyoutInteraction(metadata as EsQueryAlertMetaData); + onFinishFlyoutInteraction(metadata!); onClose(); }, onSave: async (metadata) => { - onFinishFlyoutInteraction(metadata as EsQueryAlertMetaData); + onFinishFlyoutInteraction(metadata!); }, canChangeTrigger: false, ruleTypeId: ES_QUERY_ID, diff --git a/src/plugins/unified_search/public/filter_badge/filter_badge.tsx b/src/plugins/unified_search/public/filter_badge/filter_badge.tsx index 7b20eab971e9c..e20429d5e9f36 100644 --- a/src/plugins/unified_search/public/filter_badge/filter_badge.tsx +++ b/src/plugins/unified_search/public/filter_badge/filter_badge.tsx @@ -67,7 +67,7 @@ function FilterBadge({ `} > - {!hideAlias && filter.meta.alias !== null ? ( + {filter.meta.alias && !hideAlias ? ( <> {prefix} diff --git a/x-pack/plugins/alerting/common/rule.ts b/x-pack/plugins/alerting/common/rule.ts index 7cec5bdbdd7a6..6a66b39720402 100644 --- a/x-pack/plugins/alerting/common/rule.ts +++ b/x-pack/plugins/alerting/common/rule.ts @@ -19,6 +19,7 @@ export type { ActionVariable } from '@kbn/alerting-types'; export type RuleTypeState = Record; export type RuleTypeParams = Record; +export type RuleTypeMetaData = Record; // rule type defined alert fields to persist in alerts index export type RuleAlertData = Record; diff --git a/x-pack/plugins/alerting/server/integration_tests/__snapshots__/serverless_upgrade_and_rollback_checks.test.ts.snap b/x-pack/plugins/alerting/server/integration_tests/__snapshots__/serverless_upgrade_and_rollback_checks.test.ts.snap index 70ffc475d01d6..6360d65c0e66c 100644 --- a/x-pack/plugins/alerting/server/integration_tests/__snapshots__/serverless_upgrade_and_rollback_checks.test.ts.snap +++ b/x-pack/plugins/alerting/server/integration_tests/__snapshots__/serverless_upgrade_and_rollback_checks.test.ts.snap @@ -3064,6 +3064,101 @@ Object { "presence": "optional", }, "keys": Object { + "filter": Object { + "flags": Object { + "default": [Function], + "error": [Function], + "presence": "optional", + }, + "items": Array [ + Object { + "flags": Object { + "default": Object { + "special": "deep", + }, + "error": [Function], + "presence": "optional", + }, + "keys": Object { + "meta": Object { + "flags": Object { + "error": [Function], + }, + "rules": Array [ + Object { + "args": Object { + "key": Object { + "flags": Object { + "error": [Function], + }, + "rules": Array [ + Object { + "args": Object { + "method": [Function], + }, + "name": "custom", + }, + ], + "type": "string", + }, + "value": Object { + "flags": Object { + "error": [Function], + }, + "type": "any", + }, + }, + "name": "entries", + }, + ], + "type": "record", + }, + "query": Object { + "flags": Object { + "default": [Function], + "error": [Function], + "presence": "optional", + }, + "rules": Array [ + Object { + "args": Object { + "key": Object { + "flags": Object { + "error": [Function], + }, + "rules": Array [ + Object { + "args": Object { + "method": [Function], + }, + "name": "custom", + }, + ], + "type": "string", + }, + "value": Object { + "flags": Object { + "error": [Function], + }, + "type": "any", + }, + }, + "name": "entries", + }, + ], + "type": "record", + }, + }, + "preferences": Object { + "stripUnknown": Object { + "objects": false, + }, + }, + "type": "object", + }, + ], + "type": "array", + }, "index": Object { "flags": Object { "error": [Function], diff --git a/x-pack/plugins/apm/public/components/alerting/ui_components/alerting_flyout/index.tsx b/x-pack/plugins/apm/public/components/alerting/ui_components/alerting_flyout/index.tsx index 95820bf8f84d4..c671bc2dda540 100644 --- a/x-pack/plugins/apm/public/components/alerting/ui_components/alerting_flyout/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/ui_components/alerting_flyout/index.tsx @@ -8,6 +8,7 @@ import React, { useCallback, useMemo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { ApmRuleType } from '@kbn/rule-data-utils'; +import type { RuleTypeParams } from '@kbn/alerting-plugin/common'; import { APM_SERVER_FEATURE_ID } from '../../../../../common/rules/apm_rule_types'; import { getInitialAlertValues } from '../../utils/get_initial_alert_values'; import { ApmPluginStartDeps } from '../../../../plugin'; @@ -35,7 +36,7 @@ export function AlertingFlyout(props: Props) { const { start, end } = useTimeRange({ rangeFrom, rangeTo, optional: true }); const environment = - 'environment' in query ? query.environment : ENVIRONMENT_ALL.value; + 'environment' in query ? query.environment! : ENVIRONMENT_ALL.value; const transactionType = 'transactionType' in query ? query.transactionType : undefined; const transactionName = @@ -53,7 +54,10 @@ export function AlertingFlyout(props: Props) { const addAlertFlyout = useMemo( () => ruleType && - services.triggersActionsUi.getAddRuleFlyout({ + services.triggersActionsUi.getAddRuleFlyout< + RuleTypeParams, + AlertMetadata + >({ consumer: APM_SERVER_FEATURE_ID, onClose: onCloseAddFlyout, ruleTypeId: ruleType, @@ -67,7 +71,7 @@ export function AlertingFlyout(props: Props) { errorGroupingKey, start, end, - } as AlertMetadata, + }, useRuleProducer: true, }), /* eslint-disable-next-line react-hooks/exhaustive-deps */ diff --git a/x-pack/plugins/apm/public/components/alerting/utils/helper.ts b/x-pack/plugins/apm/public/components/alerting/utils/helper.ts index 7cc0d958aaf9e..66cfe522388f7 100644 --- a/x-pack/plugins/apm/public/components/alerting/utils/helper.ts +++ b/x-pack/plugins/apm/public/components/alerting/utils/helper.ts @@ -6,9 +6,11 @@ */ import { TIME_UNITS } from '@kbn/triggers-actions-ui-plugin/public'; +import type { RuleTypeMetaData } from '@kbn/alerting-plugin/common'; + import moment from 'moment'; -export interface AlertMetadata { +export interface AlertMetadata extends RuleTypeMetaData { environment: string; serviceName?: string; transactionType?: string; diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap index b963137281b70..a9a77b477f1a2 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap @@ -28,7 +28,6 @@ Array [ }, ], "dataView": undefined, - "filterQuery": "", "groupBy": Array [ "host.hostname", ], @@ -46,6 +45,13 @@ Array [ "timeSize": 15, "timeUnit": "m", }, + "searchConfiguration": Object { + "index": "mockedIndex", + "query": Object { + "language": "kuery", + "query": "host.hostname: Users-System.local and service.type: system", + }, + }, "seriesType": "bar_stacked", "timeRange": Object { "from": "2023-03-28T10:43:13.802Z", diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx index 2506516efd81a..f07a6ddac4501 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import { Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useEffect, useState } from 'react'; @@ -54,7 +53,6 @@ import { LogRateAnalysis } from './log_rate_analysis'; import { Groups } from './groups'; import { Tags } from './tags'; import { RuleConditionChart } from '../rule_condition_chart/rule_condition_chart'; -import { getFilterQuery } from './helpers/get_filter_query'; // TODO Use a generic props for app sections https://github.com/elastic/kibana/issues/152690 export type CustomThresholdRule = Rule; @@ -118,7 +116,6 @@ export default function AlertDetailsAppSection({ const { euiTheme } = useEuiTheme(); const hasLogRateAnalysisLicense = hasAtLeast('platinum'); const [dataView, setDataView] = useState(); - const [filterQuery, setFilterQuery] = useState(''); const [, setDataViewError] = useState(); const ruleParams = rule.params as RuleTypeParams & AlertParams; const chartProps = { @@ -204,11 +201,6 @@ export default function AlertDetailsAppSection({ setAlertSummaryFields(alertSummaryFields); }, [groups, tags, rule, ruleLink, setAlertSummaryFields]); - useEffect(() => { - const query = `${(ruleParams.searchConfiguration?.query as Query)?.query as string}`; - setFilterQuery(getFilterQuery(query, groups)); - }, [groups, ruleParams.searchConfiguration]); - useEffect(() => { const initDataView = async () => { const ruleSearchConfiguration = ruleParams.searchConfiguration; @@ -271,7 +263,7 @@ export default function AlertDetailsAppSection({ {
); diff --git a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx index cd93a5e134c2b..19a1c0fcd164e 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx @@ -405,7 +405,7 @@ export default function Expressions(props: Props) { indexPatterns={dataView ? [dataView] : undefined} showQueryInput={true} showQueryMenu={false} - showFilterBar={false} + showFilterBar={!!ruleParams.searchConfiguration?.filter} showDatePicker={false} showSubmitButton={false} displayStyle="inPage" @@ -413,6 +413,16 @@ export default function Expressions(props: Props) { onQuerySubmit={onFilterChange} dataTestSubj="thresholdRuleUnifiedSearchBar" query={ruleParams.searchConfiguration?.query as Query} + filters={ruleParams.searchConfiguration?.filter} + onFiltersUpdated={(filter) => { + // Since rule params will be sent to the API as is, and we only need meta and query parameters to be + // saved in the rule's saved object, we filter extra fields here (such as $state). + const filters = filter.map(({ meta, query }) => ({ meta, query })); + setRuleParams('searchConfiguration', { + ...ruleParams.searchConfiguration, + filter: filters, + }); + }} /> {errors.filterQuery && ( @@ -454,7 +464,7 @@ export default function Expressions(props: Props) { { - const groupByFilters = Object.values(group.bucketKey).map((key, index) => { - return { - match: { - [groupByFields[index]]: key, - }, - }; - }); + const groupByQueries: QueryDslQueryContainer[] = Object.values(group.bucketKey).map( + (key, index) => { + return { + match: { + [groupByFields[index]]: key, + }, + }; + } + ); + const query = createBoolQuery( + currentTimeFrame, + timeFieldName, + searchConfiguration, + groupByQueries + ); return [ { index: indexPattern }, { size: 0, terminate_after: 1, track_total_hits: true, - query: { - bool: { - filter: [...baseFilters, ...groupByFilters], - }, - }, + query, }, ]; }); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/evaluate_rule.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/evaluate_rule.ts index 59f5801613dd0..87b7d9983465b 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/evaluate_rule.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/evaluate_rule.ts @@ -69,7 +69,7 @@ export const evaluateRule = async { @@ -27,6 +28,18 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { threshold: [1], comparator: Comparator.GT, }; + const searchConfiguration: SearchConfigurationType = { + index: { + id: 'dataset-logs-*-*', + name: 'All logs', + timeFieldName: '@timestamp', + title: 'logs-*-*', + }, + query: { + language: 'kuery', + query: '', + }, + }; const groupBy = 'host.doggoname'; const timeFieldName = 'mockedTimeFieldName'; @@ -35,13 +48,14 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { end: moment().valueOf(), }; - describe('when passed no filterQuery', () => { + describe('when passed no KQL query', () => { const searchBody = getElasticsearchMetricQuery( expressionParams, timeframe, timeFieldName, 100, true, + searchConfiguration, void 0, groupBy ); @@ -78,11 +92,18 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { }); }); - describe('when passed a filterQuery', () => { + describe('when passed a KQL query', () => { // This is adapted from a real-world query that previously broke alerts // We want to make sure it doesn't override any existing filters // https://github.com/elastic/kibana/issues/68492 - const filterQuery = 'NOT host.name:dv* and NOT host.name:ts*'; + const query = 'NOT host.name:dv* and NOT host.name:ts*'; + const currentSearchConfiguration = { + ...searchConfiguration, + query: { + language: 'kuery', + query, + }, + }; const searchBody = getElasticsearchMetricQuery( expressionParams, @@ -90,9 +111,9 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { timeFieldName, 100, true, + currentSearchConfiguration, void 0, - groupBy, - filterQuery + groupBy ); test('includes a range filter', () => { expect( @@ -164,4 +185,60 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { ); }); }); + + describe('when passed a filter', () => { + const currentSearchConfiguration = { + ...searchConfiguration, + query: { + language: 'kuery', + query: '', + }, + filter: [ + { + meta: { + alias: null, + disabled: false, + field: 'service.name', + key: 'service.name', + negate: false, + params: { + query: 'synth-node-2', + }, + type: 'phrase', + index: 'dataset-logs-*-*', + }, + query: { + match_phrase: { + 'service.name': 'synth-node-2', + }, + }, + }, + ], + }; + + const searchBody = getElasticsearchMetricQuery( + expressionParams, + timeframe, + timeFieldName, + 100, + true, + currentSearchConfiguration, + void 0, + groupBy + ); + test('includes a range filter', () => { + expect( + searchBody.query.bool.filter.find((filter) => filter.hasOwnProperty('range')) + ).toBeTruthy(); + }); + + test('includes a metric field filter', () => { + expect(searchBody.query.bool.filter).toMatchObject( + expect.arrayContaining([ + { range: { mockedTimeFieldName: expect.any(Object) } }, + { match_phrase: { 'service.name': 'synth-node-2' } }, + ]) + ); + }); + }); }); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.ts index 3cc1eee92fec9..14c18e4af1334 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.ts @@ -6,10 +6,14 @@ */ import moment from 'moment'; +import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import { Filter } from '@kbn/es-query'; import { Aggregators, CustomMetricExpressionParams, } from '../../../../../common/custom_threshold_rule/types'; +import { getSearchConfigurationBoolQuery } from '../../../../utils/get_parsed_filtered_query'; +import { SearchConfigurationType } from '../types'; import { createCustomMetricsAggregations } from './create_custom_metrics_aggregations'; import { CONTAINER_ID, @@ -20,7 +24,6 @@ import { } from '../utils'; import { createBucketSelector } from './create_bucket_selector'; import { wrapInCurrentPeriod } from './wrap_in_period'; -import { getParsedFilterQuery } from '../../../../utils/get_parsed_filtered_query'; export const calculateCurrentTimeFrame = ( metricParams: CustomMetricExpressionParams, @@ -38,25 +41,30 @@ export const calculateCurrentTimeFrame = ( }; }; -export const createBaseFilters = ( +const QueryDslQueryContainerToFilter = (queries: QueryDslQueryContainer[]): Filter[] => { + return queries.map((query) => ({ + meta: {}, + query, + })); +}; + +export const createBoolQuery = ( timeframe: { start: number; end: number }, timeFieldName: string, - filterQuery?: string + searchConfiguration: SearchConfigurationType, + additionalQueries: QueryDslQueryContainer[] = [] ) => { - const rangeFilters = [ - { - range: { - [timeFieldName]: { - gte: moment(timeframe.start).toISOString(), - lte: moment(timeframe.end).toISOString(), - }, + const rangeQuery: QueryDslQueryContainer = { + range: { + [timeFieldName]: { + gte: moment(timeframe.start).toISOString(), + lte: moment(timeframe.end).toISOString(), }, }, - ]; - - const parsedFilterQuery = getParsedFilterQuery(filterQuery); + }; + const filters = QueryDslQueryContainerToFilter([rangeQuery, ...additionalQueries]); - return [...rangeFilters, ...parsedFilterQuery]; + return getSearchConfigurationBoolQuery(searchConfiguration, filters); }; export const getElasticsearchMetricQuery = ( @@ -65,9 +73,9 @@ export const getElasticsearchMetricQuery = ( timeFieldName: string, compositeSize: number, alertOnGroupDisappear: boolean, + searchConfiguration: SearchConfigurationType, lastPeriodEnd?: number, groupBy?: string | string[], - filterQuery?: string, afterKey?: Record, fieldsExisted?: Record | null ) => { @@ -196,15 +204,11 @@ export const getElasticsearchMetricQuery = ( aggs.groupings.composite.after = afterKey; } - const baseFilters = createBaseFilters(timeframe, timeFieldName, filterQuery); + const query = createBoolQuery(timeframe, timeFieldName, searchConfiguration); return { track_total_hits: true, - query: { - bool: { - filter: baseFilters, - }, - }, + query, size: 0, aggs, }; diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts index 5e9c2e0cea019..df64a67ca8e4a 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts @@ -58,6 +58,14 @@ export const searchConfigurationSchema = schema.object({ }), query: schema.string(), }), + filter: schema.maybe( + schema.arrayOf( + schema.object({ + query: schema.maybe(schema.recordOf(schema.string(), schema.any())), + meta: schema.recordOf(schema.string(), schema.any()), + }) + ) + ), }); type CreateLifecycleExecutor = ReturnType; diff --git a/x-pack/plugins/observability/server/utils/get_parsed_filtered_query.ts b/x-pack/plugins/observability/server/utils/get_parsed_filtered_query.ts index fabefa63f0695..033a6cadc282e 100644 --- a/x-pack/plugins/observability/server/utils/get_parsed_filtered_query.ts +++ b/x-pack/plugins/observability/server/utils/get_parsed_filtered_query.ts @@ -5,7 +5,14 @@ * 2.0. */ -import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { + BoolQuery, + buildEsQuery, + Filter, + fromKueryExpression, + toElasticsearchQuery, +} from '@kbn/es-query'; +import { SearchConfigurationType } from '../lib/rules/custom_threshold/types'; export const getParsedFilterQuery: (filter: string | undefined) => Array> = ( filter @@ -19,3 +26,24 @@ export const getParsedFilterQuery: (filter: string | undefined) => Array { bool: BoolQuery } = (searchConfiguration, additionalFilters) => { + try { + const searchConfigurationFilters = (searchConfiguration.filter as Filter[]) || []; + const filters = [...additionalFilters, ...searchConfigurationFilters]; + + return buildEsQuery(undefined, searchConfiguration.query, filters, {}); + } catch (error) { + return { + bool: { + must: [], + must_not: [], + filter: [], + should: [], + }, + }; + } +}; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts b/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts index 90d51f75e8c7c..639d4bdb2b0d1 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts @@ -16,7 +16,7 @@ import { GridColumnDisplayOptions, GridRowsDisplayOptions, } from '../../common'; -import { ControlOptions, OptionsListControlOption } from '../controller'; +import type { ControlOptions, OptionsListControl } from '../controller'; export const getGridColumnDisplayOptionsFromDiscoverAppState = ( discoverAppState: DiscoverAppState @@ -79,55 +79,78 @@ const createDiscoverPhrasesFilter = ({ key, values, negate, + index, }: { - values: PhraseFilterValue[]; + index: string; key: string; + values: PhraseFilterValue[]; negate?: boolean; -}): PhrasesFilter => - ({ - meta: { - key, - negate, - type: FILTERS.PHRASES, - params: values, - }, - query: { - bool: { - should: values.map((value) => ({ match_phrase: { [key]: value.toString() } })), - minimum_should_match: 1, - }, +}): PhrasesFilter => ({ + meta: { + index, + type: FILTERS.PHRASES, + key, + params: values.map((value) => value.toString()), + negate, + }, + query: { + bool: { + should: values.map((value) => ({ match_phrase: { [key]: value.toString() } })), + minimum_should_match: 1, }, - } as PhrasesFilter); + }, +}); const createDiscoverExistsFilter = ({ + index, key, negate, }: { key: string; + index: string; negate?: boolean; }): ExistsFilter => ({ meta: { + index, + type: FILTERS.EXISTS, + value: FILTERS.EXISTS, // Required for the filter to be displayed correctly in FilterBadge key, negate, - type: FILTERS.EXISTS, }, query: { exists: { field: key } }, }); -export const getDiscoverFiltersFromState = (filters: Filter[] = [], controls?: ControlOptions) => [ - ...filters, - ...(controls - ? (Object.keys(controls) as Array).map((key) => - controls[key as keyof ControlOptions]?.selection.type === 'exists' - ? createDiscoverExistsFilter({ - key, - negate: controls[key]?.mode === 'exclude', - }) - : createDiscoverPhrasesFilter({ - key, - values: (controls[key]?.selection as OptionsListControlOption).selectedOptions, - negate: controls[key]?.mode === 'exclude', - }) - ) - : []), -]; +export const getDiscoverFiltersFromState = ( + index: string, + filters: Filter[] = [], + controls?: ControlOptions +) => { + return [ + ...filters, + ...(controls + ? (Object.entries(controls) as Array<[keyof ControlOptions, OptionsListControl]>).reduce< + Filter[] + >((acc, [key, control]) => { + if (control.selection.type === 'exists') { + acc.push( + createDiscoverExistsFilter({ + index, + key, + negate: control.mode === 'exclude', + }) + ); + } else if (control.selection.selectedOptions.length > 0) { + acc.push( + createDiscoverPhrasesFilter({ + index, + key, + values: control.selection.selectedOptions, + negate: control.mode === 'exclude', + }) + ); + } + return acc; + }, []) + : []), + ]; +}; diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/kibana.jsonc b/x-pack/plugins/observability_solution/observability_logs_explorer/kibana.jsonc index 42d762820aaad..8f6e248557efa 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/kibana.jsonc @@ -23,7 +23,12 @@ "datasetQuality" ], "optionalPlugins": [ - "serverless" + "serverless", + "triggersActionsUi", + "unifiedSearch", + "dataViews", + "dataViewEditor", + "lens" ], "requiredBundles": [ "kibanaReact" diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/applications/observability_logs_explorer.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/applications/observability_logs_explorer.tsx index 5f6739a5dfe3d..cab3742c06f05 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/applications/observability_logs_explorer.tsx +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/applications/observability_logs_explorer.tsx @@ -6,6 +6,7 @@ */ import { CoreStart } from '@kbn/core/public'; +import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { Route, Router, Routes } from '@kbn/shared-ux-router'; import React from 'react'; @@ -57,6 +58,7 @@ export const ObservabilityLogsExplorerApp = ({ plugins, pluginStart, }: ObservabilityLogsExplorerAppProps) => { + const isDarkMode = core.theme.getTheme().darkMode; const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider( core, plugins, @@ -69,10 +71,20 @@ export const ObservabilityLogsExplorerApp = ({ - - } /> - } /> - + + + } + /> + } + /> + + diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/alerts_popover.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/alerts_popover.tsx new file mode 100644 index 0000000000000..22f689010a2df --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/alerts_popover.tsx @@ -0,0 +1,142 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiPopover, EuiButtonEmpty, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui'; +import React, { useMemo, useReducer } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { useActor } from '@xstate/react'; +import { hydrateDatasetSelection } from '@kbn/logs-explorer-plugin/common'; +import { getDiscoverFiltersFromState } from '@kbn/logs-explorer-plugin/public'; +import type { AlertParams } from '@kbn/observability-plugin/public/components/custom_threshold/types'; +import { useLinkProps } from '@kbn/observability-shared-plugin/public'; +import { useKibanaContextForPlugin } from '../utils/use_kibana'; +import { useObservabilityLogsExplorerPageStateContext } from '../state_machines/observability_logs_explorer/src'; + +type ThresholdRuleTypeParams = Pick; + +interface AlertsPopoverState { + isPopoverOpen: boolean; + isAddRuleFlyoutOpen: boolean; +} + +type AlertsPopoverAction = + | { + type: 'togglePopover'; + isOpen?: boolean; + } + | { + type: 'toggleAddRuleFlyout'; + isOpen?: boolean; + }; + +function alertsPopoverReducer(state: AlertsPopoverState, action: AlertsPopoverAction) { + switch (action.type) { + case 'togglePopover': + return { + isPopoverOpen: action.isOpen ?? !state.isPopoverOpen, + isAddRuleFlyoutOpen: state.isAddRuleFlyoutOpen, + }; + + case 'toggleAddRuleFlyout': + return { + isPopoverOpen: false, + isAddRuleFlyoutOpen: action.isOpen ?? !state.isAddRuleFlyoutOpen, + }; + + default: + return state; + } +} + +export const AlertsPopover = () => { + const { + services: { triggersActionsUi }, + } = useKibanaContextForPlugin(); + + const manageRulesLinkProps = useLinkProps({ app: 'observability', pathname: '/alerts/rules' }); + + const [pageState] = useActor(useObservabilityLogsExplorerPageStateContext()); + + const [state, dispatch] = useReducer(alertsPopoverReducer, { + isPopoverOpen: false, + isAddRuleFlyoutOpen: false, + }); + + const togglePopover = () => dispatch({ type: 'togglePopover' }); + const closePopover = () => dispatch({ type: 'togglePopover', isOpen: false }); + const openAddRuleFlyout = () => dispatch({ type: 'toggleAddRuleFlyout', isOpen: true }); + const closeAddRuleFlyout = () => dispatch({ type: 'toggleAddRuleFlyout', isOpen: false }); + + const addRuleFlyout = useMemo(() => { + if ( + state.isAddRuleFlyoutOpen && + triggersActionsUi && + pageState.matches({ initialized: 'validLogsExplorerState' }) + ) { + const { logsExplorerState } = pageState.context; + const index = hydrateDatasetSelection(logsExplorerState.datasetSelection).toDataviewSpec(); + + return triggersActionsUi.getAddRuleFlyout({ + consumer: 'logs', + ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + canChangeTrigger: false, + initialValues: { + params: { + searchConfiguration: { + index, + query: logsExplorerState.query, + filter: getDiscoverFiltersFromState( + index.id, + logsExplorerState.filters, + logsExplorerState.controls + ), + }, + }, + }, + onClose: closeAddRuleFlyout, + }); + } + }, [triggersActionsUi, pageState, state.isAddRuleFlyoutOpen]); + + return ( + <> + {state.isAddRuleFlyoutOpen && addRuleFlyout} + + + + } + isOpen={state.isPopoverOpen} + closePopover={closePopover} + panelPaddingSize="none" + anchorPosition="downLeft" + > + + + , + + + , + ]} + /> + + + ); +}; diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx index b12390cc952a1..7c0b4596b4326 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx @@ -53,18 +53,22 @@ export const DiscoverLinkForValidState = React.memo( discover: DiscoverStart; pageState: InitializedPageState; }) => { - const discoverLinkParams = useMemo( - () => ({ + const discoverLinkParams = useMemo(() => { + const index = hydrateDatasetSelection(logsExplorerState.datasetSelection).toDataviewSpec(); + return { breakdownField: logsExplorerState.chart.breakdownField ?? undefined, columns: getDiscoverColumnsFromDisplayOptions(logsExplorerState), - filters: getDiscoverFiltersFromState(logsExplorerState.filters, logsExplorerState.controls), + filters: getDiscoverFiltersFromState( + index.id, + logsExplorerState.filters, + logsExplorerState.controls + ), query: logsExplorerState.query, refreshInterval: logsExplorerState.refreshInterval, timeRange: logsExplorerState.time, - dataViewSpec: hydrateDatasetSelection(logsExplorerState.datasetSelection).toDataviewSpec(), - }), - [logsExplorerState] - ); + dataViewSpec: index, + }; + }, [logsExplorerState]); return ; } 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 9c2ea0a5e4817..0f64f586ab3fd 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 @@ -26,6 +26,7 @@ import { useKibanaContextForPlugin } from '../utils/use_kibana'; import { ConnectedDiscoverLink } from './discover_link'; import { FeedbackLink } from './feedback_link'; import { ConnectedOnboardingLink } from './onboarding_link'; +import { AlertsPopover } from './alerts_popover'; export const LogsExplorerTopNavMenu = () => { const { @@ -67,6 +68,8 @@ const ServerlessTopNav = () => { + + {ObservabilityAIAssistantActionMenuItem ? ( ) : null} @@ -143,6 +146,8 @@ const StatefulTopNav = () => { + + {ObservabilityAIAssistantActionMenuItem ? ( ) : null} diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/types.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/public/types.ts index c3f094033f697..96754cfdab021 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/types.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/types.ts @@ -15,6 +15,11 @@ import { AppMountParameters, ScopedHistory } from '@kbn/core/public'; import { LogsSharedClientStartExports } from '@kbn/logs-shared-plugin/public'; import { DatasetQualityPluginStart } from '@kbn/dataset-quality-plugin/public'; import { ObservabilityAIAssistantPluginStart } from '@kbn/observability-ai-assistant-plugin/public'; +import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; +import { LensPublicStart } from '@kbn/lens-plugin/public'; import { ObservabilityLogsExplorerLocators, ObservabilityLogsExplorerLocationState, @@ -41,6 +46,11 @@ export interface ObservabilityLogsExplorerStartDeps { observabilityAIAssistant: ObservabilityAIAssistantPluginStart; observabilityShared: ObservabilitySharedPluginStart; serverless?: ServerlessPluginStart; + triggersActionsUi?: TriggersAndActionsUIPublicPluginStart; + unifiedSearch?: UnifiedSearchPublicPluginStart; + dataViews?: DataViewsPublicPluginStart; + dataViewEditor?: DataViewEditorStart; + lens?: LensPublicStart; share: SharePluginStart; datasetQuality: DatasetQualityPluginStart; } diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json b/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json index 7192e3001a70b..c434a418c4246 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json @@ -38,6 +38,13 @@ "@kbn/xstate-utils", "@kbn/router-utils", "@kbn/observability-ai-assistant-plugin", + "@kbn/rule-data-utils", + "@kbn/observability-plugin", + "@kbn/triggers-actions-ui-plugin", + "@kbn/unified-search-plugin", + "@kbn/data-views-plugin", + "@kbn/data-view-editor-plugin", + "@kbn/lens-plugin", ], "exclude": [ "target/**/*" diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/index.tsx index dfab594febf10..1a99e346ed808 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/index.tsx @@ -7,6 +7,13 @@ import { lazy } from 'react'; import { suspendedComponentWithProps } from '../../lib/suspended_component_with_props'; +import type { RuleAddComponent } from './rule_add'; +import type { RuleEditComponent } from './rule_edit'; -export const RuleAdd = suspendedComponentWithProps(lazy(() => import('./rule_add'))); -export const RuleEdit = suspendedComponentWithProps(lazy(() => import('./rule_edit'))); +export const RuleAdd = suspendedComponentWithProps( + lazy(() => import('./rule_add')) +) as RuleAddComponent; // `React.lazy` is not typed correctly to support generics so casting back to imported component + +export const RuleEdit = suspendedComponentWithProps( + lazy(() => import('./rule_edit')) +) as RuleEditComponent; // `React.lazy` is not typed correctly to support generics so casting back to imported component diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx index 07264709dd544..19eb8da4bf0d3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx @@ -15,6 +15,7 @@ import { parseRuleCircuitBreakerErrorMessage } from '@kbn/alerting-plugin/common import { Rule, RuleTypeParams, + RuleTypeMetaData, RuleUpdates, RuleFlyoutCloseReason, IErrorObject, @@ -49,7 +50,12 @@ const defaultCreateRuleErrorMessage = i18n.translate( } ); -const RuleAdd = ({ +export type RuleAddComponent = typeof RuleAdd; + +const RuleAdd = < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +>({ consumer, ruleTypeRegistry, actionTypeRegistry, @@ -67,7 +73,7 @@ const RuleAdd = ({ useRuleProducer, initialSelectedConsumer, ...props -}: RuleAddProps) => { +}: RuleAddProps) => { const onSaveHandler = onSave ?? reloadRules; const [metadata, setMetadata] = useState(initialMetadata); const onChangeMetaData = useCallback((newMetadata) => setMetadata(newMetadata), []); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx index 0aebaaaa29882..975881e516e45 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx @@ -34,6 +34,8 @@ import { RuleEditProps, IErrorObject, RuleType, + RuleTypeParams, + RuleTypeMetaData, TriggersActionsUiConfig, RuleNotifyWhenType, } from '../../../types'; @@ -81,7 +83,12 @@ const cloneAndMigrateRule = (initialRule: Rule) => { return clonedRule; }; -export const RuleEdit = ({ +export type RuleEditComponent = typeof RuleEdit; + +export const RuleEdit = < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +>({ initialRule, onClose, reloadRules, @@ -91,7 +98,7 @@ export const RuleEdit = ({ actionTypeRegistry, metadata: initialMetadata, ...props -}: RuleEditProps) => { +}: RuleEditProps) => { const onSaveHandler = onSave ?? reloadRules; const [{ rule }, dispatch] = useReducer(ruleReducer as ConcreteRuleReducer, { rule: cloneAndMigrateRule(initialRule), diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_add_rule_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_add_rule_flyout.tsx index 23f751201d1be..c6a79b4c6e82d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/get_add_rule_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_add_rule_flyout.tsx @@ -9,11 +9,14 @@ import React from 'react'; import { QueryClientProvider } from '@tanstack/react-query'; import { ConnectorProvider } from '../application/context/connector_context'; import { RuleAdd } from '../application/sections/rule_form'; -import type { ConnectorServices, RuleAddProps } from '../types'; +import type { ConnectorServices, RuleAddProps, RuleTypeParams, RuleTypeMetaData } from '../types'; import { queryClient } from '../application/query_client'; -export const getAddRuleFlyoutLazy = ( - props: RuleAddProps & { connectorServices: ConnectorServices } +export const getAddRuleFlyoutLazy = < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +>( + props: RuleAddProps & { connectorServices: ConnectorServices } ) => { return ( diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_edit_rule_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_edit_rule_flyout.tsx index 2d99e3911a168..f3fbccce267c5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/get_edit_rule_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_edit_rule_flyout.tsx @@ -9,11 +9,14 @@ import React from 'react'; import { QueryClientProvider } from '@tanstack/react-query'; import { ConnectorProvider } from '../application/context/connector_context'; import { RuleEdit } from '../application/sections/rule_form'; -import type { ConnectorServices, RuleEditProps as AlertEditProps } from '../types'; +import type { ConnectorServices, RuleEditProps, RuleTypeParams, RuleTypeMetaData } from '../types'; import { queryClient } from '../application/query_client'; -export const getEditRuleFlyoutLazy = ( - props: AlertEditProps & { connectorServices: ConnectorServices } +export const getEditRuleFlyoutLazy = < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +>( + props: RuleEditProps & { connectorServices: ConnectorServices } ) => { return ( diff --git a/x-pack/plugins/triggers_actions_ui/public/mocks.ts b/x-pack/plugins/triggers_actions_ui/public/mocks.ts index 223a54205cb48..48691c15ed62f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/mocks.ts +++ b/x-pack/plugins/triggers_actions_ui/public/mocks.ts @@ -15,8 +15,6 @@ import { getEditRuleFlyoutLazy } from './common/get_edit_rule_flyout'; import { TypeRegistry } from './application/type_registry'; import { ActionTypeModel, - RuleAddProps, - RuleEditProps, RuleTypeModel, AlertsTableProps, FieldBrowserProps, @@ -73,7 +71,7 @@ function createStartMock(): TriggersAndActionsUIPublicPluginStart { connectorServices, }); }, - getAddRuleFlyout: (props: Omit) => { + getAddRuleFlyout: (props) => { return getAddRuleFlyoutLazy({ ...props, actionTypeRegistry, @@ -81,7 +79,7 @@ function createStartMock(): TriggersAndActionsUIPublicPluginStart { connectorServices, }); }, - getEditRuleFlyout: (props: Omit) => { + getEditRuleFlyout: (props) => { return getEditRuleFlyoutLazy({ ...props, actionTypeRegistry, diff --git a/x-pack/plugins/triggers_actions_ui/public/plugin.ts b/x-pack/plugins/triggers_actions_ui/public/plugin.ts index 872528a9a5f85..bcd639e21a2ff 100644 --- a/x-pack/plugins/triggers_actions_ui/public/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/public/plugin.ts @@ -62,6 +62,8 @@ import type { RuleAddProps, RuleEditProps, RuleTypeModel, + RuleTypeParams, + RuleTypeMetaData, AlertsTableProps, RuleStatusDropdownProps, RuleTagFilterProps, @@ -115,12 +117,18 @@ export interface TriggersAndActionsUIPublicPluginStart { getEditConnectorFlyout: ( props: Omit ) => ReactElement; - getAddRuleFlyout: ( - props: Omit - ) => ReactElement; - getEditRuleFlyout: ( - props: Omit - ) => ReactElement; + getAddRuleFlyout: < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData + >( + props: Omit, 'actionTypeRegistry' | 'ruleTypeRegistry'> + ) => ReactElement>; + getEditRuleFlyout: < + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData + >( + props: Omit, 'actionTypeRegistry' | 'ruleTypeRegistry'> + ) => ReactElement>; getAlertsTable: (props: AlertsTableProps) => ReactElement; getAlertsTableDefaultAlertActions:

( props: P @@ -403,7 +411,7 @@ export class Plugin connectorServices: this.connectorServices!, }); }, - getAddRuleFlyout: (props: Omit) => { + getAddRuleFlyout: (props) => { return getAddRuleFlyoutLazy({ ...props, actionTypeRegistry: this.actionTypeRegistry, @@ -411,9 +419,7 @@ export class Plugin connectorServices: this.connectorServices!, }); }, - getEditRuleFlyout: ( - props: Omit - ) => { + getEditRuleFlyout: (props) => { return getEditRuleFlyoutLazy({ ...props, actionTypeRegistry: this.actionTypeRegistry, diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index b47d80a0839e5..36cc294bbda5f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -51,6 +51,7 @@ import { AlertingFrameworkHealth, RuleNotifyWhenType, RuleTypeParams, + RuleTypeMetaData, ActionVariable, RuleLastRun, MaintenanceWindow, @@ -127,6 +128,7 @@ export type { AlertingFrameworkHealth, RuleNotifyWhenType, RuleTypeParams, + RuleTypeMetaData, ResolvedRule, SanitizedRule, RuleStatusDropdownProps, @@ -412,8 +414,11 @@ export enum EditConnectorTabs { Test = 'test', } -export interface RuleEditProps> { - initialRule: Rule; +export interface RuleEditProps< + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +> { + initialRule: Rule; ruleTypeRegistry: RuleTypeRegistryContract; actionTypeRegistry: ActionTypeRegistryContract; onClose: (reason: RuleFlyoutCloseReason, metadata?: MetaData) => void; @@ -425,14 +430,27 @@ export interface RuleEditProps> { ruleType?: RuleType; } -export interface RuleAddProps> { +export interface RuleAddProps< + Params extends RuleTypeParams = RuleTypeParams, + MetaData extends RuleTypeMetaData = RuleTypeMetaData +> { + /** + * ID of the feature this rule should be created for. + * + * Notes: + * - The feature needs to be registered using `featuresPluginSetup.registerKibanaFeature()` API during your plugin's setup phase. + * - The user needs to have permission to access the feature in order to create the rule. + * */ consumer: string; ruleTypeRegistry: RuleTypeRegistryContract; actionTypeRegistry: ActionTypeRegistryContract; onClose: (reason: RuleFlyoutCloseReason, metadata?: MetaData) => void; ruleTypeId?: string; + /** + * Determines whether the user should be able to change the rule type in the UI. + */ canChangeTrigger?: boolean; - initialValues?: Partial; + initialValues?: Partial>; /** @deprecated use `onSave` as a callback after an alert is saved*/ reloadRules?: () => Promise; hideGrouping?: boolean; @@ -445,8 +463,8 @@ export interface RuleAddProps> { useRuleProducer?: boolean; initialSelectedConsumer?: RuleCreationValidConsumer | null; } -export interface RuleDefinitionProps { - rule: Rule; +export interface RuleDefinitionProps { + rule: Rule; ruleTypeRegistry: RuleTypeRegistryContract; actionTypeRegistry: ActionTypeRegistryContract; onEditRule: () => Promise; From 9591304b0d9900249dca6a39cb7fe7360f90666f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 9 Feb 2024 10:11:48 +0200 Subject: [PATCH 058/104] [Obs ai assistant] Use context to handle the multipane flyout (#176373) ## Summary Use a context to handle the multipane flyout properties that are needed for the `visualize_esql` function. ### How to test Should work exactly as before. The editing flyout should open when the user clicks the pencil button on a lens embeddable image --- .../public/components/chat/chat_body.tsx | 9 +- .../public/components/chat/chat_flyout.tsx | 220 +++++++++--------- .../public/components/chat/chat_timeline.tsx | 16 +- .../public/components/render_function.tsx | 11 +- ...ai_assistant_multipane_flyout_provider.tsx | 16 ++ .../public/functions/visualize_esql.test.tsx | 24 +- .../public/functions/visualize_esql.tsx | 20 +- .../conversations/conversation_view.tsx | 4 - .../public/service/create_chat_service.ts | 3 +- .../public/types.ts | 5 +- ..._timeline_items_from_conversation.test.tsx | 7 +- .../get_timeline_items_from_conversation.tsx | 5 +- 12 files changed, 157 insertions(+), 183 deletions(-) create mode 100644 x-pack/plugins/observability_ai_assistant/public/context/observability_ai_assistant_multipane_flyout_provider.tsx diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx index 8ed26d71acc58..a89419c366a2d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx @@ -35,11 +35,7 @@ import { ChatTimeline } from './chat_timeline'; import { Feedback } from '../feedback_buttons'; import { IncorrectLicensePanel } from './incorrect_license_panel'; import { WelcomeMessage } from './welcome_message'; -import { - ChatActionClickHandler, - ChatActionClickType, - type ChatFlyoutSecondSlotHandler, -} from './types'; +import { ChatActionClickHandler, ChatActionClickType } from './types'; import { ASSISTANT_SETUP_TITLE, EMPTY_CONVERSATION_TITLE, UPGRADE_LICENSE_TITLE } from '../../i18n'; import type { StartedFrom } from '../../utils/get_timeline_items_from_conversation'; import { TELEMETRY, sendEvent } from '../../analytics'; @@ -94,7 +90,6 @@ const animClassName = css` const PADDING_AND_BORDER = 32; export function ChatBody({ - chatFlyoutSecondSlotHandler, connectors, currentUser, flyoutWidthMode, @@ -107,7 +102,6 @@ export function ChatBody({ onConversationUpdate, onToggleFlyoutWidthMode, }: { - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; connectors: UseGenAIConnectorsResult; currentUser?: Pick; flyoutWidthMode?: FlyoutWidthMode; @@ -362,7 +356,6 @@ export function ChatBody({ onStopGenerating={() => { stop(); }} - chatFlyoutSecondSlotHandler={chatFlyoutSecondSlotHandler} onActionClick={handleActionClick} /> )} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx index 6823153397ca4..5a8b0ee3b3776 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx @@ -18,6 +18,7 @@ import { EuiToolTip, useEuiTheme, } from '@elastic/eui'; +import { ObservabilityAIAssistantMultipaneFlyoutProvider } from '../../context/observability_ai_assistant_multipane_flyout_provider'; import { useForceUpdate } from '../../hooks/use_force_update'; import { useCurrentUser } from '../../hooks/use_current_user'; import { useGenAIConnectors } from '../../hooks/use_genai_connectors'; @@ -134,133 +135,136 @@ export function ChatFlyout({ }; return isOpen ? ( - { - onClose(); - setIsSecondSlotVisible(false); - if (secondSlotContainer) { - ReactDOM.unmountComponentAtNode(secondSlotContainer); - } + - - - - setConversationsExpanded(!conversationsExpanded)} - /> - - } - /> - - {conversationsExpanded ? ( - - ) : ( + { + onClose(); + setIsSecondSlotVisible(false); + if (secondSlotContainer) { + ReactDOM.unmountComponentAtNode(secondSlotContainer); + } + }} + > + + setConversationsExpanded(!conversationsExpanded)} /> } - className={newChatButtonClassName} /> - )} - - - { - setConversationId(conversation.conversation.id); - }} - onToggleFlyoutWidthMode={handleToggleFlyoutWidthMode} - /> - + {conversationsExpanded ? ( + + ) : ( + + + + } + className={newChatButtonClassName} + /> + )} + - - + { + setConversationId(conversation.conversation.id); + }} + onToggleFlyoutWidthMode={handleToggleFlyoutWidthMode} + /> + + + - - - + > + + + + + ) : null; } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx index 48cf4070b0b96..0baccaf979f1f 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx @@ -13,7 +13,7 @@ import { omit } from 'lodash'; import type { Feedback } from '../feedback_buttons'; import type { Message } from '../../../common'; import type { UseKnowledgeBaseResult } from '../../hooks/use_knowledge_base'; -import type { ChatActionClickHandler, ChatFlyoutSecondSlotHandler } from './types'; +import type { ChatActionClickHandler } from './types'; import type { ObservabilityAIAssistantChatService } from '../../types'; import type { TelemetryEventTypeWithPayload } from '../../analytics'; import { ChatItem } from './chat_item'; @@ -54,7 +54,6 @@ export interface ChatTimelineProps { chatState: ChatState; currentUser?: Pick; startedFrom?: StartedFrom; - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; onEdit: (message: Message, messageAfterEdit: Message) => void; onFeedback: (message: Message, feedback: Feedback) => void; onRegenerate: (message: Message) => void; @@ -69,7 +68,6 @@ export function ChatTimeline({ hasConnector, currentUser, startedFrom, - chatFlyoutSecondSlotHandler, onEdit, onFeedback, onRegenerate, @@ -86,7 +84,6 @@ export function ChatTimeline({ currentUser, startedFrom, chatState, - chatFlyoutSecondSlotHandler, onActionClick, }); @@ -110,16 +107,7 @@ export function ChatTimeline({ } return consolidatedChatItems; - }, [ - chatService, - hasConnector, - messages, - currentUser, - startedFrom, - chatState, - chatFlyoutSecondSlotHandler, - onActionClick, - ]); + }, [chatService, hasConnector, messages, currentUser, startedFrom, chatState, onActionClick]); return ( - {chatService.renderFunction( - props.name, - props.arguments, - props.response, - props.onActionClick, - props.chatFlyoutSecondSlotHandler - )} + {chatService.renderFunction(props.name, props.arguments, props.response, props.onActionClick)} ); } diff --git a/x-pack/plugins/observability_ai_assistant/public/context/observability_ai_assistant_multipane_flyout_provider.tsx b/x-pack/plugins/observability_ai_assistant/public/context/observability_ai_assistant_multipane_flyout_provider.tsx new file mode 100644 index 0000000000000..93a091ff4a7d4 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/context/observability_ai_assistant_multipane_flyout_provider.tsx @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createContext } from 'react'; +import type { ChatFlyoutSecondSlotHandler } from '../types'; + +export const ObservabilityAIAssistantMultipaneFlyoutContext = createContext< + ChatFlyoutSecondSlotHandler | undefined +>(undefined); + +export const ObservabilityAIAssistantMultipaneFlyoutProvider = + ObservabilityAIAssistantMultipaneFlyoutContext.Provider; diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.test.tsx b/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.test.tsx index 789697fbaaaa8..de7c4f04f241c 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.test.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.test.tsx @@ -12,6 +12,7 @@ import type { LensPublicStart } from '@kbn/lens-plugin/public'; import { lensPluginMock } from '@kbn/lens-plugin/public/mocks/lens_plugin_mock'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { ObservabilityAIAssistantMultipaneFlyoutProvider } from '../context/observability_ai_assistant_multipane_flyout_provider'; import { VisualizeESQL } from './visualize_esql'; describe('VisualizeESQL', () => { @@ -50,19 +51,22 @@ describe('VisualizeESQL', () => { }, ] as DatatableColumn[]; render( - + > + + ); } diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.tsx b/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.tsx index 05145c6130b4f..61295f4faf6f7 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/functions/visualize_esql.tsx @@ -22,7 +22,7 @@ import type { TypedLensByValueInput, InlineEditLensEmbeddableContext, } from '@kbn/lens-plugin/public'; -import React, { useState, useEffect, useCallback, useMemo } from 'react'; +import React, { useState, useEffect, useCallback, useMemo, useContext } from 'react'; import ReactDOM from 'react-dom'; import useAsync from 'react-use/lib/useAsync'; import { getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; @@ -30,17 +30,14 @@ import { VisualizeESQLFunctionArguments, VisualizeESQLUserIntention, } from '../../common/functions/visualize_esql'; +import { ObservabilityAIAssistantMultipaneFlyoutContext } from '../context/observability_ai_assistant_multipane_flyout_provider'; import type { ObservabilityAIAssistantPluginStartDependencies, ObservabilityAIAssistantService, RegisterRenderFunctionDefinition, RenderFunction, } from '../types'; -import { - type ChatActionClickHandler, - ChatActionClickType, - ChatFlyoutSecondSlotHandler, -} from '../components/chat/types'; +import { type ChatActionClickHandler, ChatActionClickType } from '../components/chat/types'; interface VisualizeLensResponse { content: DatatableColumn[]; @@ -63,12 +60,6 @@ interface VisualizeESQLProps { * If not given, the embeddable gets them from the suggestions api */ userOverrides?: unknown; - /** Optional, should be passed if the embeddable is rendered in a flyout - * If not given, the inline editing push flyout won't open - * The code will be significantly improved, - * if this is addressed https://github.com/elastic/eui/issues/7443 - */ - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; /** User's preferation chart type as it comes from the model */ preferredChartType?: string; } @@ -85,7 +76,6 @@ export function VisualizeESQL({ query, onActionClick, userOverrides, - chatFlyoutSecondSlotHandler, preferredChartType, }: VisualizeESQLProps) { // fetch the pattern from the query @@ -100,6 +90,8 @@ export function VisualizeESQL({ }); }, [indexPattern]); + const chatFlyoutSecondSlotHandler = useContext(ObservabilityAIAssistantMultipaneFlyoutContext); + const [isSaveModalOpen, setIsSaveModalOpen] = useState(false); const [lensInput, setLensInput] = useState( userOverrides as TypedLensByValueInput @@ -316,7 +308,6 @@ export function registerVisualizeQueryRenderFunction({ arguments: { query, userOverrides, intention }, response, onActionClick, - chatFlyoutSecondSlotHandler, }: Parameters>[0]) => { const { content } = response as VisualizeLensResponse; @@ -370,7 +361,6 @@ export function registerVisualizeQueryRenderFunction({ query={query} onActionClick={onActionClick} userOverrides={userOverrides} - chatFlyoutSecondSlotHandler={chatFlyoutSecondSlotHandler} preferredChartType={preferredChartType} /> ); diff --git a/x-pack/plugins/observability_ai_assistant/public/routes/conversations/conversation_view.tsx b/x-pack/plugins/observability_ai_assistant/public/routes/conversations/conversation_view.tsx index 4620c0cf2775d..0f49389c1c60d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/routes/conversations/conversation_view.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/routes/conversations/conversation_view.tsx @@ -199,10 +199,6 @@ export function ConversationView() { showLinkToConversationsApp={false} startedFrom="conversationView" onConversationUpdate={handleConversationUpdate} - chatFlyoutSecondSlotHandler={{ - container: secondSlotContainer, - setVisibility: setIsSecondSlotVisible, - }} />

diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts index 211f25b045b77..17ea46c56681e 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts @@ -116,7 +116,7 @@ export async function createChatService({ return { analytics, - renderFunction: (name, args, response, onActionClick, chatFlyoutSecondSlotHandler) => { + renderFunction: (name, args, response, onActionClick) => { const fn = renderFunctionRegistry.get(name); if (!fn) { @@ -134,7 +134,6 @@ export async function createChatService({ response: parsedResponse, arguments: parsedArguments, onActionClick, - chatFlyoutSecondSlotHandler, }); }, getContexts: () => contextDefinitions, diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index 418c7eca16b19..e303b01a5c9e9 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -49,6 +49,7 @@ import type { UseGenAIConnectorsResult } from './hooks/use_genai_connectors'; export type { CreateChatCompletionResponseChunk } from '../common/types'; export type { PendingMessage }; +export type { ChatFlyoutSecondSlotHandler }; export interface ObservabilityAIAssistantChatService { analytics: AnalyticsServiceStart; @@ -76,8 +77,7 @@ export interface ObservabilityAIAssistantChatService { name: string, args: string | undefined, response: { data?: string; content?: string }, - onActionClick: ChatActionClickHandler, - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler + onActionClick: ChatActionClickHandler ) => React.ReactNode; } @@ -95,7 +95,6 @@ export type RenderFunction = (op arguments: TArguments; response: TResponse; onActionClick: ChatActionClickHandler; - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; }) => React.ReactNode; export type RegisterRenderFunctionDefinition< diff --git a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.test.tsx b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.test.tsx index 600256d66a7bc..8135111a6f548 100644 --- a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.test.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.test.tsx @@ -231,10 +231,6 @@ describe('getTimelineItemsFromConversation', () => { }, ], onActionClick: jest.fn(), - chatFlyoutSecondSlotHandler: { - container: null, - setVisibility: jest.fn(), - }, }); }); @@ -270,8 +266,7 @@ describe('getTimelineItemsFromConversation', () => { 'my_render_function', JSON.stringify({ foo: 'bar' }), { content: '[]', name: 'my_render_function', role: 'user' }, - expect.any(Function), - { container: null, setVisibility: expect.any(Function) } + expect.any(Function) ); expect(container.textContent).toEqual('Rendered'); diff --git a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx index 40b54708e5b6c..d1f14e30d6097 100644 --- a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx @@ -17,7 +17,7 @@ import { RenderFunction } from '../components/render_function'; import type { ObservabilityAIAssistantChatService } from '../types'; import { ChatState } from '../hooks/use_chat'; import { safeJsonParse } from './safe_json_parse'; -import type { ChatActionClickHandler, ChatFlyoutSecondSlotHandler } from '../components/chat/types'; +import type { ChatActionClickHandler } from '../components/chat/types'; function convertMessageToMarkdownCodeBlock(message: Message['message']) { let value: object; @@ -65,7 +65,6 @@ export function getTimelineItemsfromConversation({ messages, startedFrom, chatState, - chatFlyoutSecondSlotHandler, onActionClick, }: { chatService: ObservabilityAIAssistantChatService; @@ -74,7 +73,6 @@ export function getTimelineItemsfromConversation({ messages: Message[]; startedFrom?: StartedFrom; chatState: ChatState; - chatFlyoutSecondSlotHandler?: ChatFlyoutSecondSlotHandler; onActionClick: ChatActionClickHandler; }): ChatTimelineItem[] { const messagesWithoutSystem = messages.filter( @@ -169,7 +167,6 @@ export function getTimelineItemsfromConversation({ arguments={prevFunctionCall?.arguments} response={message.message} onActionClick={onActionClick} - chatFlyoutSecondSlotHandler={chatFlyoutSecondSlotHandler} /> ) : undefined; From 736af7b0e07512b7797e3759d076dbcebbb55b64 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Fri, 9 Feb 2024 09:15:18 +0100 Subject: [PATCH 059/104] [FTR] Fix URL checks in navigateToApp (#176546) ## Summary This PR fixes the URL check for successful navigation in the `common` PageObject `navigateToApp` method. --- test/functional/page_objects/common_page.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 653b0213bc430..98ac4d0abfe04 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -332,14 +332,16 @@ export class CommonPageObject extends FtrService { } currentUrl = (await this.browser.getCurrentUrl()).replace(/\/\/\w+:\w+@/, '//'); + const decodedAppUrl = decodeURIComponent(appUrl); + const decodedCurrentUrl = decodeURIComponent(currentUrl); - const navSuccessful = currentUrl + const navSuccessful = decodedCurrentUrl .replace(':80/', '/') .replace(':443/', '/') - .startsWith(appUrl.replace(':80/', '/').replace(':443/', '/')); + .startsWith(decodedAppUrl.replace(':80/', '/').replace(':443/', '/')); if (!navSuccessful) { - const msg = `App failed to load: ${appName} in ${this.defaultFindTimeout}ms appUrl=${appUrl} currentUrl=${currentUrl}`; + const msg = `App failed to load: ${appName} in ${this.defaultFindTimeout}ms appUrl=${decodedAppUrl} currentUrl=${decodedCurrentUrl}`; this.log.debug(msg); throw new Error(msg); } From 44df1f4caad795a3c5be45774520c1c6b3dcac22 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Fri, 9 Feb 2024 09:17:20 +0100 Subject: [PATCH 060/104] [Obs AI Assistant] Bedrock/Claude support (#176191) ~This PR still needs work (tests, mainly), so keeping it in draft for now, but feel free to take it for a spin.~ Implements Bedrock support, specifically for the Claude models. Architecturally, this introduces LLM adapters: one for OpenAI (which is what we already have), and one for Bedrock/Claude. The Bedrock/Claude adapter does the following things: - parses data from a SerDe (an AWS concept IIUC) stream using `@smithy/eventstream-serde-node`. - Converts function requests and results into XML and back (to some extent) - some slight changes to existing functionality to achieve _some_ kind of baseline performance with Bedrock + Claude. Generally, GPT seems better at implicit tasks. Claude needs explicit tasks, otherwise it will take things too literally. For instance, I had to use a function for generating a title because Claude was too eager to add explanations. For the `classify_esql` function, I had to add extra instructions to stop it from requesting information that is not there. It is prone to generating invalid XML. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../pre-configured-connectors.asciidoc | 2 +- docs/settings/alert-action-settings.asciidoc | 2 +- package.json | 6 + packages/kbn-test/jest-preset.js | 2 +- .../jest_integration_node/jest-preset.js | 2 +- .../plugins/actions/docs/openapi/bundled.json | 4 +- .../plugins/actions/docs/openapi/bundled.yaml | 2 +- .../docs/openapi/bundled_serverless.json | 4 +- .../docs/openapi/bundled_serverless.yaml | 2 +- .../schemas/config_properties_bedrock.yaml | 2 +- .../common/connectors.ts | 25 ++ .../common/conversation_complete.ts | 17 +- .../common/utils/process_openai_stream.ts | 1 - .../observability_ai_assistant/kibana.jsonc | 4 +- .../components/chat/welcome_message.tsx | 3 +- .../public/service/create_chat_service.ts | 16 +- .../scripts/evaluation/README.md | 2 +- .../scripts/evaluation/kibana_client.ts | 22 +- .../server/functions/index.ts | 3 +- .../server/functions/query/index.ts | 106 ++++---- .../server/functions/recall.ts | 14 +- .../server/routes/chat/route.ts | 22 +- .../server/routes/connectors/route.ts | 3 +- .../adapters/bedrock_claude_adapter.test.ts | 239 ++++++++++++++++ .../client/adapters/bedrock_claude_adapter.ts | 228 ++++++++++++++++ .../service/client/adapters/openai_adapter.ts | 69 +++++ .../adapters/process_bedrock_stream.test.ts | 256 ++++++++++++++++++ .../client/adapters/process_bedrock_stream.ts | 151 +++++++++++ .../server/service/client/adapters/types.ts | 25 ++ .../server/service/client/index.test.ts | 27 +- .../server/service/client/index.ts | 206 +++++++------- ..._deserialized_xml_with_json_schema.test.ts | 128 +++++++++ ...nvert_deserialized_xml_with_json_schema.ts | 106 ++++++++ .../eventsource_stream_into_observable.ts | 38 +++ .../util/eventstream_serde_into_observable.ts | 58 ++++ .../server/service/util/flush_buffer.ts | 63 +++++ .../json_schema_to_flat_parameters.test.ts | 208 ++++++++++++++ .../util/json_schema_to_flat_parameters.ts | 73 +++++ .../service/util/observable_into_stream.ts | 5 +- .../service/util/stream_into_observable.ts | 31 ++- .../server/types.ts | 5 +- .../observability_ai_assistant/tsconfig.json | 2 + .../common/bedrock/constants.ts | 2 +- .../stack_connectors/common/bedrock/schema.ts | 2 + .../public/connector_types/bedrock/params.tsx | 2 +- .../connector_types/bedrock/bedrock.test.ts | 58 +++- .../server/connector_types/bedrock/bedrock.ts | 48 +++- .../server/connector_types/bedrock/index.ts | 10 +- .../server/bedrock_simulation.ts | 2 +- .../tests/actions/connector_types/bedrock.ts | 12 +- .../common/create_llm_proxy.ts | 9 +- .../tests/complete/complete.spec.ts | 12 +- .../tests/conversations/index.spec.ts | 10 +- yarn.lock | 65 ++++- 54 files changed, 2159 insertions(+), 257 deletions(-) create mode 100644 x-pack/plugins/observability_ai_assistant/common/connectors.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.test.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/openai_adapter.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.test.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/client/adapters/types.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.test.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/eventsource_stream_into_observable.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/eventstream_serde_into_observable.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/flush_buffer.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.test.ts create mode 100644 x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.ts diff --git a/docs/management/connectors/pre-configured-connectors.asciidoc b/docs/management/connectors/pre-configured-connectors.asciidoc index b7293b6232190..c027220376cdf 100644 --- a/docs/management/connectors/pre-configured-connectors.asciidoc +++ b/docs/management/connectors/pre-configured-connectors.asciidoc @@ -148,7 +148,7 @@ xpack.actions.preconfigured: actionTypeId: .bedrock config: apiUrl: https://bedrock-runtime.us-east-1.amazonaws.com <1> - defaultModel: anthropic.claude-v2 <2> + defaultModel: anthropic.claude-v2:1 <2> secrets: accessKey: key-value <3> secret: secret-value <4> diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index b7d7e8d344a32..2bfde478a494d 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -340,7 +340,7 @@ For a <>, specifies a string f The default model to use for requests, which varies by connector: + -- -* For an <>, current support is for the Anthropic Claude models. Defaults to `anthropic.claude-v2`. +* For an <>, current support is for the Anthropic Claude models. Defaults to `anthropic.claude-v2:1`. * For a <>, it is optional and applicable only when `xpack.actions.preconfigured..config.apiProvider` is `OpenAI`. -- diff --git a/package.json b/package.json index 05b09aa56196c..c11b0b349099f 100644 --- a/package.json +++ b/package.json @@ -881,6 +881,8 @@ "@reduxjs/toolkit": "1.9.7", "@slack/webhook": "^7.0.1", "@smithy/eventstream-codec": "^2.0.12", + "@smithy/eventstream-serde-node": "^2.1.1", + "@smithy/types": "^2.9.1", "@smithy/util-utf8": "^2.0.0", "@tanstack/react-query": "^4.29.12", "@tanstack/react-query-devtools": "^4.29.12", @@ -946,6 +948,7 @@ "diff": "^5.1.0", "elastic-apm-node": "^4.4.0", "email-addresses": "^5.0.0", + "eventsource-parser": "^1.1.1", "execa": "^5.1.1", "expiry-js": "0.1.7", "exponential-backoff": "^3.1.1", @@ -954,6 +957,7 @@ "fast-glob": "^3.3.2", "fflate": "^0.6.9", "file-saver": "^1.3.8", + "flat": "5", "fnv-plus": "^1.3.1", "font-awesome": "4.7.0", "formik": "^2.4.5", @@ -1380,11 +1384,13 @@ "@types/ejs": "^3.0.6", "@types/enzyme": "^3.10.12", "@types/eslint": "^8.44.2", + "@types/event-stream": "^4.0.5", "@types/express": "^4.17.13", "@types/extract-zip": "^1.6.2", "@types/faker": "^5.1.5", "@types/fetch-mock": "^7.3.1", "@types/file-saver": "^2.0.0", + "@types/flat": "^5.0.5", "@types/flot": "^0.0.31", "@types/fnv-plus": "^1.3.0", "@types/geojson": "^7946.0.10", diff --git a/packages/kbn-test/jest-preset.js b/packages/kbn-test/jest-preset.js index df9ed4cab4f51..de4e6032ba52f 100644 --- a/packages/kbn-test/jest-preset.js +++ b/packages/kbn-test/jest-preset.js @@ -105,7 +105,7 @@ module.exports = { transformIgnorePatterns: [ // ignore all node_modules except monaco-editor, monaco-yaml and react-monaco-editor which requires babel transforms to handle dynamic import() // since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842) - '[/\\\\]node_modules(?![\\/\\\\](byte-size|monaco-editor|monaco-yaml|monaco-languageserver-types|monaco-marker-data-provider|monaco-worker-manager|vscode-languageserver-types|react-monaco-editor|d3-interpolate|d3-color|langchain|langsmith|@cfworker|gpt-tokenizer))[/\\\\].+\\.js$', + '[/\\\\]node_modules(?![\\/\\\\](byte-size|monaco-editor|monaco-yaml|monaco-languageserver-types|monaco-marker-data-provider|monaco-worker-manager|vscode-languageserver-types|react-monaco-editor|d3-interpolate|d3-color|langchain|langsmith|@cfworker|gpt-tokenizer|flat))[/\\\\].+\\.js$', 'packages/kbn-pm/dist/index.js', '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith))/dist/[/\\\\].+\\.js$', '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith))/dist/util/[/\\\\].+\\.js$', diff --git a/packages/kbn-test/jest_integration_node/jest-preset.js b/packages/kbn-test/jest_integration_node/jest-preset.js index 631b2c4f9350e..6472237c5dd17 100644 --- a/packages/kbn-test/jest_integration_node/jest-preset.js +++ b/packages/kbn-test/jest_integration_node/jest-preset.js @@ -22,7 +22,7 @@ module.exports = { // An array of regexp pattern strings that are matched against, matched files will skip transformation: transformIgnorePatterns: [ // since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842) - '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith|gpt-tokenizer))[/\\\\].+\\.js$', + '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith|gpt-tokenizer|flat))[/\\\\].+\\.js$', '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith))/dist/[/\\\\].+\\.js$', '[/\\\\]node_modules(?![\\/\\\\](langchain|langsmith))/dist/util/[/\\\\].+\\.js$', ], diff --git a/x-pack/plugins/actions/docs/openapi/bundled.json b/x-pack/plugins/actions/docs/openapi/bundled.json index d165392087670..d910d5ad6501e 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.json +++ b/x-pack/plugins/actions/docs/openapi/bundled.json @@ -2240,7 +2240,7 @@ "defaultModel": { "type": "string", "description": "The generative artificial intelligence model for Amazon Bedrock to use. Current support is for the Anthropic Claude models.\n", - "default": "anthropic.claude-v2" + "default": "anthropic.claude-v2:1" } } }, @@ -6841,4 +6841,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/plugins/actions/docs/openapi/bundled.yaml b/x-pack/plugins/actions/docs/openapi/bundled.yaml index 58ea32fe25764..cd55a90afa483 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled.yaml @@ -1498,7 +1498,7 @@ components: type: string description: | The generative artificial intelligence model for Amazon Bedrock to use. Current support is for the Anthropic Claude models. - default: anthropic.claude-v2 + default: anthropic.claude-v2:1 secrets_properties_bedrock: title: Connector secrets properties for an Amazon Bedrock connector description: Defines secrets for connectors when type is `.bedrock`. diff --git a/x-pack/plugins/actions/docs/openapi/bundled_serverless.json b/x-pack/plugins/actions/docs/openapi/bundled_serverless.json index acde35b764a5e..ba7d2b16be139 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled_serverless.json +++ b/x-pack/plugins/actions/docs/openapi/bundled_serverless.json @@ -1226,7 +1226,7 @@ "defaultModel": { "type": "string", "description": "The generative artificial intelligence model for Amazon Bedrock to use. Current support is for the Anthropic Claude models.\n", - "default": "anthropic.claude-v2" + "default": "anthropic.claude-v2:1" } } }, @@ -4377,4 +4377,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml b/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml index 3d9be12c8077e..564b121ec663b 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml @@ -857,7 +857,7 @@ components: type: string description: | The generative artificial intelligence model for Amazon Bedrock to use. Current support is for the Anthropic Claude models. - default: anthropic.claude-v2 + default: anthropic.claude-v2:1 secrets_properties_bedrock: title: Connector secrets properties for an Amazon Bedrock connector description: Defines secrets for connectors when type is `.bedrock`. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_bedrock.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_bedrock.yaml index 25b279c423739..189a5d5e2e05e 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_bedrock.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_bedrock.yaml @@ -12,4 +12,4 @@ properties: description: > The generative artificial intelligence model for Amazon Bedrock to use. Current support is for the Anthropic Claude models. - default: anthropic.claude-v2 \ No newline at end of file + default: anthropic.claude-v2:1 diff --git a/x-pack/plugins/observability_ai_assistant/common/connectors.ts b/x-pack/plugins/observability_ai_assistant/common/connectors.ts new file mode 100644 index 0000000000000..2b834081a7ac9 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/common/connectors.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export enum ObservabilityAIAssistantConnectorType { + Bedrock = '.bedrock', + OpenAI = '.gen-ai', +} + +export const SUPPORTED_CONNECTOR_TYPES = [ + ObservabilityAIAssistantConnectorType.OpenAI, + ObservabilityAIAssistantConnectorType.Bedrock, +]; + +export function isSupportedConnectorType( + type: string +): type is ObservabilityAIAssistantConnectorType { + return ( + type === ObservabilityAIAssistantConnectorType.Bedrock || + type === ObservabilityAIAssistantConnectorType.OpenAI + ); +} diff --git a/x-pack/plugins/observability_ai_assistant/common/conversation_complete.ts b/x-pack/plugins/observability_ai_assistant/common/conversation_complete.ts index f5fe0d37408c2..b082478bba100 100644 --- a/x-pack/plugins/observability_ai_assistant/common/conversation_complete.ts +++ b/x-pack/plugins/observability_ai_assistant/common/conversation_complete.ts @@ -14,6 +14,7 @@ export enum StreamingChatResponseEventType { ConversationUpdate = 'conversationUpdate', MessageAdd = 'messageAdd', ChatCompletionError = 'chatCompletionError', + BufferFlush = 'bufferFlush', } type StreamingChatResponseEventBase< @@ -76,6 +77,13 @@ export type ChatCompletionErrorEvent = StreamingChatResponseEventBase< } >; +export type BufferFlushEvent = StreamingChatResponseEventBase< + StreamingChatResponseEventType.BufferFlush, + { + data?: string; + } +>; + export type StreamingChatResponseEvent = | ChatCompletionChunkEvent | ConversationCreateEvent @@ -129,7 +137,14 @@ export function createConversationNotFoundError() { ); } -export function createInternalServerError(originalErrorMessage: string) { +export function createInternalServerError( + originalErrorMessage: string = i18n.translate( + 'xpack.observabilityAiAssistant.chatCompletionError.internalServerError', + { + defaultMessage: 'An internal server error occurred', + } + ) +) { return new ChatCompletionError(ChatCompletionErrorCode.InternalError, originalErrorMessage); } diff --git a/x-pack/plugins/observability_ai_assistant/common/utils/process_openai_stream.ts b/x-pack/plugins/observability_ai_assistant/common/utils/process_openai_stream.ts index 2487fca287cc7..8b6ef27ee8ebd 100644 --- a/x-pack/plugins/observability_ai_assistant/common/utils/process_openai_stream.ts +++ b/x-pack/plugins/observability_ai_assistant/common/utils/process_openai_stream.ts @@ -19,7 +19,6 @@ export function processOpenAiStream() { const id = v4(); return source.pipe( - map((line) => line.substring(6)), filter((line) => !!line && line !== '[DONE]'), map( (line) => diff --git a/x-pack/plugins/observability_ai_assistant/kibana.jsonc b/x-pack/plugins/observability_ai_assistant/kibana.jsonc index 3f346cccff0c1..a3eaad0d216a3 100644 --- a/x-pack/plugins/observability_ai_assistant/kibana.jsonc +++ b/x-pack/plugins/observability_ai_assistant/kibana.jsonc @@ -25,7 +25,9 @@ "ml" ], "requiredBundles": [ "kibanaReact", "kibanaUtils"], - "optionalPlugins": [], + "optionalPlugins": [ + "cloud" + ], "extraPublicDirs": [] } } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx index bf514691f7d93..0227ef42e2808 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx @@ -25,6 +25,7 @@ import { Disclaimer } from './disclaimer'; import { WelcomeMessageConnectors } from './welcome_message_connectors'; import { WelcomeMessageKnowledgeBase } from './welcome_message_knowledge_base'; import { useKibana } from '../../hooks/use_kibana'; +import { isSupportedConnectorType } from '../../../common/connectors'; const fullHeightClassName = css` height: 100%; @@ -68,7 +69,7 @@ export function WelcomeMessage({ const onConnectorCreated = (createdConnector: ActionConnector) => { setConnectorFlyoutOpen(false); - if (createdConnector.actionTypeId === '.gen-ai') { + if (isSupportedConnectorType(createdConnector.actionTypeId)) { connectors.reloadConnectors(); } diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts index 17ea46c56681e..5fe933835eecd 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts @@ -9,8 +9,10 @@ import { AnalyticsServiceStart, HttpResponse } from '@kbn/core/public'; import { AbortError } from '@kbn/kibana-utils-plugin/common'; import { IncomingMessage } from 'http'; import { pick } from 'lodash'; -import { concatMap, delay, map, Observable, of, scan, shareReplay, timestamp } from 'rxjs'; +import { concatMap, delay, filter, map, Observable, of, scan, shareReplay, timestamp } from 'rxjs'; import { + BufferFlushEvent, + StreamingChatResponseEventType, StreamingChatResponseEventWithoutError, type StreamingChatResponseEvent, } from '../../common/conversation_complete'; @@ -163,7 +165,11 @@ export async function createChatService({ const response = _response as unknown as HttpResponse; const response$ = toObservable(response) .pipe( - map((line) => JSON.parse(line) as StreamingChatResponseEvent), + map((line) => JSON.parse(line) as StreamingChatResponseEvent | BufferFlushEvent), + filter( + (line): line is StreamingChatResponseEvent => + line.type !== StreamingChatResponseEventType.BufferFlush + ), throwSerializedChatCompletionErrors() ) .subscribe(subscriber); @@ -224,7 +230,11 @@ export async function createChatService({ const subscription = toObservable(response) .pipe( - map((line) => JSON.parse(line) as StreamingChatResponseEvent), + map((line) => JSON.parse(line) as StreamingChatResponseEvent | BufferFlushEvent), + filter( + (line): line is StreamingChatResponseEvent => + line.type !== StreamingChatResponseEventType.BufferFlush + ), throwSerializedChatCompletionErrors() ) .subscribe(subscriber); diff --git a/x-pack/plugins/observability_ai_assistant/scripts/evaluation/README.md b/x-pack/plugins/observability_ai_assistant/scripts/evaluation/README.md index c5ff90ed582f2..76bf8a7fe7df2 100644 --- a/x-pack/plugins/observability_ai_assistant/scripts/evaluation/README.md +++ b/x-pack/plugins/observability_ai_assistant/scripts/evaluation/README.md @@ -26,7 +26,7 @@ By default, the tool will look for a Kibana instance running locally (at `http:/ #### Connector -Use `--connectorId` to specify a `.gen-ai` connector to use. If none are given, it will prompt you to select a connector based on the ones that are available. If only a single `.gen-ai` connector is found, it will be used without prompting. +Use `--connectorId` to specify a `.gen-ai` or `.bedrock` connector to use. If none are given, it will prompt you to select a connector based on the ones that are available. If only a single supported connector is found, it will be used without prompting. #### Persisting conversations diff --git a/x-pack/plugins/observability_ai_assistant/scripts/evaluation/kibana_client.ts b/x-pack/plugins/observability_ai_assistant/scripts/evaluation/kibana_client.ts index d77e37a2b55a8..d0aa91f7ac53e 100644 --- a/x-pack/plugins/observability_ai_assistant/scripts/evaluation/kibana_client.ts +++ b/x-pack/plugins/observability_ai_assistant/scripts/evaluation/kibana_client.ts @@ -12,7 +12,9 @@ import { format, parse, UrlObject } from 'url'; import { ToolingLog } from '@kbn/tooling-log'; import pRetry from 'p-retry'; import { Message, MessageRole } from '../../common'; +import { isSupportedConnectorType } from '../../common/connectors'; import { + BufferFlushEvent, ChatCompletionChunkEvent, ChatCompletionErrorEvent, ConversationCreateEvent, @@ -217,7 +219,17 @@ export class KibanaClient { ) ).data ).pipe( - map((line) => JSON.parse(line) as ChatCompletionChunkEvent | ChatCompletionErrorEvent), + map( + (line) => + JSON.parse(line) as + | ChatCompletionChunkEvent + | ChatCompletionErrorEvent + | BufferFlushEvent + ), + filter( + (line): line is ChatCompletionChunkEvent | ChatCompletionErrorEvent => + line.type !== StreamingChatResponseEventType.BufferFlush + ), throwSerializedChatCompletionErrors(), concatenateChatCompletionChunks() ); @@ -270,13 +282,13 @@ export class KibanaClient { ) ).data ).pipe( - map((line) => JSON.parse(line) as StreamingChatResponseEvent), - throwSerializedChatCompletionErrors(), + map((line) => JSON.parse(line) as StreamingChatResponseEvent | BufferFlushEvent), filter( (event): event is MessageAddEvent | ConversationCreateEvent => event.type === StreamingChatResponseEventType.MessageAdd || event.type === StreamingChatResponseEventType.ConversationCreate ), + throwSerializedChatCompletionErrors(), toArray() ); @@ -427,6 +439,8 @@ export class KibanaClient { }) ); - return connectors.data.filter((connector) => connector.connector_type_id === '.gen-ai'); + return connectors.data.filter((connector) => + isSupportedConnectorType(connector.connector_type_id) + ); } } diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/index.ts b/x-pack/plugins/observability_ai_assistant/server/functions/index.ts index d02f943c3523e..708f77da33321 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/index.ts @@ -53,7 +53,6 @@ export const registerFunctions: ChatRegistrationFunction = async ({ If multiple functions are suitable, use the most specific and easy one. E.g., when the user asks to visualise APM data, use the APM functions (if available) rather than "query". - Use the "get_dataset_info" function if it is not clear what fields or indices the user means, or if you want to get more information about the mappings. Note that ES|QL (the Elasticsearch query language, which is NOT Elasticsearch SQL, but a new piped language) is the preferred query language. @@ -66,6 +65,8 @@ export const registerFunctions: ChatRegistrationFunction = async ({ When the "visualize_query" function has been called, a visualization has been displayed to the user. DO NOT UNDER ANY CIRCUMSTANCES follow up a "visualize_query" function call with your own visualization attempt. If the "execute_query" function has been called, summarize these results for the user. The user does not see a visualization in this case. + Use the "get_dataset_info" function if it is not clear what fields or indices the user means, or if you want to get more information about the mappings. + If the "get_dataset_info" function returns no data, and the user asks for a query, generate a query anyway with the "query" function, but be explicit about it potentially being incorrect. ` ); diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/query/index.ts b/x-pack/plugins/observability_ai_assistant/server/functions/query/index.ts index b69188d81b84a..86da0c0395587 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/query/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/query/index.ts @@ -113,6 +113,7 @@ export function registerQueryFunction({ type: 'boolean', }, }, + required: ['switch'], } as const, }, async ({ messages, connectorId }, signal) => { @@ -129,54 +130,58 @@ export function registerQueryFunction({ const source$ = ( await client.chat('classify_esql', { connectorId, - messages: withEsqlSystemMessage( - `Use the classify_esql function to classify the user's request - and get more information about specific functions and commands - you think are candidates for answering the question. - + messages: withEsqlSystemMessage().concat({ + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.User, + content: `Use the classify_esql function to classify the user's request + in the user message before this. + and get more information about specific functions and commands + you think are candidates for answering the question. - Examples for functions and commands: - Do you need to group data? Request \`STATS\`. - Extract data? Request \`DISSECT\` AND \`GROK\`. - Convert a column based on a set of conditionals? Request \`EVAL\` and \`CASE\`. - - For determining the intention of the user, the following options are available: - - ${VisualizeESQLUserIntention.generateQueryOnly}: the user only wants to generate the query, - but not run it. - - ${VisualizeESQLUserIntention.executeAndReturnResults}: the user wants to execute the query, - and have the assistant return/analyze/summarize the results. they don't need a - visualization. - - ${VisualizeESQLUserIntention.visualizeAuto}: The user wants to visualize the data from the - query, but wants us to pick the best visualization type, or their preferred - visualization is unclear. - - These intentions will display a specific visualization: - ${VisualizeESQLUserIntention.visualizeBar} - ${VisualizeESQLUserIntention.visualizeDonut} - ${VisualizeESQLUserIntention.visualizeHeatmap} - ${VisualizeESQLUserIntention.visualizeLine} - ${VisualizeESQLUserIntention.visualizeTagcloud} - ${VisualizeESQLUserIntention.visualizeTreemap} - ${VisualizeESQLUserIntention.visualizeWaffle} - ${VisualizeESQLUserIntention.visualizeXy} - - Some examples: - "Show me the avg of x" => ${VisualizeESQLUserIntention.executeAndReturnResults} - "Show me the results of y" => ${VisualizeESQLUserIntention.executeAndReturnResults} - "Display the sum of z" => ${VisualizeESQLUserIntention.executeAndReturnResults} - - "I want a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} - "... Just show me the query" => ${VisualizeESQLUserIntention.generateQueryOnly} - "Create a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} - - "Show me the avg of x over time" => ${VisualizeESQLUserIntention.visualizeAuto} - "I want a bar chart of ... " => ${VisualizeESQLUserIntention.visualizeBar} - "I want to see a heat map of ..." => ${VisualizeESQLUserIntention.visualizeHeatmap} - ` - ), + Examples for functions and commands: + Do you need to group data? Request \`STATS\`. + Extract data? Request \`DISSECT\` AND \`GROK\`. + Convert a column based on a set of conditionals? Request \`EVAL\` and \`CASE\`. + + For determining the intention of the user, the following options are available: + + ${VisualizeESQLUserIntention.generateQueryOnly}: the user only wants to generate the query, + but not run it. + + ${VisualizeESQLUserIntention.executeAndReturnResults}: the user wants to execute the query, + and have the assistant return/analyze/summarize the results. they don't need a + visualization. + + ${VisualizeESQLUserIntention.visualizeAuto}: The user wants to visualize the data from the + query, but wants us to pick the best visualization type, or their preferred + visualization is unclear. + + These intentions will display a specific visualization: + ${VisualizeESQLUserIntention.visualizeBar} + ${VisualizeESQLUserIntention.visualizeDonut} + ${VisualizeESQLUserIntention.visualizeHeatmap} + ${VisualizeESQLUserIntention.visualizeLine} + ${VisualizeESQLUserIntention.visualizeTagcloud} + ${VisualizeESQLUserIntention.visualizeTreemap} + ${VisualizeESQLUserIntention.visualizeWaffle} + ${VisualizeESQLUserIntention.visualizeXy} + + Some examples: + "Show me the avg of x" => ${VisualizeESQLUserIntention.executeAndReturnResults} + "Show me the results of y" => ${VisualizeESQLUserIntention.executeAndReturnResults} + "Display the sum of z" => ${VisualizeESQLUserIntention.executeAndReturnResults} + + "I want a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} + "... Just show me the query" => ${VisualizeESQLUserIntention.generateQueryOnly} + "Create a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} + + "Show me the avg of x over time" => ${VisualizeESQLUserIntention.visualizeAuto} + "I want a bar chart of ... " => ${VisualizeESQLUserIntention.visualizeBar} + "I want to see a heat map of ..." => ${VisualizeESQLUserIntention.visualizeHeatmap} + `, + }, + }), signal, functions: [ { @@ -184,6 +189,9 @@ export function registerQueryFunction({ description: `Use this function to determine: - what ES|QL functions and commands are candidates for answering the user's question - whether the user has requested a query, and if so, it they want it to be executed, or just shown. + + All parameters are required. Make sure the functions and commands you request are available in the + system message. `, parameters: { type: 'object', @@ -218,6 +226,10 @@ export function registerQueryFunction({ const response = await lastValueFrom(source$); + if (!response.message.function_call.arguments) { + throw new Error('LLM did not call classify_esql function'); + } + const args = JSON.parse(response.message.function_call.arguments) as { commands: string[]; functions: string[]; diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts index 909a823286cc6..125c9a2f6eea0 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts @@ -11,11 +11,11 @@ import dedent from 'dedent'; import * as t from 'io-ts'; import { compact, last, omit } from 'lodash'; import { lastValueFrom } from 'rxjs'; +import { Logger } from '@kbn/logging'; import { FunctionRegistrationParameters } from '.'; import { MessageRole, type Message } from '../../common/types'; import { concatenateChatCompletionChunks } from '../../common/utils/concatenate_chat_completion_chunks'; import type { ObservabilityAIAssistantClient } from '../service/client'; -import { RespondFunctionResources } from '../service/types'; export function registerRecallFunction({ client, @@ -114,7 +114,7 @@ export function registerRecallFunction({ client, connectorId, signal, - resources, + logger: resources.logger, }); return { @@ -162,7 +162,7 @@ async function scoreSuggestions({ client, connectorId, signal, - resources, + logger, }: { suggestions: Awaited>; messages: Message[]; @@ -170,7 +170,7 @@ async function scoreSuggestions({ client: ObservabilityAIAssistantClient; connectorId: string; signal: AbortSignal; - resources: RespondFunctionResources; + logger: Logger; }) { const indexedSuggestions = suggestions.map((suggestion, index) => ({ ...suggestion, id: index })); @@ -233,6 +233,7 @@ async function scoreSuggestions({ }) ).pipe(concatenateChatCompletionChunks()) ); + const scoreFunctionRequest = decodeOrThrow(scoreFunctionRequestRt)(response); const { scores: scoresAsString } = decodeOrThrow(jsonRt.pipe(scoreFunctionArgumentsRt))( scoreFunctionRequest.message.function_call.arguments @@ -264,10 +265,7 @@ async function scoreSuggestions({ relevantDocumentIds.includes(suggestion.id) ); - resources.logger.debug( - `Found ${relevantDocumentIds.length} relevant suggestions from the knowledge base. ${scores.length} suggestions were considered in total.` - ); - resources.logger.debug(`Relevant documents: ${JSON.stringify(relevantDocuments, null, 2)}`); + logger.debug(`Relevant documents: ${JSON.stringify(relevantDocuments, null, 2)}`); return relevantDocuments; } diff --git a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts index 517cc48f9f27c..a9c58a9a59e00 100644 --- a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts +++ b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts @@ -5,13 +5,13 @@ * 2.0. */ import { notImplemented } from '@hapi/boom'; -import * as t from 'io-ts'; import { toBooleanRt } from '@kbn/io-ts-utils'; -import type OpenAI from 'openai'; +import * as t from 'io-ts'; import { Readable } from 'stream'; +import { flushBuffer } from '../../service/util/flush_buffer'; +import { observableIntoStream } from '../../service/util/observable_into_stream'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; import { messageRt } from '../runtime_types'; -import { observableIntoStream } from '../../service/util/observable_into_stream'; const chatRoute = createObservabilityAIAssistantServerRoute({ endpoint: 'POST /internal/observability_ai_assistant/chat', @@ -40,7 +40,10 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ handler: async (resources): Promise => { const { request, params, service } = resources; - const client = await service.getClient({ request }); + const [client, cloudStart] = await Promise.all([ + service.getClient({ request }), + resources.plugins.cloud?.start(), + ]); if (!client) { throw notImplemented(); @@ -68,7 +71,7 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ : {}), }); - return observableIntoStream(response$); + return observableIntoStream(response$.pipe(flushBuffer(!!cloudStart?.isCloudEnabled))); }, }); @@ -90,10 +93,13 @@ const chatCompleteRoute = createObservabilityAIAssistantServerRoute({ }), ]), }), - handler: async (resources): Promise => { + handler: async (resources): Promise => { const { request, params, service } = resources; - const client = await service.getClient({ request }); + const [client, cloudStart] = await Promise.all([ + service.getClient({ request }), + resources.plugins.cloud?.start() || Promise.resolve(undefined), + ]); if (!client) { throw notImplemented(); @@ -125,7 +131,7 @@ const chatCompleteRoute = createObservabilityAIAssistantServerRoute({ functionClient, }); - return observableIntoStream(response$); + return observableIntoStream(response$.pipe(flushBuffer(!!cloudStart?.isCloudEnabled))); }, }); diff --git a/x-pack/plugins/observability_ai_assistant/server/routes/connectors/route.ts b/x-pack/plugins/observability_ai_assistant/server/routes/connectors/route.ts index 894896fec6b3c..79134b9fef8d0 100644 --- a/x-pack/plugins/observability_ai_assistant/server/routes/connectors/route.ts +++ b/x-pack/plugins/observability_ai_assistant/server/routes/connectors/route.ts @@ -5,6 +5,7 @@ * 2.0. */ import { FindActionResult } from '@kbn/actions-plugin/server'; +import { isSupportedConnectorType } from '../../../common/connectors'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; const listConnectorsRoute = createObservabilityAIAssistantServerRoute({ @@ -21,7 +22,7 @@ const listConnectorsRoute = createObservabilityAIAssistantServerRoute({ const connectors = await actionsClient.getAll(); - return connectors.filter((connector) => connector.actionTypeId === '.gen-ai'); + return connectors.filter((connector) => isSupportedConnectorType(connector.actionTypeId)); }, }); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.test.ts new file mode 100644 index 0000000000000..e92d14088d337 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.test.ts @@ -0,0 +1,239 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { Logger } from '@kbn/logging'; +import dedent from 'dedent'; +import { last } from 'lodash'; +import { MessageRole } from '../../../../common'; +import { createBedrockClaudeAdapter } from './bedrock_claude_adapter'; +import { LlmApiAdapterFactory } from './types'; + +describe('createBedrockClaudeAdapter', () => { + describe('getSubAction', () => { + function callSubActionFactory(overrides?: Partial[0]>) { + const subActionParams = createBedrockClaudeAdapter({ + logger: { + debug: jest.fn(), + } as unknown as Logger, + functions: [ + { + name: 'my_tool', + description: 'My tool', + parameters: { + properties: { + myParam: { + type: 'string', + }, + }, + }, + }, + ], + messages: [ + { + '@timestamp': new Date().toString(), + message: { + role: MessageRole.System, + content: '', + }, + }, + { + '@timestamp': new Date().toString(), + message: { + role: MessageRole.User, + content: 'How can you help me?', + }, + }, + ], + ...overrides, + }).getSubAction().subActionParams as { + temperature: number; + messages: Array<{ role: string; content: string }>; + }; + + return { + ...subActionParams, + messages: subActionParams.messages.map((msg) => ({ ...msg, content: dedent(msg.content) })), + }; + } + describe('with functions', () => { + it('sets the temperature to 0', () => { + expect(callSubActionFactory().temperature).toEqual(0); + }); + + it('formats the functions', () => { + expect(callSubActionFactory().messages[0].content).toContain( + dedent(` + + my_tool + My tool + + + myParam + string + + + Required: false + Multiple: false + + + + + + `) + ); + }); + + it('replaces mentions of functions with tools', () => { + const messages = [ + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.System, + content: + 'Call the "esql" tool. You can chain successive function calls, using the functions available.', + }, + }, + ]; + + const content = callSubActionFactory({ messages }).messages[0].content; + + expect(content).not.toContain(`"esql" function`); + expect(content).toContain(`"esql" tool`); + expect(content).not.toContain(`functions`); + expect(content).toContain(`tools`); + expect(content).toContain(`function calls`); + }); + + it('mentions to explicitly call the specified function if given', () => { + expect(last(callSubActionFactory({ functionCall: 'my_tool' }).messages)!.content).toContain( + 'Remember, use the my_tool tool to answer this question.' + ); + }); + + it('formats the function requests as XML', () => { + const messages = [ + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.System, + content: '', + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.Assistant, + function_call: { + name: 'my_tool', + arguments: JSON.stringify({ myParam: 'myValue' }), + trigger: MessageRole.User as const, + }, + }, + }, + ]; + + expect(last(callSubActionFactory({ messages }).messages)!.content).toContain( + dedent(` + + my_tool + + myValue + + + `) + ); + }); + + it('formats errors', () => { + const messages = [ + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.System, + content: '', + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.Assistant, + function_call: { + name: 'my_tool', + arguments: JSON.stringify({ myParam: 'myValue' }), + trigger: MessageRole.User as const, + }, + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.User, + name: 'my_tool', + content: JSON.stringify({ error: 'An internal server error occurred' }), + }, + }, + ]; + + expect(last(callSubActionFactory({ messages }).messages)!.content).toContain( + dedent(` + + An internal server error occurred + + `) + ); + }); + + it('formats function responses as XML + JSON', () => { + const messages = [ + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.System, + content: '', + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.Assistant, + function_call: { + name: 'my_tool', + arguments: JSON.stringify({ myParam: 'myValue' }), + trigger: MessageRole.User as const, + }, + }, + }, + { + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.User, + name: 'my_tool', + content: JSON.stringify({ myResponse: { myParam: 'myValue' } }), + }, + }, + ]; + + expect(last(callSubActionFactory({ messages }).messages)!.content).toContain( + dedent(` + + my_tool + + +myValue + + + + `) + ); + }); + }); + }); + + describe('streamIntoObservable', () => { + // this data format is heavily encoded, so hard to reproduce. + // will leave this empty until we have some sample data. + }); +}); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.ts new file mode 100644 index 0000000000000..d5ba0d726ab12 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/bedrock_claude_adapter.ts @@ -0,0 +1,228 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import dedent from 'dedent'; +import { castArray } from 'lodash'; +import { filter, tap } from 'rxjs'; +import { Builder } from 'xml2js'; +import { createInternalServerError } from '../../../../common/conversation_complete'; +import { + BedrockChunkMember, + eventstreamSerdeIntoObservable, +} from '../../util/eventstream_serde_into_observable'; +import { jsonSchemaToFlatParameters } from '../../util/json_schema_to_flat_parameters'; +import { processBedrockStream } from './process_bedrock_stream'; +import type { LlmApiAdapterFactory } from './types'; + +function replaceFunctionsWithTools(content: string) { + return content.replaceAll(/(function)(s)?(?!\scall)/g, (match, p1, p2) => { + return `tool${p2 || ''}`; + }); +} + +// Most of the work here is to re-format OpenAI-compatible functions for Claude. +// See https://github.com/anthropics/anthropic-tools/blob/main/tool_use_package/prompt_constructors.py + +export const createBedrockClaudeAdapter: LlmApiAdapterFactory = ({ + messages, + functions, + functionCall, + logger, +}) => ({ + getSubAction: () => { + const [systemMessage, ...otherMessages] = messages; + + const filteredFunctions = functionCall + ? functions?.filter((fn) => fn.name === functionCall) + : functions; + + let functionsPrompt: string = ''; + + if (filteredFunctions?.length) { + functionsPrompt = `In this environment, you have access to a set of tools you can use to answer the user's question. + + When deciding what tool to use, keep in mind that you can call other tools in successive requests, so decide what tool + would be a good first step. + + You MUST only invoke a single tool, and invoke it once. Other invocations will be ignored. + You MUST wait for the results before invoking another. + You can call multiple tools in successive messages. This means you can chain function calls. If any tool was used in a previous + message, consider whether it still makes sense to follow it up with another function call. + + ${ + functions?.find((fn) => fn.name === 'recall') + ? `The "recall" function is ALWAYS used after a user question. Even if it was used before, your job is to answer the last user question, + even if the "recall" function was executed after that. Consider the tools you need to answer the user's question.` + : '' + } + + Rather than explaining how you would call a function, just generate the XML to call the function. It will automatically be + executed and returned to you. + + These results are generally not visible to the user. Treat them as if they are not, + unless specified otherwise. + + ONLY respond with XML, do not add any text. + + If a parameter allows multiple values, separate the values by "," + + You may call them like this. + + + + $TOOL_NAME + + <$PARAMETER_NAME>$PARAMETER_VALUE + ... + + + + + Here are the tools available: + + + ${filteredFunctions + .map( + (fn) => ` + ${fn.name} + ${fn.description} + + ${jsonSchemaToFlatParameters(fn.parameters).map((param) => { + return ` + ${param.name} + ${param.type} + + ${param.description || ''} + Required: ${!!param.required} + Multiple: ${!!param.array} + ${ + param.enum || param.constant + ? `Allowed values: ${castArray(param.constant || param.enum).join(', ')}` + : '' + } + + `; + })} + + ` + ) + .join('\n')} + + + + Examples: + + Assistant: + + + my_tool + + foo + + + + + Assistant: + + + another_tool + + foo + + + + + `; + } + + const formattedMessages = [ + { + role: 'system', + content: `${replaceFunctionsWithTools(systemMessage.message.content!)} + + ${functionsPrompt} + `, + }, + ...otherMessages.map((message, index) => { + const builder = new Builder({ headless: true }); + if (message.message.name) { + const deserialized = JSON.parse(message.message.content || '{}'); + + if ('error' in deserialized) { + return { + role: message.message.role, + content: dedent(` + + ${builder.buildObject(deserialized)} + + + `), + }; + } + + return { + role: message.message.role, + content: dedent(` + + + ${message.message.name} + + ${builder.buildObject(deserialized)} + + + `), + }; + } + + let content = replaceFunctionsWithTools(message.message.content || ''); + + if (message.message.function_call?.name) { + content += builder.buildObject({ + function_calls: { + invoke: { + tool_name: message.message.function_call.name, + parameters: JSON.parse(message.message.function_call.arguments || '{}'), + }, + }, + }); + } + + if (index === otherMessages.length - 1 && functionCall) { + content += ` + + Remember, use the ${functionCall} tool to answer this question.`; + } + + return { + role: message.message.role, + content, + }; + }), + ]; + + return { + subAction: 'invokeStream', + subActionParams: { + messages: formattedMessages, + temperature: 0, + stopSequences: ['\n\nHuman:', ''], + }, + }; + }, + streamIntoObservable: (readable) => + eventstreamSerdeIntoObservable(readable).pipe( + tap((value) => { + if ('modelStreamErrorException' in value) { + throw createInternalServerError(value.modelStreamErrorException.originalMessage); + } + }), + filter((value): value is BedrockChunkMember => { + return 'chunk' in value && value.chunk?.headers?.[':event-type']?.value === 'chunk'; + }), + processBedrockStream({ logger, functions }) + ), +}); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/openai_adapter.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/openai_adapter.ts new file mode 100644 index 0000000000000..61935d891a1db --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/openai_adapter.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { compact, isEmpty, omit } from 'lodash'; +import OpenAI from 'openai'; +import { MessageRole } from '../../../../common'; +import { processOpenAiStream } from '../../../../common/utils/process_openai_stream'; +import { eventsourceStreamIntoObservable } from '../../util/eventsource_stream_into_observable'; +import { LlmApiAdapterFactory } from './types'; + +export const createOpenAiAdapter: LlmApiAdapterFactory = ({ + messages, + functions, + functionCall, + logger, +}) => { + return { + getSubAction: () => { + const messagesForOpenAI: Array< + Omit & { + role: MessageRole; + } + > = compact( + messages + .filter((message) => message.message.content || message.message.function_call?.name) + .map((message) => { + const role = + message.message.role === MessageRole.Elastic + ? MessageRole.User + : message.message.role; + + return { + role, + content: message.message.content, + function_call: isEmpty(message.message.function_call?.name) + ? undefined + : omit(message.message.function_call, 'trigger'), + name: message.message.name, + }; + }) + ); + + const functionsForOpenAI = functions; + + const request: Omit & { model?: string } = { + messages: messagesForOpenAI as OpenAI.ChatCompletionCreateParams['messages'], + stream: true, + ...(!!functions?.length ? { functions: functionsForOpenAI } : {}), + temperature: 0, + function_call: functionCall ? { name: functionCall } : undefined, + }; + + return { + subAction: 'stream', + subActionParams: { + body: JSON.stringify(request), + stream: true, + }, + }; + }, + streamIntoObservable: (readable) => { + return eventsourceStreamIntoObservable(readable).pipe(processOpenAiStream()); + }, + }; +}; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.test.ts new file mode 100644 index 0000000000000..78775b4d79d51 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.test.ts @@ -0,0 +1,256 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { fromUtf8 } from '@smithy/util-utf8'; +import { lastValueFrom, of } from 'rxjs'; +import { Logger } from '@kbn/logging'; +import { concatenateChatCompletionChunks } from '../../../../common/utils/concatenate_chat_completion_chunks'; +import { processBedrockStream } from './process_bedrock_stream'; +import { MessageRole } from '../../../../common'; + +describe('processBedrockStream', () => { + const encode = (completion: string, stop?: string) => { + return { + chunk: { + headers: { + '::event-type': { value: 'chunk', type: 'uuid' as const }, + }, + body: fromUtf8( + JSON.stringify({ + bytes: Buffer.from(JSON.stringify({ completion, stop }), 'utf-8').toString('base64'), + }) + ), + }, + }; + }; + + function getLoggerMock() { + return { + debug: jest.fn(), + } as unknown as Logger; + } + + it('parses normal text messages', async () => { + expect( + await lastValueFrom( + of(encode('This'), encode(' is'), encode(' some normal'), encode(' text')).pipe( + processBedrockStream({ logger: getLoggerMock() }), + concatenateChatCompletionChunks() + ) + ) + ).toEqual({ + message: { + content: 'This is some normal text', + function_call: { + arguments: '', + name: '', + trigger: MessageRole.Assistant, + }, + role: MessageRole.Assistant, + }, + }); + }); + + it('parses function calls when no text is given', async () => { + expect( + await lastValueFrom( + of( + encode('my_toolmy_value', '') + ).pipe( + processBedrockStream({ + logger: getLoggerMock(), + functions: [ + { + name: 'my_tool', + description: '', + parameters: { + properties: { + my_param: { + type: 'string', + }, + }, + }, + }, + ], + }), + concatenateChatCompletionChunks() + ) + ) + ).toEqual({ + message: { + content: '', + function_call: { + arguments: JSON.stringify({ my_param: 'my_value' }), + name: 'my_tool', + trigger: MessageRole.Assistant, + }, + role: MessageRole.Assistant, + }, + }); + }); + + it('parses function calls when they are prefaced by text', async () => { + expect( + await lastValueFrom( + of( + encode('This is'), + encode(' my text\nmy_toolmy_value', '') + ).pipe( + processBedrockStream({ + logger: getLoggerMock(), + functions: [ + { + name: 'my_tool', + description: '', + parameters: { + properties: { + my_param: { + type: 'string', + }, + }, + }, + }, + ], + }), + concatenateChatCompletionChunks() + ) + ) + ).toEqual({ + message: { + content: 'This is my text', + function_call: { + arguments: JSON.stringify({ my_param: 'my_value' }), + name: 'my_tool', + trigger: MessageRole.Assistant, + }, + role: MessageRole.Assistant, + }, + }); + }); + + it('throws an error if the XML cannot be parsed', async () => { + expect( + async () => + await lastValueFrom( + of( + encode('my_toolmy_value', '') + ).pipe( + processBedrockStream({ + logger: getLoggerMock(), + functions: [ + { + name: 'my_tool', + description: '', + parameters: { + properties: { + my_param: { + type: 'string', + }, + }, + }, + }, + ], + }), + concatenateChatCompletionChunks() + ) + ) + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "Unexpected close tag + Line: 0 + Column: 49 + Char: >" + `); + }); + + it('throws an error if the function does not exist', async () => { + expect( + async () => + await lastValueFrom( + of( + encode('my_other_toolmy_value', '') + ).pipe( + processBedrockStream({ + logger: getLoggerMock(), + functions: [ + { + name: 'my_tool', + description: '', + parameters: { + properties: { + my_param: { + type: 'string', + }, + }, + }, + }, + ], + }), + concatenateChatCompletionChunks() + ) + ) + ).rejects.toThrowError( + 'Function definition for my_other_tool not found. Available are: my_tool' + ); + }); + + it('successfully invokes a function without parameters', async () => { + expect( + await lastValueFrom( + of( + encode('my_tool', '') + ).pipe( + processBedrockStream({ + logger: getLoggerMock(), + functions: [ + { + name: 'my_tool', + description: '', + parameters: { + properties: { + my_param: { + type: 'string', + }, + }, + }, + }, + ], + }), + concatenateChatCompletionChunks() + ) + ) + ).toEqual({ + message: { + content: '', + function_call: { + arguments: '{}', + name: 'my_tool', + trigger: MessageRole.Assistant, + }, + role: MessageRole.Assistant, + }, + }); + }); +}); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.ts new file mode 100644 index 0000000000000..41bc19717485c --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/process_bedrock_stream.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { toUtf8 } from '@smithy/util-utf8'; +import { Observable } from 'rxjs'; +import { v4 } from 'uuid'; +import { Parser } from 'xml2js'; +import type { Logger } from '@kbn/logging'; +import { JSONSchema } from 'json-schema-to-ts'; +import { + ChatCompletionChunkEvent, + createInternalServerError, + StreamingChatResponseEventType, +} from '../../../../common/conversation_complete'; +import type { BedrockChunkMember } from '../../util/eventstream_serde_into_observable'; +import { convertDeserializedXmlWithJsonSchema } from '../../util/convert_deserialized_xml_with_json_schema'; + +async function parseFunctionCallXml({ + xml, + functions, +}: { + xml: string; + functions?: Array<{ name: string; description: string; parameters: JSONSchema }>; +}) { + const parser = new Parser(); + + const parsedValue = await parser.parseStringPromise(xml); + const invoke = parsedValue.function_calls.invoke[0]; + const fnName = invoke.tool_name[0]; + const parameters: Array> = invoke.parameters ?? []; + const functionDef = functions?.find((fn) => fn.name === fnName); + + if (!functionDef) { + throw createInternalServerError( + `Function definition for ${fnName} not found. ${ + functions?.length + ? 'Available are: ' + functions.map((fn) => fn.name).join(', ') + '.' + : 'No functions are available.' + }` + ); + } + + const args = convertDeserializedXmlWithJsonSchema(parameters, functionDef.parameters); + + return { + name: fnName, + arguments: JSON.stringify(args), + }; +} + +export function processBedrockStream({ + logger, + functions, +}: { + logger: Logger; + functions?: Array<{ name: string; description: string; parameters: JSONSchema }>; +}) { + return (source: Observable) => + new Observable((subscriber) => { + let functionCallsBuffer: string = ''; + const id = v4(); + + // We use this to make sure we don't complete the Observable + // before all operations have completed. + let nextPromise = Promise.resolve(); + + // As soon as we see a `'; + + const isInFunctionCall = !!functionCallsBuffer; + + if (isStartOfFunctionCall) { + const [before, after] = completion.split(' { + subscriber.next({ + id, + type: StreamingChatResponseEventType.ChatCompletionChunk, + message: { + content: index === parts.length - 1 ? part : part + ' ', + }, + }); + }); + } + } + + source.subscribe({ + next: (value) => { + nextPromise = nextPromise.then(() => + handleNext(value).catch((error) => subscriber.error(error)) + ); + }, + error: (err) => { + subscriber.error(err); + }, + complete: () => { + nextPromise.then(() => subscriber.complete()); + }, + }); + }); +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/types.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/types.ts new file mode 100644 index 0000000000000..6ef3611bb4aae --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/adapters/types.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Readable } from 'node:stream'; +import type { Observable } from 'rxjs'; +import type { Logger } from '@kbn/logging'; +import type { Message } from '../../../../common'; +import type { ChatCompletionChunkEvent } from '../../../../common/conversation_complete'; +import type { CompatibleJSONSchema } from '../../../../common/types'; + +export type LlmApiAdapterFactory = (options: { + logger: Logger; + messages: Message[]; + functions?: Array<{ name: string; description: string; parameters: CompatibleJSONSchema }>; + functionCall?: string; +}) => LlmApiAdapter; + +export interface LlmApiAdapter { + getSubAction: () => { subAction: string; subActionParams: Record }; + streamIntoObservable: (readable: Readable) => Observable; +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts index fb22828247474..cbcbf0ea3fa3a 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts @@ -16,6 +16,7 @@ import { finished } from 'stream/promises'; import { ObservabilityAIAssistantClient } from '.'; import { createResourceNamesMap } from '..'; import { MessageRole, type Message } from '../../../common'; +import { ObservabilityAIAssistantConnectorType } from '../../../common/connectors'; import { ChatCompletionChunkEvent, ChatCompletionErrorCode, @@ -63,7 +64,7 @@ function createLlmSimulator() { ], }; await new Promise((resolve, reject) => { - stream.write(`data: ${JSON.stringify(chunk)}\n`, undefined, (err) => { + stream.write(`data: ${JSON.stringify(chunk)}\n\n`, undefined, (err) => { return err ? reject(err) : resolve(); }); }); @@ -72,7 +73,7 @@ function createLlmSimulator() { if (stream.destroyed) { throw new Error('Stream is already destroyed'); } - await new Promise((resolve) => stream.write('data: [DONE]', () => stream.end(resolve))); + await new Promise((resolve) => stream.write('data: [DONE]\n\n', () => stream.end(resolve))); }, error: (error: Error) => { stream.destroy(error); @@ -85,6 +86,7 @@ describe('Observability AI Assistant client', () => { const actionsClientMock: DeeplyMockedKeys = { execute: jest.fn(), + get: jest.fn(), } as any; const internalUserEsClientMock: DeeplyMockedKeys = { @@ -125,6 +127,15 @@ describe('Observability AI Assistant client', () => { return name !== 'recall'; }); + actionsClientMock.get.mockResolvedValue({ + actionTypeId: ObservabilityAIAssistantConnectorType.OpenAI, + id: 'foo', + name: 'My connector', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, + }); + currentUserEsClientMock.search.mockResolvedValue({ hits: { hits: [], @@ -491,6 +502,8 @@ describe('Observability AI Assistant client', () => { stream.on('data', dataHandler); + await nextTick(); + await llmSimulator.next({ content: 'Hello' }); await llmSimulator.complete(); @@ -590,6 +603,8 @@ describe('Observability AI Assistant client', () => { stream.on('data', dataHandler); + await nextTick(); + await llmSimulator.next({ content: 'Hello' }); await new Promise((resolve) => @@ -598,7 +613,7 @@ describe('Observability AI Assistant client', () => { error: { message: 'Connection unexpectedly closed', }, - })}\n`, + })}\n\n`, resolve ) ); @@ -694,6 +709,8 @@ describe('Observability AI Assistant client', () => { stream.on('data', dataHandler); + await nextTick(); + await llmSimulator.next({ content: 'Hello', function_call: { name: 'my-function', arguments: JSON.stringify({ foo: 'bar' }) }, @@ -1259,6 +1276,8 @@ describe('Observability AI Assistant client', () => { await nextLlmCallPromise; } + await nextTick(); + await requestAlertsFunctionCall(); await requestAlertsFunctionCall(); @@ -1348,6 +1367,8 @@ describe('Observability AI Assistant client', () => { stream.on('data', dataHandler); + await nextTick(); + await llmSimulator.next({ function_call: { name: 'get_top_alerts' } }); await llmSimulator.complete(); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index afd34aa8ea966..2fc6bb7be34cc 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -12,12 +12,11 @@ import type { Logger } from '@kbn/logging'; import type { PublicMethodsOf } from '@kbn/utility-types'; import apm from 'elastic-apm-node'; import { decode, encode } from 'gpt-tokenizer'; -import { compact, isEmpty, last, merge, noop, omit, pick, take } from 'lodash'; -import type OpenAI from 'openai'; +import { last, merge, noop, omit, pick, take } from 'lodash'; import { filter, - firstValueFrom, isObservable, + last as lastOperator, lastValueFrom, Observable, shareReplay, @@ -25,13 +24,14 @@ import { } from 'rxjs'; import { Readable } from 'stream'; import { v4 } from 'uuid'; +import { ObservabilityAIAssistantConnectorType } from '../../../common/connectors'; import { ChatCompletionChunkEvent, ChatCompletionErrorEvent, createConversationNotFoundError, + createTokenLimitReachedError, MessageAddEvent, StreamingChatResponseEventType, - createTokenLimitReachedError, type StreamingChatResponseEvent, } from '../../../common/conversation_complete'; import { @@ -47,7 +47,6 @@ import { } from '../../../common/types'; import { concatenateChatCompletionChunks } from '../../../common/utils/concatenate_chat_completion_chunks'; import { emitWithConcatenatedMessage } from '../../../common/utils/emit_with_concatenated_message'; -import { processOpenAiStream } from '../../../common/utils/process_openai_stream'; import type { ChatFunctionClient } from '../chat_function_client'; import { KnowledgeBaseEntryOperationType, @@ -56,7 +55,9 @@ import { } from '../knowledge_base_service'; import type { ObservabilityAIAssistantResourceNames } from '../types'; import { getAccessQuery } from '../util/get_access_query'; -import { streamIntoObservable } from '../util/stream_into_observable'; +import { createBedrockClaudeAdapter } from './adapters/bedrock_claude_adapter'; +import { createOpenAiAdapter } from './adapters/openai_adapter'; +import { LlmApiAdapter } from './adapters/types'; export class ObservabilityAIAssistantClient { constructor( @@ -465,111 +466,102 @@ export class ObservabilityAIAssistantClient { const spanId = (span?.ids['span.id'] || '').substring(0, 6); - const messagesForOpenAI: Array< - Omit & { - role: MessageRole; - } - > = compact( - messages - .filter((message) => message.message.content || message.message.function_call?.name) - .map((message) => { - const role = - message.message.role === MessageRole.Elastic ? MessageRole.User : message.message.role; - - return { - role, - content: message.message.content, - function_call: isEmpty(message.message.function_call?.name) - ? undefined - : omit(message.message.function_call, 'trigger'), - name: message.message.name, - }; - }) - ); + try { + const connector = await this.dependencies.actionsClient.get({ + id: connectorId, + }); - const functionsForOpenAI = functions; + let adapter: LlmApiAdapter; + + switch (connector.actionTypeId) { + case ObservabilityAIAssistantConnectorType.OpenAI: + adapter = createOpenAiAdapter({ + logger: this.dependencies.logger, + messages, + functionCall, + functions, + }); + break; + + case ObservabilityAIAssistantConnectorType.Bedrock: + adapter = createBedrockClaudeAdapter({ + logger: this.dependencies.logger, + messages, + functionCall, + functions, + }); + break; + + default: + throw new Error(`Connector type is not supported: ${connector.actionTypeId}`); + } - const request: Omit & { model?: string } = { - messages: messagesForOpenAI as OpenAI.ChatCompletionCreateParams['messages'], - stream: true, - ...(!!functions?.length ? { functions: functionsForOpenAI } : {}), - temperature: 0, - function_call: functionCall ? { name: functionCall } : undefined, - }; + const subAction = adapter.getSubAction(); - this.dependencies.logger.debug(`Sending conversation to connector`); - this.dependencies.logger.trace(JSON.stringify(request, null, 2)); + this.dependencies.logger.debug(`Sending conversation to connector`); + this.dependencies.logger.trace(JSON.stringify(subAction.subActionParams, null, 2)); - const now = performance.now(); + const now = performance.now(); - const executeResult = await this.dependencies.actionsClient.execute({ - actionId: connectorId, - params: { - subAction: 'stream', - subActionParams: { - body: JSON.stringify(request), - stream: true, - }, - }, - }); + const executeResult = await this.dependencies.actionsClient.execute({ + actionId: connectorId, + params: subAction, + }); - this.dependencies.logger.debug( - `Received action client response: ${executeResult.status} (took: ${Math.round( - performance.now() - now - )}ms)${spanId ? ` (${spanId})` : ''}` - ); + this.dependencies.logger.debug( + `Received action client response: ${executeResult.status} (took: ${Math.round( + performance.now() - now + )}ms)${spanId ? ` (${spanId})` : ''}` + ); - if (executeResult.status === 'error' && executeResult?.serviceMessage) { - const tokenLimitRegex = - /This model's maximum context length is (\d+) tokens\. However, your messages resulted in (\d+) tokens/g; - const tokenLimitRegexResult = tokenLimitRegex.exec(executeResult.serviceMessage); + if (executeResult.status === 'error' && executeResult?.serviceMessage) { + const tokenLimitRegex = + /This model's maximum context length is (\d+) tokens\. However, your messages resulted in (\d+) tokens/g; + const tokenLimitRegexResult = tokenLimitRegex.exec(executeResult.serviceMessage); - if (tokenLimitRegexResult) { - const [, tokenLimit, tokenCount] = tokenLimitRegexResult; - throw createTokenLimitReachedError(parseInt(tokenLimit, 10), parseInt(tokenCount, 10)); + if (tokenLimitRegexResult) { + const [, tokenLimit, tokenCount] = tokenLimitRegexResult; + throw createTokenLimitReachedError(parseInt(tokenLimit, 10), parseInt(tokenCount, 10)); + } } - } - if (executeResult.status === 'error') { - throw internal(`${executeResult?.message} - ${executeResult?.serviceMessage}`); - } + if (executeResult.status === 'error') { + throw internal(`${executeResult?.message} - ${executeResult?.serviceMessage}`); + } - const response = executeResult.data as Readable; + const response = executeResult.data as Readable; - signal.addEventListener('abort', () => response.destroy()); + signal.addEventListener('abort', () => response.destroy()); - const observable = streamIntoObservable(response).pipe(processOpenAiStream(), shareReplay()); + const response$ = adapter.streamIntoObservable(response).pipe(shareReplay()); - firstValueFrom(observable) - .catch(noop) - .finally(() => { - this.dependencies.logger.debug( - `Received first value after ${Math.round(performance.now() - now)}ms${ - spanId ? ` (${spanId})` : '' - }` - ); + response$.pipe(concatenateChatCompletionChunks(), lastOperator()).subscribe({ + error: (error) => { + this.dependencies.logger.debug('Error in chat response'); + this.dependencies.logger.debug(error); + }, + next: (message) => { + this.dependencies.logger.debug(`Received message:\n${JSON.stringify(message)}`); + }, }); - lastValueFrom(observable) - .then( - () => { + lastValueFrom(response$) + .then(() => { span?.setOutcome('success'); - }, - () => { + }) + .catch(() => { span?.setOutcome('failure'); - } - ) - .finally(() => { - this.dependencies.logger.debug( - `Completed response in ${Math.round(performance.now() - now)}ms${ - spanId ? ` (${spanId})` : '' - }` - ); - - span?.end(); - }); + }) + .finally(() => { + span?.end(); + }); - return observable; + return response$; + } catch (error) { + span?.setOutcome('failure'); + span?.end(); + throw error; + } }; find = async (options?: { query?: string }): Promise<{ conversations: Conversation[] }> => { @@ -631,13 +623,36 @@ export class ObservabilityAIAssistantClient { }) => { const response$ = await this.chat('generate_title', { messages: [ + { + '@timestamp': new Date().toString(), + message: { + role: MessageRole.System, + content: `You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you.`, + }, + }, { '@timestamp': new Date().toISOString(), message: { role: MessageRole.User, content: messages.slice(1).reduce((acc, curr) => { return `${acc} ${curr.message.role}: ${curr.message.content}`; - }, 'You are a helpful assistant for Elastic Observability. Assume the following message is the start of a conversation between you and a user; give this conversation a title based on the content below. DO NOT UNDER ANY CIRCUMSTANCES wrap this title in single or double quotes. This title is shown in a list of conversations to the user, so title it for the user, not for you. Here is the content:'), + }, 'Generate a title, using the title_conversation_function, based on the following conversation:\n\n'), + }, + }, + ], + functions: [ + { + name: 'title_conversation', + description: + 'Use this function to title the conversation. Do not wrap the title in quotes', + parameters: { + type: 'object', + properties: { + title: { + type: 'string', + }, + }, + required: ['title'], }, }, ], @@ -647,7 +662,10 @@ export class ObservabilityAIAssistantClient { const response = await lastValueFrom(response$.pipe(concatenateChatCompletionChunks())); - const input = response.message?.content || ''; + const input = + (response.message.function_call.name + ? JSON.parse(response.message.function_call.arguments).title + : response.message?.content) || ''; // This regular expression captures a string enclosed in single or double quotes. // It extracts the string content without the quotes. diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.test.ts new file mode 100644 index 0000000000000..8d1d64721abc4 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.test.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { convertDeserializedXmlWithJsonSchema } from './convert_deserialized_xml_with_json_schema'; + +describe('deserializeXmlWithJsonSchema', () => { + it('deserializes XML into a JSON object according to the JSON schema', () => { + expect( + convertDeserializedXmlWithJsonSchema( + [ + { + foo: ['bar'], + }, + ], + { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + } + ) + ).toEqual({ foo: 'bar' }); + }); + + it('converts strings to numbers if needed', () => { + expect( + convertDeserializedXmlWithJsonSchema( + [ + { + myNumber: ['0'], + }, + ], + { + type: 'object', + properties: { + myNumber: { + type: 'number', + }, + }, + } + ) + ).toEqual({ myNumber: 0 }); + }); + + it('de-dots object paths', () => { + expect( + convertDeserializedXmlWithJsonSchema( + [ + { + 'myObject.foo': ['bar'], + }, + ], + { + type: 'object', + properties: { + myObject: { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + }, + }, + } + ) + ).toEqual({ + myObject: { + foo: 'bar', + }, + }); + }); + + it('casts to an array if needed', () => { + expect( + convertDeserializedXmlWithJsonSchema( + [ + { + myNumber: ['0'], + }, + ], + { + type: 'object', + properties: { + myNumber: { + type: 'number', + }, + }, + } + ) + ).toEqual({ + myNumber: 0, + }); + + expect( + convertDeserializedXmlWithJsonSchema( + [ + { + 'labels.myProp': ['myFirstValue, mySecondValue'], + }, + ], + { + type: 'object', + properties: { + labels: { + type: 'array', + items: { + type: 'object', + properties: { + myProp: { + type: 'string', + }, + }, + }, + }, + }, + } + ) + ).toEqual({ + labels: [{ myProp: 'myFirstValue' }, { myProp: 'mySecondValue' }], + }); + }); +}); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.ts new file mode 100644 index 0000000000000..a351edb9a33a1 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/convert_deserialized_xml_with_json_schema.ts @@ -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 { set } from '@kbn/safer-lodash-set'; +import { unflatten } from 'flat'; +import type { JSONSchema } from 'json-schema-to-ts'; +import { forEach, get, isPlainObject } from 'lodash'; +import { jsonSchemaToFlatParameters } from './json_schema_to_flat_parameters'; + +// JS to XML is "lossy", e.g. everything becomes an array and a string, +// so we need a JSON schema to deserialize it + +export function convertDeserializedXmlWithJsonSchema( + parameterResults: Array>, + schema: JSONSchema +): Record { + const parameters = jsonSchemaToFlatParameters(schema); + + const result: Record = Object.fromEntries( + parameterResults.flatMap((parameterResult) => { + return Object.keys(parameterResult).map((name) => { + return [name, parameterResult[name]]; + }); + }) + ); + + parameters.forEach((param) => { + const key = param.name; + let value: any[] = result[key] ?? []; + value = param.array + ? String(value) + .split(',') + .map((val) => val.trim()) + : value; + + switch (param.type) { + case 'number': + value = value.map((val) => Number(val)); + break; + + case 'integer': + value = value.map((val) => Math.floor(Number(val))); + break; + + case 'boolean': + value = value.map((val) => String(val).toLowerCase() === 'true' || val === '1'); + break; + } + + result[key] = param.array ? value : value[0]; + }); + + function getArrayPaths(subSchema: JSONSchema, path: string = ''): string[] { + if (typeof subSchema === 'boolean') { + return []; + } + + if (subSchema.type === 'object') { + return Object.keys(subSchema.properties!).flatMap((key) => { + return getArrayPaths(subSchema.properties![key], path ? path + '.' + key : key); + }); + } + + if (subSchema.type === 'array') { + return [path, ...getArrayPaths(subSchema.items as JSONSchema, path)]; + } + + return []; + } + + const arrayPaths = getArrayPaths(schema); + + const unflattened: Record = unflatten(result); + + arrayPaths.forEach((arrayPath) => { + const target: any[] = []; + function walk(value: any, path: string) { + if (Array.isArray(value)) { + value.forEach((val, index) => { + if (!target[index]) { + target[index] = {}; + } + if (path) { + set(target[index], path, val); + } else { + target[index] = val; + } + }); + } else if (isPlainObject(value)) { + forEach(value, (val, key) => { + walk(val, path ? path + '.' + key : key); + }); + } + } + const val = get(unflattened, arrayPath); + + walk(val, ''); + + set(unflattened, arrayPath, target); + }); + + return unflattened; +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/eventsource_stream_into_observable.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/eventsource_stream_into_observable.ts new file mode 100644 index 0000000000000..5ff332128f8ac --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/eventsource_stream_into_observable.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createParser } from 'eventsource-parser'; +import { Readable } from 'node:stream'; +import { Observable } from 'rxjs'; + +// OpenAI sends server-sent events, so we can use a library +// to deal with parsing, buffering, unicode etc + +export function eventsourceStreamIntoObservable(readable: Readable) { + return new Observable((subscriber) => { + const parser = createParser((event) => { + if (event.type === 'event') { + subscriber.next(event.data); + } + }); + + async function processStream() { + for await (const chunk of readable) { + parser.feed(chunk.toString()); + } + } + + processStream().then( + () => { + subscriber.complete(); + }, + (error) => { + subscriber.error(error); + } + ); + }); +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/eventstream_serde_into_observable.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/eventstream_serde_into_observable.ts new file mode 100644 index 0000000000000..9252ec7588e3e --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/eventstream_serde_into_observable.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EventStreamMarshaller } from '@smithy/eventstream-serde-node'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; +import { identity } from 'lodash'; +import { Observable } from 'rxjs'; +import { Readable } from 'stream'; +import { Message } from '@smithy/types'; + +interface ModelStreamErrorException { + name: 'ModelStreamErrorException'; + originalStatusCode?: number; + originalMessage?: string; +} + +export interface BedrockChunkMember { + chunk: Message; +} + +export interface ModelStreamErrorExceptionMember { + modelStreamErrorException: ModelStreamErrorException; +} + +export type BedrockStreamMember = BedrockChunkMember | ModelStreamErrorExceptionMember; + +// AWS uses SerDe to send over serialized data, so we use their +// @smithy library to parse the stream data + +export function eventstreamSerdeIntoObservable(readable: Readable) { + return new Observable((subscriber) => { + const marshaller = new EventStreamMarshaller({ + utf8Encoder: toUtf8, + utf8Decoder: fromUtf8, + }); + + async function processStream() { + for await (const chunk of marshaller.deserialize(readable, identity)) { + if (chunk) { + subscriber.next(chunk as BedrockStreamMember); + } + } + } + + processStream().then( + () => { + subscriber.complete(); + }, + (error) => { + subscriber.error(error); + } + ); + }); +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/flush_buffer.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/flush_buffer.ts new file mode 100644 index 0000000000000..22723f1e49966 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/flush_buffer.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { repeat } from 'lodash'; +import { identity, Observable, OperatorFunction } from 'rxjs'; +import { + BufferFlushEvent, + StreamingChatResponseEventType, + StreamingChatResponseEventWithoutError, +} from '../../../common/conversation_complete'; + +// The Cloud proxy currently buffers 4kb or 8kb of data until flushing. +// This decreases the responsiveness of the streamed response, +// so we manually insert some data every 250ms if needed to force it +// to flush. + +export function flushBuffer( + isCloud: boolean +): OperatorFunction { + if (!isCloud) { + return identity; + } + + return (source: Observable) => + new Observable((subscriber) => { + const cloudProxyBufferSize = 4096; + let currentBufferSize: number = 0; + + const flushBufferIfNeeded = () => { + if (currentBufferSize && currentBufferSize <= cloudProxyBufferSize) { + subscriber.next({ + data: repeat('0', cloudProxyBufferSize * 2), + type: StreamingChatResponseEventType.BufferFlush, + }); + currentBufferSize = 0; + } + }; + + const intervalId = setInterval(flushBufferIfNeeded, 250); + + source.subscribe({ + next: (value) => { + currentBufferSize = + currentBufferSize <= cloudProxyBufferSize + ? JSON.stringify(value).length + currentBufferSize + : cloudProxyBufferSize; + subscriber.next(value); + }, + error: (error) => { + clearInterval(intervalId); + subscriber.error(error); + }, + complete: () => { + clearInterval(intervalId); + subscriber.complete(); + }, + }); + }); +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.test.ts new file mode 100644 index 0000000000000..afcfedf71dc85 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.test.ts @@ -0,0 +1,208 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { jsonSchemaToFlatParameters } from './json_schema_to_flat_parameters'; + +describe('jsonSchemaToFlatParameters', () => { + it('converts a simple object', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + str: { + type: 'string', + }, + bool: { + type: 'boolean', + }, + }, + }) + ).toEqual([ + { + name: 'str', + type: 'string', + required: false, + }, + { + name: 'bool', + type: 'boolean', + required: false, + }, + ]); + }); + + it('handles descriptions', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + str: { + type: 'string', + description: 'My string', + }, + }, + }) + ).toEqual([ + { + name: 'str', + type: 'string', + required: false, + description: 'My string', + }, + ]); + }); + + it('handles required properties', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + str: { + type: 'string', + }, + bool: { + type: 'boolean', + }, + }, + required: ['str'], + }) + ).toEqual([ + { + name: 'str', + type: 'string', + required: true, + }, + { + name: 'bool', + type: 'boolean', + required: false, + }, + ]); + }); + + it('handles objects', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + nested: { + type: 'object', + properties: { + str: { + type: 'string', + }, + }, + }, + }, + required: ['str'], + }) + ).toEqual([ + { + name: 'nested.str', + required: false, + type: 'string', + }, + ]); + }); + + it('handles arrays', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + arr: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + required: ['str'], + }) + ).toEqual([ + { + name: 'arr', + required: false, + array: true, + type: 'string', + }, + ]); + + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + arr: { + type: 'array', + items: { + type: 'object', + properties: { + foo: { + type: 'string', + }, + bar: { + type: 'object', + properties: { + baz: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + required: ['arr.foo.bar'], + }) + ).toEqual([ + { + name: 'arr.foo', + required: false, + array: true, + type: 'string', + }, + { + name: 'arr.bar.baz', + required: false, + array: true, + type: 'string', + }, + ]); + }); + + it('handles enum and const', () => { + expect( + jsonSchemaToFlatParameters({ + type: 'object', + properties: { + constant: { + type: 'string', + const: 'foo', + }, + enum: { + type: 'number', + enum: ['foo', 'bar'], + }, + }, + required: ['str'], + }) + ).toEqual([ + { + name: 'constant', + required: false, + type: 'string', + constant: 'foo', + }, + { + name: 'enum', + required: false, + type: 'number', + enum: ['foo', 'bar'], + }, + ]); + }); +}); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.ts new file mode 100644 index 0000000000000..cd984b0cfd7d0 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/json_schema_to_flat_parameters.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { JSONSchema } from 'json-schema-to-ts'; +import { castArray, isArray } from 'lodash'; + +interface Parameter { + name: string; + type: string; + description?: string; + required?: boolean; + enum?: unknown[]; + constant?: unknown; + array?: boolean; +} + +export function jsonSchemaToFlatParameters( + schema: JSONSchema, + name: string = '', + options: { required?: boolean; array?: boolean } = {} +): Parameter[] { + if (typeof schema === 'boolean') { + return []; + } + + switch (schema.type) { + case 'string': + case 'number': + case 'boolean': + case 'integer': + case 'null': + return [ + { + name, + type: schema.type, + description: schema.description, + array: options.array, + required: options.required, + constant: schema.const, + enum: schema.enum !== undefined ? castArray(schema.enum) : schema.enum, + }, + ]; + + case 'array': + if ( + typeof schema.items === 'boolean' || + typeof schema.items === 'undefined' || + isArray(schema.items) + ) { + return []; + } + return jsonSchemaToFlatParameters(schema.items as JSONSchema, name, { + ...options, + array: true, + }); + + default: + case 'object': + if (typeof schema.properties === 'undefined') { + return []; + } + return Object.entries(schema.properties).flatMap(([key, subSchema]) => { + return jsonSchemaToFlatParameters(subSchema, name ? `${name}.${key}` : key, { + ...options, + required: schema.required && schema.required.includes(key) ? true : false, + }); + }); + } +} diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/observable_into_stream.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/observable_into_stream.ts index a1ec52918453f..3ca09acde2b6f 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/util/observable_into_stream.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/observable_into_stream.ts @@ -8,14 +8,15 @@ import { Observable } from 'rxjs'; import { PassThrough } from 'stream'; import { + BufferFlushEvent, ChatCompletionErrorEvent, isChatCompletionError, - StreamingChatResponseEvent, StreamingChatResponseEventType, + StreamingChatResponseEventWithoutError, } from '../../../common/conversation_complete'; export function observableIntoStream( - source: Observable> + source: Observable ) { const stream = new PassThrough(); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/stream_into_observable.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/stream_into_observable.ts index 764e39fdec152..b2c65c51da9cc 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/util/stream_into_observable.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/stream_into_observable.ts @@ -5,20 +5,25 @@ * 2.0. */ -import { concatMap, filter, from, map, Observable } from 'rxjs'; +import { Observable } from 'rxjs'; import type { Readable } from 'stream'; -export function streamIntoObservable(readable: Readable): Observable { - let lineBuffer = ''; +export function streamIntoObservable(readable: Readable): Observable { + return new Observable((subscriber) => { + const decodedStream = readable; - return from(readable).pipe( - map((chunk: Buffer) => chunk.toString('utf-8')), - map((part) => { - const lines = (lineBuffer + part).split('\n'); - lineBuffer = lines.pop() || ''; // Keep the last incomplete line for the next chunk - return lines; - }), - concatMap((lines) => lines), - filter((line) => line.trim() !== '') - ); + async function processStream() { + for await (const chunk of decodedStream) { + subscriber.next(chunk); + } + } + + processStream() + .then(() => { + subscriber.complete(); + }) + .catch((error) => { + subscriber.error(error); + }); + }); } diff --git a/x-pack/plugins/observability_ai_assistant/server/types.ts b/x-pack/plugins/observability_ai_assistant/server/types.ts index ea2d3ee39e426..21fcc21f39a65 100644 --- a/x-pack/plugins/observability_ai_assistant/server/types.ts +++ b/x-pack/plugins/observability_ai_assistant/server/types.ts @@ -23,7 +23,8 @@ import type { } from '@kbn/data-views-plugin/server'; import type { MlPluginSetup, MlPluginStart } from '@kbn/ml-plugin/server'; import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; -import { ObservabilityAIAssistantService } from './service'; +import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server'; +import type { ObservabilityAIAssistantService } from './service'; export interface ObservabilityAIAssistantPluginSetup { /** @@ -47,6 +48,7 @@ export interface ObservabilityAIAssistantPluginSetupDependencies { dataViews: DataViewsServerPluginSetup; ml: MlPluginSetup; licensing: LicensingPluginSetup; + cloud?: CloudSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { actions: ActionsPluginStart; @@ -56,4 +58,5 @@ export interface ObservabilityAIAssistantPluginStartDependencies { dataViews: DataViewsServerPluginStart; ml: MlPluginStart; licensing: LicensingPluginStart; + cloud?: CloudStart; } diff --git a/x-pack/plugins/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_ai_assistant/tsconfig.json index f5a29c470fe7a..13af731fd49db 100644 --- a/x-pack/plugins/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_ai_assistant/tsconfig.json @@ -61,6 +61,8 @@ "@kbn/apm-synthtrace-client", "@kbn/apm-synthtrace", "@kbn/code-editor", + "@kbn/safer-lodash-set", + "@kbn/cloud-plugin", "@kbn/ui-actions-plugin", "@kbn/expressions-plugin", "@kbn/visualization-utils", diff --git a/x-pack/plugins/stack_connectors/common/bedrock/constants.ts b/x-pack/plugins/stack_connectors/common/bedrock/constants.ts index 242447d505218..ea3fb7af72fa9 100644 --- a/x-pack/plugins/stack_connectors/common/bedrock/constants.ts +++ b/x-pack/plugins/stack_connectors/common/bedrock/constants.ts @@ -23,6 +23,6 @@ export enum SUB_ACTION { } export const DEFAULT_TOKEN_LIMIT = 8191; -export const DEFAULT_BEDROCK_MODEL = 'anthropic.claude-v2'; +export const DEFAULT_BEDROCK_MODEL = 'anthropic.claude-v2:1'; export const DEFAULT_BEDROCK_URL = `https://bedrock-runtime.us-east-1.amazonaws.com` as const; diff --git a/x-pack/plugins/stack_connectors/common/bedrock/schema.ts b/x-pack/plugins/stack_connectors/common/bedrock/schema.ts index 057780a803560..c26ce8c1e88c3 100644 --- a/x-pack/plugins/stack_connectors/common/bedrock/schema.ts +++ b/x-pack/plugins/stack_connectors/common/bedrock/schema.ts @@ -32,6 +32,8 @@ export const InvokeAIActionParamsSchema = schema.object({ }) ), model: schema.maybe(schema.string()), + temperature: schema.maybe(schema.number()), + stopSequences: schema.maybe(schema.arrayOf(schema.string())), }); export const InvokeAIActionResponseSchema = schema.object({ diff --git a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx index 7678f52321dd3..0ccd8c1d08023 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx @@ -102,7 +102,7 @@ const BedrockParamsFields: React.FunctionComponent { editSubActionParams({ model: ev.target.value }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts index 3cd2ad2061ffd..3b1cb3bc96ec8 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts @@ -73,7 +73,7 @@ describe('BedrockConnector', () => { 'Content-Type': 'application/json', }, host: 'bedrock-runtime.us-east-1.amazonaws.com', - path: '/model/anthropic.claude-v2/invoke', + path: '/model/anthropic.claude-v2:1/invoke', service: 'bedrock', }, { accessKeyId: '123', secretAccessKey: 'secret' } @@ -137,7 +137,7 @@ describe('BedrockConnector', () => { 'x-amzn-bedrock-accept': '*/*', }, host: 'bedrock-runtime.us-east-1.amazonaws.com', - path: '/model/anthropic.claude-v2/invoke-with-response-stream', + path: '/model/anthropic.claude-v2:1/invoke-with-response-stream', service: 'bedrock', }, { accessKeyId: '123', secretAccessKey: 'secret' } @@ -165,14 +165,53 @@ describe('BedrockConnector', () => { it('formats messages from user, assistant, and system', async () => { await connector.invokeStream({ messages: [ + { + role: 'system', + content: 'Be a good chatbot', + }, { role: 'user', content: 'Hello world', }, + { + role: 'assistant', + content: 'Hi, I am a good chatbot', + }, + { + role: 'user', + content: 'What is 2+2?', + }, + ], + }); + expect(mockRequest).toHaveBeenCalledWith({ + signed: true, + responseType: 'stream', + url: `${DEFAULT_BEDROCK_URL}/model/${DEFAULT_BEDROCK_MODEL}/invoke-with-response-stream`, + method: 'post', + responseSchema: StreamingResponseSchema, + data: JSON.stringify({ + prompt: + 'Be a good chatbot\n\nHuman:Hello world\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', + max_tokens_to_sample: DEFAULT_TOKEN_LIMIT, + temperature: 0.5, + stop_sequences: ['\n\nHuman:'], + }), + }); + }); + + it('formats the system message as a user message for claude<2.1', async () => { + const modelOverride = 'anthropic.claude-v2'; + + await connector.invokeStream({ + messages: [ { role: 'system', content: 'Be a good chatbot', }, + { + role: 'user', + content: 'Hello world', + }, { role: 'assistant', content: 'Hi, I am a good chatbot', @@ -182,16 +221,17 @@ describe('BedrockConnector', () => { content: 'What is 2+2?', }, ], + model: modelOverride, }); expect(mockRequest).toHaveBeenCalledWith({ signed: true, responseType: 'stream', - url: `${DEFAULT_BEDROCK_URL}/model/${DEFAULT_BEDROCK_MODEL}/invoke-with-response-stream`, + url: `${DEFAULT_BEDROCK_URL}/model/${modelOverride}/invoke-with-response-stream`, method: 'post', responseSchema: StreamingResponseSchema, data: JSON.stringify({ prompt: - '\n\nHuman:Hello world\n\nHuman:Be a good chatbot\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', + '\n\nHuman:Be a good chatbot\n\nHuman:Hello world\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', max_tokens_to_sample: DEFAULT_TOKEN_LIMIT, temperature: 0.5, stop_sequences: ['\n\nHuman:'], @@ -244,14 +284,14 @@ describe('BedrockConnector', () => { it('formats messages from user, assistant, and system', async () => { const response = await connector.invokeAI({ messages: [ - { - role: 'user', - content: 'Hello world', - }, { role: 'system', content: 'Be a good chatbot', }, + { + role: 'user', + content: 'Hello world', + }, { role: 'assistant', content: 'Hi, I am a good chatbot', @@ -271,7 +311,7 @@ describe('BedrockConnector', () => { responseSchema: RunActionResponseSchema, data: JSON.stringify({ prompt: - '\n\nHuman:Hello world\n\nHuman:Be a good chatbot\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', + 'Be a good chatbot\n\nHuman:Hello world\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', max_tokens_to_sample: DEFAULT_TOKEN_LIMIT, temperature: 0.5, stop_sequences: ['\n\nHuman:'], diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts index f70a592509776..3fdbaae1d702a 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts @@ -26,7 +26,11 @@ import type { InvokeAIActionResponse, StreamActionParams, } from '../../../common/bedrock/types'; -import { SUB_ACTION, DEFAULT_TOKEN_LIMIT } from '../../../common/bedrock/constants'; +import { + SUB_ACTION, + DEFAULT_TOKEN_LIMIT, + DEFAULT_BEDROCK_MODEL, +} from '../../../common/bedrock/constants'; import { DashboardActionParams, DashboardActionResponse, @@ -233,9 +237,14 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B * @param messages An array of messages to be sent to the API * @param model Optional model to be used for the API request. If not provided, the default model from the connector will be used. */ - public async invokeStream({ messages, model }: InvokeAIActionParams): Promise { + public async invokeStream({ + messages, + model, + stopSequences, + temperature, + }: InvokeAIActionParams): Promise { const res = (await this.streamApi({ - body: JSON.stringify(formatBedrockBody({ messages })), + body: JSON.stringify(formatBedrockBody({ messages, model, stopSequences, temperature })), model, })) as unknown as IncomingMessage; return res; @@ -250,20 +259,43 @@ The Kibana Connector in use may need to be reconfigured with an updated Amazon B messages, model, }: InvokeAIActionParams): Promise { - const res = await this.runApi({ body: JSON.stringify(formatBedrockBody({ messages })), model }); + const res = await this.runApi({ + body: JSON.stringify(formatBedrockBody({ messages, model })), + model, + }); return { message: res.completion.trim() }; } } const formatBedrockBody = ({ + model = DEFAULT_BEDROCK_MODEL, messages, + stopSequences = ['\n\nHuman:'], + temperature = 0.5, }: { + model?: string; messages: Array<{ role: string; content: string }>; + stopSequences?: string[]; + temperature?: number; }) => { const combinedMessages = messages.reduce((acc: string, message) => { const { role, content } = message; - // Bedrock only has Assistant and Human, so 'system' and 'user' will be converted to Human - const bedrockRole = role === 'assistant' ? '\n\nAssistant:' : '\n\nHuman:'; + const [, , modelName, majorVersion, minorVersion] = + (model || '').match(/(\w+)\.(.*)-v(\d+)(?::(\d+))?/) || []; + // Claude only has Assistant and Human, so 'user' will be converted to Human + let bedrockRole: string; + + if ( + role === 'system' && + modelName === 'claude' && + Number(majorVersion) >= 2 && + Number(minorVersion) >= 1 + ) { + bedrockRole = ''; + } else { + bedrockRole = role === 'assistant' ? '\n\nAssistant:' : '\n\nHuman:'; + } + return `${acc}${bedrockRole}${content}`; }, ''); @@ -271,8 +303,8 @@ const formatBedrockBody = ({ // end prompt in "Assistant:" to avoid the model starting its message with "Assistant:" prompt: `${combinedMessages} \n\nAssistant:`, max_tokens_to_sample: DEFAULT_TOKEN_LIMIT, - temperature: 0.5, + temperature, // prevent model from talking to itself - stop_sequences: ['\n\nHuman:'], + stop_sequences: stopSequences, }; }; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/index.ts index 5f295b8c39367..688148d51ed63 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/index.ts @@ -10,7 +10,10 @@ import { SubActionConnectorType, ValidatorType, } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { GenerativeAIForSecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; +import { + GenerativeAIForObservabilityConnectorFeatureId, + GenerativeAIForSecurityConnectorFeatureId, +} from '@kbn/actions-plugin/common'; import { urlAllowListValidator } from '@kbn/actions-plugin/server'; import { ValidatorServices } from '@kbn/actions-plugin/server/types'; import { assertURL } from '@kbn/actions-plugin/server/sub_action_framework/helpers/validators'; @@ -29,7 +32,10 @@ export const getConnectorType = (): SubActionConnectorType => ( secrets: SecretsSchema, }, validators: [{ type: ValidatorType.CONFIG, validator: configValidator }], - supportedFeatureIds: [GenerativeAIForSecurityConnectorFeatureId], + supportedFeatureIds: [ + GenerativeAIForSecurityConnectorFeatureId, + GenerativeAIForObservabilityConnectorFeatureId, + ], minimumLicenseRequired: 'enterprise' as const, renderParameterTemplates, }); diff --git a/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/bedrock_simulation.ts b/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/bedrock_simulation.ts index 29e77feb5edaf..18051754cc77a 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/bedrock_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/bedrock_simulation.ts @@ -29,7 +29,7 @@ export class BedrockSimulator extends Simulator { return BedrockSimulator.sendErrorResponse(response); } - if (request.url === '/model/anthropic.claude-v2/invoke-with-response-stream') { + if (request.url === '/model/anthropic.claude-v2:1/invoke-with-response-stream') { return BedrockSimulator.sendStreamResponse(response); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts index 14ec27598a60f..fc0ca3378d8c0 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts @@ -27,7 +27,7 @@ const secrets = { }; const defaultConfig = { - defaultModel: 'anthropic.claude-v2', + defaultModel: 'anthropic.claude-v2:1', }; // eslint-disable-next-line import/no-default-export @@ -380,14 +380,14 @@ export default function bedrockTest({ getService }: FtrProviderContext) { subAction: 'invokeAI', subActionParams: { messages: [ - { - role: 'user', - content: 'Hello world', - }, { role: 'system', content: 'Be a good chatbot', }, + { + role: 'user', + content: 'Hello world', + }, { role: 'assistant', content: 'Hi, I am a good chatbot', @@ -404,7 +404,7 @@ export default function bedrockTest({ getService }: FtrProviderContext) { expect(simulator.requestData).to.eql({ prompt: - '\n\nHuman:Hello world\n\nHuman:Be a good chatbot\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', + 'Be a good chatbot\n\nHuman:Hello world\n\nAssistant:Hi, I am a good chatbot\n\nHuman:What is 2+2? \n\nAssistant:', max_tokens_to_sample: DEFAULT_TOKEN_LIMIT, temperature: 0.5, stop_sequences: ['\n\nHuman:'], diff --git a/x-pack/test/observability_ai_assistant_api_integration/common/create_llm_proxy.ts b/x-pack/test/observability_ai_assistant_api_integration/common/create_llm_proxy.ts index 3aaaf982c3597..aead4e6276c56 100644 --- a/x-pack/test/observability_ai_assistant_api_integration/common/create_llm_proxy.ts +++ b/x-pack/test/observability_ai_assistant_api_integration/common/create_llm_proxy.ts @@ -65,7 +65,8 @@ export class LlmProxy { } } - throw new Error('No interceptors found to handle request'); + response.writeHead(500, 'No interceptors found to handle request: ' + request.url); + response.end(); }) .listen(port); } @@ -111,7 +112,7 @@ export class LlmProxy { }), next: (msg) => { const chunk = createOpenAiChunk(msg); - return write(`data: ${JSON.stringify(chunk)}\n`); + return write(`data: ${JSON.stringify(chunk)}\n\n`); }, rawWrite: (chunk: string) => { return write(chunk); @@ -120,11 +121,11 @@ export class LlmProxy { await end(); }, complete: async () => { - await write('data: [DONE]'); + await write('data: [DONE]\n\n'); await end(); }, error: async (error) => { - await write(`data: ${JSON.stringify({ error })}`); + await write(`data: ${JSON.stringify({ error })}\n\n`); await end(); }, }; diff --git a/x-pack/test/observability_ai_assistant_api_integration/tests/complete/complete.spec.ts b/x-pack/test/observability_ai_assistant_api_integration/tests/complete/complete.spec.ts index c56af40a6ab29..82ad5b6dd1224 100644 --- a/x-pack/test/observability_ai_assistant_api_integration/tests/complete/complete.spec.ts +++ b/x-pack/test/observability_ai_assistant_api_integration/tests/complete/complete.spec.ts @@ -104,7 +104,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const chunk = JSON.stringify(createOpenAiChunk('Hello')); await simulator.rawWrite(`data: ${chunk.substring(0, 10)}`); - await simulator.rawWrite(`${chunk.substring(10)}\n`); + await simulator.rawWrite(`${chunk.substring(10)}\n\n`); await simulator.complete(); await new Promise((resolve) => passThrough.on('end', () => resolve())); @@ -146,15 +146,17 @@ export default function ApiTest({ getService }: FtrProviderContext) { const titleInterceptor = proxy.intercept( 'title', (body) => - (JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming).messages - .length === 1 + ( + JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming + ).functions?.find((fn) => fn.name === 'title_conversation') !== undefined ); const conversationInterceptor = proxy.intercept( 'conversation', (body) => - (JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming).messages - .length !== 1 + ( + JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming + ).functions?.find((fn) => fn.name === 'title_conversation') === undefined ); const responsePromise = new Promise((resolve, reject) => { diff --git a/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts b/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts index ce9fc050b5e09..c0b2b36dfc029 100644 --- a/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts +++ b/x-pack/test/observability_ai_assistant_functional/tests/conversations/index.spec.ts @@ -148,15 +148,17 @@ export default function ApiTest({ getService, getPageObjects }: FtrProviderConte const titleInterceptor = proxy.intercept( 'title', (body) => - (JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming) - .messages.length === 1 + ( + JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming + ).functions?.find((fn) => fn.name === 'title_conversation') !== undefined ); const conversationInterceptor = proxy.intercept( 'conversation', (body) => - (JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming) - .messages.length !== 1 + ( + JSON.parse(body) as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming + ).functions?.find((fn) => fn.name === 'title_conversation') === undefined ); await testSubjects.setValue(ui.pages.conversations.chatInput, 'hello'); diff --git a/yarn.lock b/yarn.lock index 62b6925bfe980..42e12233631a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7750,14 +7750,32 @@ "@types/node" ">=18.0.0" axios "^1.6.0" -"@smithy/eventstream-codec@^2.0.12": - version "2.0.12" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.0.12.tgz#99fab750d0ac3941f341d912d3c3a1ab985e1a7a" - integrity sha512-ZZQLzHBJkbiAAdj2C5K+lBlYp/XJ+eH2uy+jgJgYIFW/o5AM59Hlj7zyI44/ZTDIQWmBxb3EFv/c5t44V8/g8A== +"@smithy/eventstream-codec@^2.0.12", "@smithy/eventstream-codec@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.1.1.tgz#4405ab0f9c77d439c575560c4886e59ee17d6d38" + integrity sha512-E8KYBxBIuU4c+zrpR22VsVrOPoEDzk35bQR3E+xm4k6Pa6JqzkDOdMyf9Atac5GPNKHJBdVaQ4JtjdWX2rl/nw== dependencies: "@aws-crypto/crc32" "3.0.0" - "@smithy/types" "^2.4.0" - "@smithy/util-hex-encoding" "^2.0.0" + "@smithy/types" "^2.9.1" + "@smithy/util-hex-encoding" "^2.1.1" + tslib "^2.5.0" + +"@smithy/eventstream-serde-node@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.1.1.tgz#2e1afa27f9c7eb524c1c53621049c5e4e3cea6a5" + integrity sha512-LF882q/aFidFNDX7uROAGxq3H0B7rjyPkV6QDn6/KDQ+CG7AFkRccjxRf1xqajq/Pe4bMGGr+VKAaoF6lELIQw== + dependencies: + "@smithy/eventstream-serde-universal" "^2.1.1" + "@smithy/types" "^2.9.1" + tslib "^2.5.0" + +"@smithy/eventstream-serde-universal@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.1.1.tgz#0f5eec9ad033017973a67bafb5549782499488d2" + integrity sha512-LR0mMT+XIYTxk4k2fIxEA1BPtW3685QlqufUEUAX1AJcfFfxNDKEvuCRZbO8ntJb10DrIFVJR9vb0MhDCi0sAQ== + dependencies: + "@smithy/eventstream-codec" "^2.1.1" + "@smithy/types" "^2.9.1" tslib "^2.5.0" "@smithy/is-array-buffer@^2.0.0": @@ -7767,10 +7785,10 @@ dependencies: tslib "^2.5.0" -"@smithy/types@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.4.0.tgz#ed35e429e3ea3d089c68ed1bf951d0ccbdf2692e" - integrity sha512-iH1Xz68FWlmBJ9vvYeHifVMWJf82ONx+OybPW8ZGf5wnEv2S0UXcU4zwlwJkRXuLKpcSLHrraHbn2ucdVXLb4g== +"@smithy/types@^2.4.0", "@smithy/types@^2.9.1": + version "2.9.1" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.9.1.tgz#ed04d4144eed3b8bd26d20fc85aae8d6e357ebb9" + integrity sha512-vjXlKNXyprDYDuJ7UW5iobdmyDm6g8dDG+BFUncAg/3XJaN45Gy5RWWWUVgrzIK7S4R1KWgIX5LeJcfvSI24bw== dependencies: tslib "^2.5.0" @@ -7782,10 +7800,10 @@ "@smithy/is-array-buffer" "^2.0.0" tslib "^2.5.0" -"@smithy/util-hex-encoding@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz#0aa3515acd2b005c6d55675e377080a7c513b59e" - integrity sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA== +"@smithy/util-hex-encoding@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.1.1.tgz#978252b9fb242e0a59bae4ead491210688e0d15f" + integrity sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg== dependencies: tslib "^2.5.0" @@ -9346,6 +9364,13 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== +"@types/event-stream@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/event-stream/-/event-stream-4.0.5.tgz#29f1be5f4c0de2e0312cf3b5f7146c975c08d918" + integrity sha512-pQ/RR/iuBW8K8WmwYaaC1nkZH0cHonNAIw6ktG8BCNrNuqNeERfBzNIAOq6Z7tvLzpjcMV02SZ5pxAekAYQpWA== + dependencies: + "@types/node" "*" + "@types/expect@^1.20.4": version "1.20.4" resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" @@ -9390,6 +9415,11 @@ resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.0.tgz#cbb49815a5e1129d5f23836a98d65d93822409af" integrity sha512-dxdRrUov2HVTbSRFX+7xwUPlbGYVEZK6PrSqClg2QPos3PNe0bCajkDDkDeeC1znjSH03KOEqVbXpnJuWa2wgQ== +"@types/flat@^5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.5.tgz#2304df0b2b1e6dde50d81f029593e0a1bc2474d3" + integrity sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q== + "@types/flot@^0.0.31": version "0.0.31" resolved "https://registry.yarnpkg.com/@types/flot/-/flot-0.0.31.tgz#0daca37c6c855b69a0a7e2e37dd0f84b3db8c8c1" @@ -16620,6 +16650,11 @@ events@^3.0.0, events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource-parser@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-1.1.1.tgz#576f8bcf391c5e5ccdea817abd9ead36d1754247" + integrity sha512-3Ej2iLj6ZnX+5CMxqyUb8syl9yVZwcwm8IIMrOJlF7I51zxOOrRlU3zxSb/6hFbl03ts1ZxHAGJdWLZOLyKG7w== + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -17272,7 +17307,7 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flat@^5.0.2: +flat@5, flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== From e20e6598767bb5e9f80b4629b5785b5dc63fc904 Mon Sep 17 00:00:00 2001 From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com> Date: Fri, 9 Feb 2024 09:18:44 +0100 Subject: [PATCH 061/104] Refactor TM to update the tasks that has state validation error (#176415) Resolves: #172605 This PR makes TM TaskRunner to handle state validation errors gracefully to allow it update the task state. ## To verify: 1 - Create a rule with some actions. 2- Throw an error in [state validation function](https://github.com/elastic/kibana/pull/176415/files#diff-ae4166cd6b3509473867eaed0e7b974a15b9c0268225131aef1b00d61e800e89R428) to force it to return an error. 3- Expect the rule tasks to run and update the task state successfully rather than throwing an error and preventing task update. --- .../task_state_validation.test.ts | 6 ++-- x-pack/plugins/task_manager/server/task.ts | 1 + .../server/task_running/task_runner.test.ts | 20 +++++++++--- .../server/task_running/task_runner.ts | 32 ++++++++++++++----- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts b/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts index 716e1f8dcb83f..c7ee109d17b11 100644 --- a/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts +++ b/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts @@ -308,6 +308,7 @@ describe('task state validation', () => { it('should fail the task run when setting allow_reading_invalid_state:false and reading an invalid state', async () => { const logSpy = jest.spyOn(pollingLifecycleOpts.logger, 'warn'); + const updateSpy = jest.spyOn(pollingLifecycleOpts.taskStore, 'bulkUpdate'); const id = uuidV4(); await injectTask(kibanaServer.coreStart.elasticsearch.client.asInternalUser, { @@ -331,8 +332,9 @@ describe('task state validation', () => { expect(logSpy.mock.calls[0][0]).toBe( `Task (fooType/${id}) has a validation error: [foo]: expected value of type [string] but got [boolean]` ); - expect(logSpy.mock.calls[1][0]).toBe( - `Task fooType \"${id}\" failed in attempt to run: [foo]: expected value of type [string] but got [boolean]` + expect(updateSpy).toHaveBeenCalledWith( + expect.arrayContaining([expect.objectContaining({ id, taskType: 'fooType' })]), + { validate: false } ); }); }); diff --git a/x-pack/plugins/task_manager/server/task.ts b/x-pack/plugins/task_manager/server/task.ts index c71f8b42185ca..0d064153859a5 100644 --- a/x-pack/plugins/task_manager/server/task.ts +++ b/x-pack/plugins/task_manager/server/task.ts @@ -50,6 +50,7 @@ export type SuccessfulRunResult = { state: Record; taskRunError?: DecoratedError; skipAttempts?: number; + shouldValidate?: boolean; } & ( | // ensure a SuccessfulRunResult can either specify a new `runAt` or a new `schedule`, but not both { diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts index 8a96405abfed6..6735b3c0602b8 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts @@ -1082,6 +1082,7 @@ describe('TaskManagerRunner', () => { await runner.run(); expect(store.update).toHaveBeenCalledTimes(1); + expect(store.update).toHaveBeenCalledWith(expect.any(Object), { validate: true }); const instance = store.update.mock.calls[0][0]; expect(instance.runAt.getTime()).toEqual(nextRetry.getTime()); @@ -1113,6 +1114,8 @@ describe('TaskManagerRunner', () => { await runner.run(); expect(store.update).toHaveBeenCalledTimes(1); + expect(store.update).toHaveBeenCalledWith(expect.any(Object), { validate: true }); + const instance = store.update.mock.calls[0][0]; const minRunAt = Date.now(); @@ -1179,6 +1182,8 @@ describe('TaskManagerRunner', () => { await runner.run(); expect(store.update).toHaveBeenCalledTimes(1); + expect(store.update).toHaveBeenCalledWith(expect.any(Object), { validate: true }); + sinon.assert.notCalled(getRetryStub); const instance = store.update.mock.calls[0][0]; @@ -1252,6 +1257,7 @@ describe('TaskManagerRunner', () => { new Date(Date.now() + intervalSeconds * 1000).getTime() ); expect(instance.enabled).not.toBeDefined(); + expect(store.update).toHaveBeenCalledWith(expect.any(Object), { validate: true }); }); test('throws error when the task has invalid state', async () => { @@ -1266,7 +1272,7 @@ describe('TaskManagerRunner', () => { stateVersion: 4, }; - const { runner, logger } = await readyToRunStageSetup({ + const { runner, logger, store } = await readyToRunStageSetup({ instance: mockTaskInstance, definitions: { bar: { @@ -1308,13 +1314,19 @@ describe('TaskManagerRunner', () => { }, }); - expect(() => runner.run()).rejects.toMatchInlineSnapshot( - `[Error: [foo]: expected value of type [string] but got [boolean]]` - ); + expect(await runner.run()).toEqual({ + error: { + error: new Error('[foo]: expected value of type [string] but got [boolean]'), + shouldValidate: false, + state: { bar: 'test', baz: 'test', foo: true }, + }, + tag: 'err', + }); expect(logger.warn).toHaveBeenCalledTimes(1); expect(logger.warn).toHaveBeenCalledWith( 'Task (bar/foo) has a validation error: [foo]: expected value of type [string] but got [boolean]' ); + expect(store.update).toHaveBeenCalledWith(expect.any(Object), { validate: false }); }); test('does not throw error and runs when the task has invalid state and allowReadingInvalidState = true', async () => { diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.ts index ab86d83e99310..faea2bfb7e446 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.ts @@ -314,16 +314,30 @@ export class TaskManagerRunner implements TaskRunner { const apmTrans = apm.startTransaction(this.taskType, TASK_MANAGER_RUN_TRANSACTION_TYPE, { childOf: this.instance.task.traceparent, }); + const stopTaskTimer = startTaskTimerWithEventLoopMonitoring(this.eventLoopDelayConfig); // Validate state - const validatedTaskInstance = this.validateTaskState(this.instance.task); + const stateValidationResult = this.validateTaskState(this.instance.task); + + if (stateValidationResult.error) { + const processedResult = await withSpan({ name: 'process result', type: 'task manager' }, () => + this.processResult( + asErr({ + error: stateValidationResult.error, + state: stateValidationResult.taskInstance.state, + shouldValidate: false, + }), + stopTaskTimer() + ) + ); + if (apmTrans) apmTrans.end('failure'); + return processedResult; + } const modifiedContext = await this.beforeRun({ - taskInstance: validatedTaskInstance, + taskInstance: stateValidationResult.taskInstance, }); - const stopTaskTimer = startTaskTimerWithEventLoopMonitoring(this.eventLoopDelayConfig); - this.onTaskEvent( asTaskManagerStatEvent( 'runDelay', @@ -411,11 +425,12 @@ export class TaskManagerRunner implements TaskRunner { private validateTaskState(taskInstance: ConcreteTaskInstance) { const { taskType, id } = taskInstance; try { - const validatedTask = this.taskValidator.getValidatedTaskInstanceFromReading(taskInstance); - return validatedTask; + const validatedTaskInstance = + this.taskValidator.getValidatedTaskInstanceFromReading(taskInstance); + return { taskInstance: validatedTaskInstance, error: null }; } catch (error) { this.logger.warn(`Task (${taskType}/${id}) has a validation error: ${error.message}`); - throw error; + return { taskInstance, error }; } } @@ -723,6 +738,7 @@ export class TaskManagerRunner implements TaskRunner { this.instance = asRan(this.instance.task); await this.removeTask(); } else { + const { shouldValidate = true } = unwrap(result); this.instance = asRan( await this.bufferedTaskStore.update( defaults( @@ -735,7 +751,7 @@ export class TaskManagerRunner implements TaskRunner { }, taskWithoutEnabled(this.instance.task) ), - { validate: true } + { validate: shouldValidate } ) ); } From dfa053b5a13839cca770460c54c4b47afd76dc94 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Fri, 9 Feb 2024 09:50:20 +0100 Subject: [PATCH 062/104] Fix serverless test user for MKI runs (#176430) ## Summary This PR fixes an issue when running FTR tests against MKI with the new internal test user. ### Details - The hard-coded `elastic` in the expected username of the authentication test has been replaced by whatever username is configured, making it work for local and MKI runs - During debugging, I've noticed an incomplete cleanup after the index template tests (running this suite twice on the same project failed due to an already existing resource). Added a proper cleanup. --- .../index_management/lib/templates.api.ts | 4 ++-- .../common/index_management/index_templates.ts | 13 ++++++++++++- .../common/platform_security/authentication.ts | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/templates.api.ts b/x-pack/test/api_integration/apis/management/index_management/lib/templates.api.ts index 6e8fbffbe0416..e929cbff2f188 100644 --- a/x-pack/test/api_integration/apis/management/index_management/lib/templates.api.ts +++ b/x-pack/test/api_integration/apis/management/index_management/lib/templates.api.ts @@ -36,9 +36,9 @@ export function templatesApi(getService: FtrProviderContext['getService']) { .send(payload); // Delete all templates created during tests - const cleanUpTemplates = async () => { + const cleanUpTemplates = async (additionalRequestHeaders: object = {}) => { try { - await deleteTemplates(templatesCreated); + await deleteTemplates(templatesCreated).set(additionalRequestHeaders); templatesCreated = []; } catch (e) { // Silently swallow errors diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts index 0b94803bcd765..6546d94afe391 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts @@ -23,6 +23,7 @@ export default function ({ getService }: FtrProviderContext) { let updateTemplate: typeof indexManagementService['templates']['api']['updateTemplate']; let deleteTemplates: typeof indexManagementService['templates']['api']['deleteTemplates']; let simulateTemplate: typeof indexManagementService['templates']['api']['simulateTemplate']; + let cleanUpTemplates: typeof indexManagementService['templates']['api']['cleanUpTemplates']; let getRandomString: () => string; describe('Index templates', function () { @@ -30,12 +31,22 @@ export default function ({ getService }: FtrProviderContext) { ({ templates: { helpers: { getTemplatePayload, catTemplate, getSerializedTemplate }, - api: { createTemplate, updateTemplate, deleteTemplates, simulateTemplate }, + api: { + createTemplate, + updateTemplate, + deleteTemplates, + simulateTemplate, + cleanUpTemplates, + }, }, } = indexManagementService); getRandomString = () => randomness.string({ casing: 'lower', alpha: true }); }); + after(async () => { + await cleanUpTemplates({ 'x-elastic-internal-origin': 'xxx' }); + }); + describe('get', () => { let templateName: string; diff --git a/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authentication.ts b/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authentication.ts index 4c8353487adce..da71d2ad4858a 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authentication.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authentication.ts @@ -11,6 +11,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const svlCommonApi = getService('svlCommonApi'); const supertest = getService('supertest'); + const config = getService('config'); describe('security/authentication', function () { describe('route access', () => { @@ -144,8 +145,7 @@ export default function ({ getService }: FtrProviderContext) { metadata: {}, operator: true, roles: ['superuser'], - // We use `elastic` for MKI, and `elastic_serverless` for any other testing environment. - username: expect.stringContaining('elastic'), + username: config.get('servers.kibana.username'), }); expect(status).toBe(200); }); From d2f2d43b7f691d529811e46afa2cd9791c9fc0c5 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Fri, 9 Feb 2024 09:51:15 +0100 Subject: [PATCH 063/104] [Security Solution] Improve alert UX for criticality enrichments (#176056) ## Summary ### Assign user-friendly column labels to enrichment fields for improved readability. * Add a `displayAsText` prop for Entity Analytics fields on the Alerts table. * host.asset.criticality -> Host Criticality * user.asset.criticality -> User Criticality * host.risk.calculated.level -> Host Risk Level * user.risk.calculated.level -> User Risk Level * Add migration that renames `host.risk.calculated._evel` and `user.risk.calculated_level` on local storage ### Render a custom component for the Host and User criticality inside the Alerts table cell. ![Screenshot 2024-02-02 at 13 03 21](https://github.com/elastic/kibana/assets/1490444/91db2dec-6fe5-4a09-9a8e-b55be4ef927d) ### How to test it? * Clone and install https://github.com/elastic/security-documents-generator * Execute `npm start entity-store` on an empty kibana instance * Increase the created rule `Additional look-back time` and restart the rule (that will generate more alerts) * Open the alerts page (make sure your local storage is empty otherwise, you won't see the new column names) ### Know issues with the current implementation * The new columns might not be displayed to users after an upgrade * We couldn't rename `calculated_score_norm` and `calculated_score_norm` because they are not shown by default ### Context #### Known Alert columns issues: _The columns are stored on local storage when the alerts page loads_ * After users open the Alerts page once, they will always see the stored columns * We need to create a migration when adding or updating a default column. * The risk score columns are displayed for users that have the risk engine disabled. #### Risk fields friendly names limitations * We can only rename columns that are displayed by default. * If the user has loaded the page, he will only see the new column name if we write a migration to rename the columns inside local storage. This [issue](https://github.com/elastic/kibana/issues/176125) tracks the @elastic/response-ops team's planned improvements to column names and visibility. ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [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 --- .../alerts_table/default_config.test.tsx | 24 +++++- .../components/alerts_table/translations.ts | 28 +++++++ .../security_solution_detections/columns.ts | 28 ++++--- .../asset_criticality_badge.tsx | 2 +- .../asset_criticality_level.test.tsx | 35 +++++++++ .../renderers/asset_criticality_level.tsx | 60 ++++++++++++++ .../body/renderers/formatted_field.tsx | 17 ++++ .../containers/local_storage/index.tsx | 2 + .../migrates_risk_level_title.test.tsx | 78 +++++++++++++++++++ .../migrates_risk_level_title.tsx | 56 +++++++++++++ .../e2e/entity_analytics/enrichments.cy.ts | 8 +- 11 files changed, 317 insertions(+), 21 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.tsx diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx index 1e0c7021929c9..05de5e9725399 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx @@ -67,11 +67,27 @@ const platinumBaseColumns = [ initialWidth: 450, }, { columnHeaderType: 'not-filtered', id: 'host.name' }, - { columnHeaderType: 'not-filtered', id: 'host.risk.calculated_level' }, { columnHeaderType: 'not-filtered', id: 'user.name' }, - { columnHeaderType: 'not-filtered', id: 'user.risk.calculated_level' }, - { columnHeaderType: 'not-filtered', id: 'host.asset.criticality' }, - { columnHeaderType: 'not-filtered', id: 'user.asset.criticality' }, + { + columnHeaderType: 'not-filtered', + id: 'host.risk.calculated_level', + displayAsText: 'Host Risk Level', + }, + { + columnHeaderType: 'not-filtered', + id: 'user.risk.calculated_level', + displayAsText: 'User Risk Level', + }, + { + columnHeaderType: 'not-filtered', + id: 'host.asset.criticality', + displayAsText: 'Host Criticality', + }, + { + columnHeaderType: 'not-filtered', + id: 'user.asset.criticality', + displayAsText: 'User Criticality', + }, { columnHeaderType: 'not-filtered', id: 'process.name' }, { columnHeaderType: 'not-filtered', id: 'file.name' }, { columnHeaderType: 'not-filtered', id: 'source.ip' }, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts index ae0c05d2bdb05..4a7ea8e77cc92 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts @@ -137,6 +137,34 @@ export const ALERTS_HEADERS_NEW_TERMS_FIELDS = i18n.translate( } ); +export const ALERTS_HEADERS_HOST_RISK_LEVEL = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.hostRiskLevel', + { + defaultMessage: 'Host Risk Level', + } +); + +export const ALERTS_HEADERS_USER_RISK_LEVEL = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.userRiskLevel', + { + defaultMessage: 'User Risk Level', + } +); + +export const ALERTS_HEADERS_HOST_CRITICALITY = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.hostCriticality', + { + defaultMessage: 'Host Criticality', + } +); + +export const ALERTS_HEADERS_USER_CRITICALITY = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.userCriticality', + { + defaultMessage: 'User Criticality', + } +); + export const ACTION_INVESTIGATE_IN_TIMELINE = i18n.translate( 'xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle', { diff --git a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts index fc3f5afa897a2..6ca0a67244179 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts +++ b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts @@ -34,6 +34,18 @@ export const assigneesColumn: ColumnHeaderOptions = { initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH, }; +export const hostRiskLevelColumn: ColumnHeaderOptions = { + columnHeaderType: defaultColumnHeaderType, + id: ALERT_HOST_RISK_SCORE_CALCULATED_LEVEL, + displayAsText: i18n.ALERTS_HEADERS_HOST_RISK_LEVEL, +}; + +export const userRiskLevelColumn: ColumnHeaderOptions = { + columnHeaderType: defaultColumnHeaderType, + id: ALERT_USER_RISK_SCORE_CALCULATED_LEVEL, + displayAsText: i18n.ALERTS_HEADERS_USER_RISK_LEVEL, +}; + const getBaseColumns = ( license?: LicenseService ): Array< @@ -63,32 +75,24 @@ const getBaseColumns = ( columnHeaderType: defaultColumnHeaderType, id: 'host.name', }, - isPlatinumPlus - ? { - columnHeaderType: defaultColumnHeaderType, - id: ALERT_HOST_RISK_SCORE_CALCULATED_LEVEL, - } - : null, { columnHeaderType: defaultColumnHeaderType, id: 'user.name', }, - isPlatinumPlus - ? { - columnHeaderType: defaultColumnHeaderType, - id: ALERT_USER_RISK_SCORE_CALCULATED_LEVEL, - } - : null, + isPlatinumPlus ? hostRiskLevelColumn : null, + isPlatinumPlus ? userRiskLevelColumn : null, isPlatinumPlus ? { columnHeaderType: defaultColumnHeaderType, id: ALERT_HOST_CRITICALITY, + displayAsText: i18n.ALERTS_HEADERS_HOST_CRITICALITY, } : null, isPlatinumPlus ? { columnHeaderType: defaultColumnHeaderType, id: ALERT_USER_CRITICALITY, + displayAsText: i18n.ALERTS_HEADERS_USER_CRITICALITY, } : null, { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx index 003d693a0182e..2fa32b82b8767 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { CRITICALITY_LEVEL_TITLE, CRITICALITY_LEVEL_DESCRIPTION } from './translations'; import type { CriticalityLevel } from '../../../../common/entity_analytics/asset_criticality/types'; -const CRITICALITY_LEVEL_COLOR: Record = { +export const CRITICALITY_LEVEL_COLOR: Record = { very_important: '#E7664C', important: '#D6BF57', normal: '#54B399', diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.test.tsx new file mode 100644 index 0000000000000..2a52c4509492a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.test.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TestProviders } from '../../../../../common/mock'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { AssetCriticalityLevel } from './asset_criticality_level'; + +jest.mock('../../../../../common/components/draggables', () => ({ + DefaultDraggable: ({ children }: { children: React.ReactNode }) => <>{children}, +})); + +const defaultProps = { + contextId: 'testContext', + eventId: 'testEvent', + fieldName: 'testField', + fieldType: 'testType', + isAggregatable: true, + isDraggable: true, + value: 'low', +}; + +describe('AssetCriticalityLevel', () => { + it('renders', () => { + const { getByTestId } = render(, { + wrapper: TestProviders, + }); + + expect(getByTestId('AssetCriticalityLevel-score-badge')).toHaveTextContent('low'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.tsx new file mode 100644 index 0000000000000..ac3fa8d977b61 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/asset_criticality_level.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import { isString } from 'lodash/fp'; +import type { CriticalityLevel } from '../../../../../../common/entity_analytics/asset_criticality/types'; +import { CRITICALITY_LEVEL_COLOR } from '../../../../../entity_analytics/components/asset_criticality'; +import { DefaultDraggable } from '../../../../../common/components/draggables'; + +interface Props { + contextId: string; + eventId: string; + fieldName: string; + fieldType: string; + isAggregatable: boolean; + isDraggable: boolean; + value: string | number | undefined | null; +} + +const AssetCriticalityLevelComponent: React.FC = ({ + contextId, + eventId, + fieldName, + fieldType, + isAggregatable, + isDraggable, + value, +}) => { + const color = isString(value) ? CRITICALITY_LEVEL_COLOR[value as CriticalityLevel] : 'normal'; + + const badge = ( + + {value} + + ); + + return isDraggable ? ( + + {badge} + + ) : ( + badge + ); +}; + +export const AssetCriticalityLevel = React.memo(AssetCriticalityLevelComponent); +AssetCriticalityLevel.displayName = 'AssetCriticalityLevel'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx index 7062fc7afbb78..040e6335eb8a1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx @@ -13,6 +13,10 @@ import { isNumber, isEmpty } from 'lodash/fp'; import React from 'react'; import { css } from '@emotion/css'; +import { + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, +} from '../../../../../../common/field_maps/field_names'; import { SENTINEL_ONE_AGENT_ID_FIELD } from '../../../../../common/utils/sentinelone_alert_check'; import { SentinelOneAgentStatus } from '../../../../../detections/components/host_isolation/sentinel_one_agent_status'; import { EndpointAgentStatusById } from '../../../../../common/components/endpoint/endpoint_agent_status'; @@ -45,6 +49,7 @@ import { RenderRuleName, renderEventModule, renderUrl } from './formatted_field_ import { RuleStatus } from './rule_status'; import { HostName } from './host_name'; import { UserName } from './user_name'; +import { AssetCriticalityLevel } from './asset_criticality_level'; // simple black-list to prevent dragging and dropping fields such as message name const columnNamesNotDraggable = [MESSAGE_FIELD_NAME]; @@ -256,6 +261,18 @@ const FormattedFieldValueComponent: React.FC<{ iconSide={isButton ? 'right' : undefined} /> ); + } else if (fieldName === ALERT_HOST_CRITICALITY || fieldName === ALERT_USER_CRITICALITY) { + return ( + + ); } else if (fieldName === AGENT_STATUS_FIELD_NAME) { return ( { const tableModel = allDataTables[tableId]; diff --git a/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.test.tsx b/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.test.tsx new file mode 100644 index 0000000000000..a43e0a860e7ac --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.test.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + LOCAL_STORAGE_MIGRATION_KEY, + migrateEntityRiskLevelColumnTitle, +} from './migrates_risk_level_title'; +import type { DataTableState } from '@kbn/securitysolution-data-table'; +import { + hostRiskLevelColumn, + userRiskLevelColumn, +} from '../../../detections/configurations/security_solution_detections/columns'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; +import { localStorageMock } from '../../../common/mock/mock_local_storage'; +import { LOCAL_STORAGE_TABLE_KEY } from '.'; + +const getColumnsBeforeMigration = () => [ + { ...userRiskLevelColumn, displayAsText: undefined }, + { ...hostRiskLevelColumn, displayAsText: undefined }, +]; + +let storage: Storage; + +describe('migrateEntityRiskLevelColumnTitle', () => { + beforeEach(() => { + storage = new Storage(localStorageMock()); + }); + + it('does NOT migrate `columns` when `columns` is not an array', () => { + const dataTableState = { + 'alerts-page': {}, + } as unknown as DataTableState['dataTable']['tableById']; + + migrateEntityRiskLevelColumnTitle(storage, dataTableState); + + expect(dataTableState['alerts-page'].columns).toStrictEqual(undefined); + }); + + it('does not migrates columns if if it has already run once', () => { + storage.set(LOCAL_STORAGE_MIGRATION_KEY, true); + const dataTableState = { + 'alerts-page': { + columns: getColumnsBeforeMigration(), + }, + } as unknown as DataTableState['dataTable']['tableById']; + + migrateEntityRiskLevelColumnTitle(storage, dataTableState); + + expect(dataTableState['alerts-page'].columns).toStrictEqual(getColumnsBeforeMigration()); + }); + + it('migrates columns saved to localStorage', () => { + const dataTableState = { + 'alerts-page': { + columns: getColumnsBeforeMigration(), + }, + } as unknown as DataTableState['dataTable']['tableById']; + + migrateEntityRiskLevelColumnTitle(storage, dataTableState); + + // assert that it mutates the table model + expect(dataTableState['alerts-page'].columns).toStrictEqual([ + userRiskLevelColumn, + hostRiskLevelColumn, + ]); + // assert that it updates the migration flag on storage + expect(storage.get(LOCAL_STORAGE_MIGRATION_KEY)).toEqual(true); + // assert that it updates the table inside local storage + expect(storage.get(LOCAL_STORAGE_TABLE_KEY)['alerts-page'].columns).toStrictEqual([ + userRiskLevelColumn, + hostRiskLevelColumn, + ]); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.tsx b/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.tsx new file mode 100644 index 0000000000000..8cbae007b3a1f --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/containers/local_storage/migrates_risk_level_title.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 type { DataTableState, TableId } from '@kbn/securitysolution-data-table'; +import { tableEntity, TableEntityType } from '@kbn/securitysolution-data-table'; +import type { Storage } from '@kbn/kibana-utils-plugin/public'; +import { LOCAL_STORAGE_TABLE_KEY } from '.'; +import { + hostRiskLevelColumn, + userRiskLevelColumn, +} from '../../../detections/configurations/security_solution_detections/columns'; + +export const LOCAL_STORAGE_MIGRATION_KEY = + 'securitySolution.dataTable.entityRiskLevelColumnTitleMigration'; + +export const migrateEntityRiskLevelColumnTitle = ( + storage: Storage, + dataTableState: DataTableState['dataTable']['tableById'] +) => { + // Set/Get a flag to prevent migration from running more than once + const hasAlreadyMigrated: boolean = storage.get(LOCAL_STORAGE_MIGRATION_KEY); + if (hasAlreadyMigrated) { + return; + } + storage.set(LOCAL_STORAGE_MIGRATION_KEY, true); + + let updatedTableModel = false; + + for (const [tableId, tableModel] of Object.entries(dataTableState)) { + // Only updates the title for alerts tables + if (tableEntity[tableId as TableId] === TableEntityType.alert) { + // In order to show correct column title after user upgrades to 8.13 we need update the stored table model with the new title. + const columns = tableModel.columns; + if (Array.isArray(columns)) { + columns.forEach((col) => { + if (col.id === userRiskLevelColumn.id) { + col.displayAsText = userRiskLevelColumn.displayAsText; + updatedTableModel = true; + } + + if (col.id === hostRiskLevelColumn.id) { + col.displayAsText = hostRiskLevelColumn.displayAsText; + updatedTableModel = true; + } + }); + } + } + } + if (updatedTableModel) { + storage.set(LOCAL_STORAGE_TABLE_KEY, dataTableState); + } +}; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts index acb38b4dcefff..a080c4494833f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts @@ -63,8 +63,8 @@ describe('Enrichment', { tags: ['@ess', '@serverless'] }, () => { }); it('Should has enrichment fields from legacy risk', function () { - cy.get(HOST_RISK_HEADER_COLUMN).contains('host.risk.calculated_level'); - cy.get(USER_RISK_HEADER_COLUMN).contains('user.risk.calculated_level'); + cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); + cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); cy.get(HOST_RISK_COLUMN).contains('Low'); scrollAlertTableColumnIntoView(USER_RISK_COLUMN); @@ -103,8 +103,8 @@ describe('Enrichment', { tags: ['@ess', '@serverless'] }, () => { }); it('Should has enrichment fields from legacy risk', function () { - cy.get(HOST_RISK_HEADER_COLUMN).contains('host.risk.calculated_level'); - cy.get(USER_RISK_HEADER_COLUMN).contains('user.risk.calculated_level'); + cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); + cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); cy.get(HOST_RISK_COLUMN).contains('Critical'); scrollAlertTableColumnIntoView(USER_RISK_COLUMN); From bc19b6b13c2c0c8d461586a17de7b923d319df18 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Fri, 9 Feb 2024 10:31:57 +0100 Subject: [PATCH 064/104] [Ops] Increase step timeout for storybook build (#176501) ## Summary Several instances of post-merge build failed on the storybook build and upload, as it just finished briefly within limit, the step altogether timed out. This PR increases the timeout by 20m (a generous increment) while taking note on ideally speeding up storybook builds: https://github.com/elastic/kibana/issues/176500 --- .buildkite/pipelines/on_merge.yml | 2 +- .buildkite/pipelines/pull_request/storybooks.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml index 2841dce49bb26..fcf4a82c0801c 100644 --- a/.buildkite/pipelines/on_merge.yml +++ b/.buildkite/pipelines/on_merge.yml @@ -372,7 +372,7 @@ steps: agents: queue: n2-8-spot key: storybooks - timeout_in_minutes: 60 + timeout_in_minutes: 80 retry: automatic: - exit_status: '-1' diff --git a/.buildkite/pipelines/pull_request/storybooks.yml b/.buildkite/pipelines/pull_request/storybooks.yml index 81d13b628e049..8f76879231de2 100644 --- a/.buildkite/pipelines/pull_request/storybooks.yml +++ b/.buildkite/pipelines/pull_request/storybooks.yml @@ -4,4 +4,4 @@ steps: agents: queue: n2-8-spot key: storybooks - timeout_in_minutes: 60 + timeout_in_minutes: 80 From 240e5ef10c6f5763724510b727ce07c82fe15498 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:39:57 +0100 Subject: [PATCH 065/104] [Fleet] Make datastream rollover lazy (#174790) (#176565) ## Summary Add back changes in https://github.com/elastic/kibana/pull/174790 after https://github.com/elastic/elasticsearch/issues/104732 is fixed Resolve https://github.com/elastic/kibana/issues/174480 Co-authored-by: Nicolas Chaulet --- .../elasticsearch/template/template.test.ts | 9 +- .../epm/elasticsearch/template/template.ts | 8 +- .../apis/epm/data_stream.ts | 96 +++++++++++-------- .../apis/epm/install_hidden_datastreams.ts | 80 +++++++++------- 4 files changed, 113 insertions(+), 80 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts index f680a0bf004a6..58bcfcca386cf 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts @@ -1673,7 +1673,14 @@ describe('EPM template', () => { }, ]); - expect(esClient.indices.rollover).toHaveBeenCalled(); + expect(esClient.transport.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/test.prefix1-default/_rollover', + querystring: { + lazy: true, + }, + }) + ); }); it('should skip rollover on expected error when flag is on', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index da2b801548e18..01b1792dc5e79 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -946,8 +946,12 @@ const getDataStreams = async ( const rolloverDataStream = (dataStreamName: string, esClient: ElasticsearchClient) => { try { // Do no wrap rollovers in retryTransientEsErrors since it is not idempotent - return esClient.indices.rollover({ - alias: dataStreamName, + return esClient.transport.request({ + method: 'POST', + path: `/${dataStreamName}/_rollover`, + querystring: { + lazy: true, + }, }); } catch (error) { throw new PackageESError( diff --git a/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts b/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts index 06a67a13e425c..a257ff97933d9 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/data_stream.ts @@ -41,43 +41,46 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); + const writeMetricsDoc = (namespace: string) => + es.transport.request( + { + method: 'POST', + path: `/${metricsTemplateName}-${namespace}/_doc?refresh=true`, + body: { + '@timestamp': new Date().toISOString(), + logs_test_name: 'test', + data_stream: { + dataset: `${pkgName}.test_metrics`, + namespace, + type: 'metrics', + }, + }, + }, + { meta: true } + ); + + const writeLogsDoc = (namespace: string) => + es.transport.request( + { + method: 'POST', + path: `/${logsTemplateName}-${namespace}/_doc?refresh=true`, + body: { + '@timestamp': new Date().toISOString(), + logs_test_name: 'test', + data_stream: { + dataset: `${pkgName}.test_logs`, + namespace, + type: 'logs', + }, + }, + }, + { meta: true } + ); beforeEach(async () => { await installPackage(pkgName, pkgVersion); await Promise.all( namespaces.map(async (namespace) => { - const createLogsRequest = es.transport.request( - { - method: 'POST', - path: `/${logsTemplateName}-${namespace}/_doc`, - body: { - '@timestamp': '2015-01-01', - logs_test_name: 'test', - data_stream: { - dataset: `${pkgName}.test_logs`, - namespace, - type: 'logs', - }, - }, - }, - { meta: true } - ); - const createMetricsRequest = es.transport.request( - { - method: 'POST', - path: `/${metricsTemplateName}-${namespace}/_doc`, - body: { - '@timestamp': '2015-01-01', - logs_test_name: 'test', - data_stream: { - dataset: `${pkgName}.test_metrics`, - namespace, - type: 'metrics', - }, - }, - }, - { meta: true } - ); - return Promise.all([createLogsRequest, createMetricsRequest]); + return Promise.all([writeLogsDoc(namespace), writeMetricsDoc(namespace)]); }) ); }); @@ -141,7 +144,11 @@ export default function (providerContext: FtrProviderContext) { it('after update, it should have rolled over logs datastream because mappings are not compatible and not metrics', async function () { await installPackage(pkgName, pkgUpdateVersion); + await asyncForEach(namespaces, async (namespace) => { + // write doc as rollover is lazy + await writeLogsDoc(namespace); + await writeMetricsDoc(namespace); const resLogsDatastream = await es.transport.request( { method: 'GET', @@ -266,6 +273,8 @@ export default function (providerContext: FtrProviderContext) { }) .expect(200); + // Write a doc to trigger lazy rollover + await writeLogsDoc('default'); // Datastream should have been rolled over expect(await getLogsDefaultBackingIndicesLength()).to.be(2); }); @@ -303,26 +312,29 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); - beforeEach(async () => { - await installPackage(pkgName, pkgVersion); - - // Create a sample document so the data stream is created - await es.transport.request( + const writeMetricDoc = (body: any = {}) => + es.transport.request( { method: 'POST', - path: `/${metricsTemplateName}-${namespace}/_doc`, + path: `/${metricsTemplateName}-${namespace}/_doc?refresh=true`, body: { - '@timestamp': '2015-01-01', + '@timestamp': new Date().toISOString(), logs_test_name: 'test', data_stream: { dataset: `${pkgName}.test_logs`, namespace, type: 'logs', }, + ...body, }, }, { meta: true } ); + beforeEach(async () => { + await installPackage(pkgName, pkgVersion); + + // Create a sample document so the data stream is created + await writeMetricDoc(); }); afterEach(async () => { @@ -340,6 +352,10 @@ export default function (providerContext: FtrProviderContext) { it('rolls over data stream when index_mode: time_series is set in the updated package version', async () => { await installPackage(pkgName, pkgUpdateVersion); + // Write a doc so lazy rollover can happen + await writeMetricDoc({ + some_field: 'test', + }); const resMetricsDatastream = await es.transport.request( { method: 'GET', diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_hidden_datastreams.ts b/x-pack/test/fleet_api_integration/apis/epm/install_hidden_datastreams.ts index 2fe976352944a..2ec6fb92000e3 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_hidden_datastreams.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_hidden_datastreams.ts @@ -34,46 +34,50 @@ export default function (providerContext: FtrProviderContext) { .send({ force: true }) .expect(200); - await es.index({ - index: 'metrics-apm.service_summary.10m-default', - document: { - '@timestamp': '2023-05-30T07:50:00.000Z', - agent: { - name: 'go', - }, - data_stream: { - dataset: 'apm.service_summary.10m', - namespace: 'default', - type: 'metrics', - }, - ecs: { - version: '8.6.0-dev', - }, - event: { - agent_id_status: 'missing', - ingested: '2023-05-30T07:57:12Z', - }, - metricset: { - interval: '10m', - name: 'service_summary', - }, - observer: { - hostname: '047e282994fb', - type: 'apm-server', - version: '8.7.0', - }, - processor: { - event: 'metric', - name: 'metric', - }, - service: { - language: { + const writeDoc = () => + es.index({ + refresh: true, + index: 'metrics-apm.service_summary.10m-default', + document: { + '@timestamp': '2023-05-30T07:50:00.000Z', + agent: { name: 'go', }, - name: '___main_elastic_cloud_87_ilm_fix', + data_stream: { + dataset: 'apm.service_summary.10m', + namespace: 'default', + type: 'metrics', + }, + ecs: { + version: '8.6.0-dev', + }, + event: { + agent_id_status: 'missing', + ingested: '2023-05-30T07:57:12Z', + }, + metricset: { + interval: '10m', + name: 'service_summary', + }, + observer: { + hostname: '047e282994fb', + type: 'apm-server', + version: '8.7.0', + }, + processor: { + event: 'metric', + name: 'metric', + }, + service: { + language: { + name: 'go', + }, + name: '___main_elastic_cloud_87_ilm_fix', + }, }, - }, - }); + }); + + await writeDoc(); await supertest .post(`/api/fleet/epm/packages/apm/8.8.0`) @@ -81,6 +85,8 @@ export default function (providerContext: FtrProviderContext) { .send({ force: true }) .expect(200); + // Rollover are lazy need to write a new doc + await writeDoc(); const ds = await es.indices.get({ index: 'metrics-apm.service_summary*', expand_wildcards: ['open', 'hidden'], From cd1f2b02bb81a94af5fea0e63b79f36f249a8e16 Mon Sep 17 00:00:00 2001 From: jennypavlova Date: Fri, 9 Feb 2024 11:06:14 +0100 Subject: [PATCH 066/104] [ObsUx][Infra] Add collapsible sections in the overview tab (#175716) Closes #175989 ## Summary This PR is a follow-up to https://github.com/elastic/kibana/issues/175558. It adds the active alerts count next to the alert section title (this will happen after the alerts widget is loaded) following the rules: Default behaviour No alerts at all ==> Collapse and say 'No active alerts' No active alerts ==> Collapse and say 'No active alerts' Active alerts ==> Expand fully Collapsed No alerts at all ==> Say 'No active alerts' No active alerts ==> Say 'No active alerts' Active alerts ==> say "X active alerts" It adds a change in the `AlertSummaryWidget` to make it possible to get the alerts count after the widget is loaded using a new prop. This PR also changes the alerts tab active alert count badge color on the hosts view to keep it consistent: | Before | After | | ------ | ------ | | image | image | ## Testing - Open hosts view and select a host with active alerts (flyout or full page) - The alerts section should be expanded showing the alerts widget imagefd1a21035a5f) - Collapse the alerts section by clicking on the title or the button: image - Open hosts view and select a host without active alerts (flyout or full page) - The alerts section should be collapsed showing the message 'No active alerts' ![Image](https://github.com/elastic/obs-infraobs-team/assets/14139027/7077d3b3-c020-4be5-a3da-b46dda0d3ae0) https://github.com/elastic/kibana/assets/14139027/4058ed69-95f5-4b4c-8925-6680ac3791c1 --- .../asset_details/tabs/overview/alerts.tsx | 30 ++++++++++--- .../tabs/overview/alerts_closed_content.tsx | 44 ++++++++++++++++++ .../overview/section/collapsible_section.tsx | 11 ++++- .../infra/public/hooks/use_alerts_count.ts | 2 +- .../components/tabs/alerts_tab_badge.tsx | 8 ++-- .../alert_summary_widget.tsx | 4 +- .../sections/alert_summary_widget/types.ts | 7 ++- .../functional/apps/infra/node_details.ts | 45 +++++++++++++++++++ .../functional/page_objects/asset_details.ts | 18 ++++++++ 9 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts_closed_content.tsx diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx index 1fc8cc6614a75..4b7a1907e206a 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx @@ -4,9 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, type EuiAccordionProps } from '@elastic/eui'; import { useSummaryTimeRange } from '@kbn/observability-plugin/public'; import type { TimeRange } from '@kbn/es-query'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; @@ -24,6 +24,8 @@ import { ALERT_STATUS_ALL } from '../../../../common/alerts/constants'; import { AlertsSectionTitle } from '../../components/section_titles'; import { useAssetDetailsRenderPropsContext } from '../../hooks/use_asset_details_render_props'; import { CollapsibleSection } from './section/collapsible_section'; +import { AlertsClosedContent } from './alerts_closed_content'; +import { type AlertsCount } from '../../../../hooks/use_alerts_count'; export const AlertsSummaryContent = ({ assetName, @@ -37,6 +39,9 @@ export const AlertsSummaryContent = ({ const { featureFlags } = usePluginConfig(); const [isAlertFlyoutVisible, { toggle: toggleAlertFlyout }] = useBoolean(false); const { overrides } = useAssetDetailsRenderPropsContext(); + const [collapsibleStatus, setCollapsibleStatus] = + useState('open'); + const [activeAlertsCount, setActiveAlertsCount] = useState(undefined); const alertsEsQueryByStatus = useMemo( () => @@ -48,6 +53,14 @@ export const AlertsSummaryContent = ({ [assetName, dateRange] ); + const onLoaded = (alertsCount?: AlertsCount) => { + const { activeAlertCount = 0 } = alertsCount ?? {}; + const hasActiveAlerts = activeAlertCount > 0; + + setCollapsibleStatus(hasActiveAlerts ? 'open' : 'closed'); + setActiveAlertsCount(alertsCount?.activeAlertCount); + }; + return ( <> } + initialTriggerValue={collapsibleStatus} extraAction={ {featureFlags.inventoryThresholdAlertRuleEnabled && ( @@ -72,9 +87,12 @@ export const AlertsSummaryContent = ({ } > - + - {featureFlags.inventoryThresholdAlertRuleEnabled && ( void; } const MemoAlertSummaryWidget = React.memo( - ({ alertsQuery, dateRange }: MemoAlertSummaryWidgetProps) => { + ({ alertsQuery, dateRange, onLoaded }: MemoAlertSummaryWidgetProps) => { const { services } = useKibanaContextForPlugin(); const summaryTimeRange = useSummaryTimeRange(dateRange); @@ -112,6 +131,7 @@ const MemoAlertSummaryWidget = React.memo( featureIds={infraAlertFeatureIds} filter={alertsQuery} timeRange={summaryTimeRange} + onLoaded={onLoaded} fullSize hideChart /> diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts_closed_content.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts_closed_content.tsx new file mode 100644 index 0000000000000..a08a0313230ee --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts_closed_content.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 { i18n } from '@kbn/i18n'; +import { EuiBadge, EuiToolTip } from '@elastic/eui'; + +export const AlertsClosedContent = ({ activeAlertCount }: { activeAlertCount?: number }) => { + const shouldRenderAlertsClosedContent = typeof activeAlertCount === 'number'; + + if (!shouldRenderAlertsClosedContent) { + return null; + } + + if (activeAlertCount > 0) { + return ( + + + {activeAlertCount} + + + ); + } + + return ( + + {i18n.translate('xpack.infra.assetDetails.noActiveAlertsContentClosedSection', { + defaultMessage: 'No active alerts', + })} + + ); +}; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/section/collapsible_section.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/section/collapsible_section.tsx index ec31851d89a6d..da0b993199ee1 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/section/collapsible_section.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/section/collapsible_section.tsx @@ -5,6 +5,8 @@ * 2.0. */ +import React, { useEffect, useState } from 'react'; + import { EuiAccordion, EuiFlexGroup, @@ -12,7 +14,6 @@ import { useGeneratedHtmlId, type EuiAccordionProps, } from '@elastic/eui'; -import React, { useState } from 'react'; export const CollapsibleSection = ({ title, @@ -22,6 +23,7 @@ export const CollapsibleSection = ({ collapsible, ['data-test-subj']: dataTestSubj, id, + initialTriggerValue, }: { title: React.FunctionComponent; closedSectionContent?: React.ReactNode; @@ -31,13 +33,18 @@ export const CollapsibleSection = ({ collapsible: boolean; ['data-test-subj']: string; id: string; + initialTriggerValue?: EuiAccordionProps['forceState']; }) => { const [trigger, setTrigger] = useState('open'); + useEffect(() => { + setTrigger(initialTriggerValue ?? 'open'); + }, [initialTriggerValue]); + const Title = title; const ButtonContent = () => closedSectionContent && trigger === 'closed' ? ( - + </EuiFlexItem> diff --git a/x-pack/plugins/infra/public/hooks/use_alerts_count.ts b/x-pack/plugins/infra/public/hooks/use_alerts_count.ts index 7d05a275d6eae..5c602d09b7d23 100644 --- a/x-pack/plugins/infra/public/hooks/use_alerts_count.ts +++ b/x-pack/plugins/infra/public/hooks/use_alerts_count.ts @@ -28,7 +28,7 @@ interface FetchAlertsCountParams { signal: AbortSignal; } -interface AlertsCount { +export interface AlertsCount { activeAlertCount: number; recoveredAlertCount: number; } diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/alerts_tab_badge.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/alerts_tab_badge.tsx index 15c4e568ad8ed..c3f778299ab69 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/alerts_tab_badge.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/alerts_tab_badge.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React from 'react'; -import { EuiIcon, EuiLoadingSpinner, EuiNotificationBadge, EuiToolTip } from '@elastic/eui'; +import { EuiIcon, EuiLoadingSpinner, EuiBadge, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useAlertsCount } from '../../../../../hooks/use_alerts_count'; import { infraAlertFeatureIds } from './config'; @@ -40,12 +40,12 @@ export const AlertsTabBadge = () => { typeof alertsCount?.activeAlertCount === 'number' && alertsCount.activeAlertCount > 0; return shouldRenderBadge ? ( - <EuiNotificationBadge + <EuiBadge + color="danger" className="eui-alignCenter" - size="m" data-test-subj="hostsView-tabs-alerts-count" > {alertsCount?.activeAlertCount} - </EuiNotificationBadge> + </EuiBadge> ) : null; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.tsx index 2031c9a1f3fe2..2619ef2b25258 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.tsx @@ -37,9 +37,9 @@ export const AlertSummaryWidget = ({ useEffect(() => { if (!isLoading && onLoaded) { - onLoaded(); + onLoaded({ activeAlertCount, recoveredAlertCount }); } - }, [isLoading, onLoaded]); + }, [activeAlertCount, isLoading, onLoaded, recoveredAlertCount]); if (isLoading) return <AlertSummaryWidgetLoader fullSize={fullSize} isLoadingWithoutChart={hideChart} />; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts index 48a49acf5ad7c..1bb02adff0653 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts @@ -30,6 +30,11 @@ export interface ChartProps { onBrushEnd?: BrushEndListener; } +interface AlertsCount { + activeAlertCount: number; + recoveredAlertCount: number; +} + export interface AlertSummaryWidgetProps { featureIds?: ValidFeatureId[]; filter?: estypes.QueryDslQueryContainer; @@ -38,5 +43,5 @@ export interface AlertSummaryWidgetProps { timeRange: AlertSummaryTimeRange; chartProps: ChartProps; hideChart?: boolean; - onLoaded?: () => void; + onLoaded?: (alertsCount?: AlertsCount) => void; } diff --git a/x-pack/test/functional/apps/infra/node_details.ts b/x-pack/test/functional/apps/infra/node_details.ts index 172ac410eb427..42147652f34a5 100644 --- a/x-pack/test/functional/apps/infra/node_details.ts +++ b/x-pack/test/functional/apps/infra/node_details.ts @@ -204,6 +204,15 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.assetDetails.overviewAlertsTitleExists(); }); + it('should show / hide alerts section with no alerts and show / hide closed section content', async () => { + await pageObjects.assetDetails.alertsSectionCollapsibleExist(); + // Collapsed by default + await pageObjects.assetDetails.alertsSectionClosedContentNoAlertsExist(); + // Expand + await pageObjects.assetDetails.alertsSectionCollapsibleClick(); + await pageObjects.assetDetails.alertsSectionClosedContentNoAlertsMissing(); + }); + it('shows the CPU Profiling prompt if UI setting for Profiling integration is enabled', async () => { await setInfrastructureProfilingIntegrationUiSetting(true); await pageObjects.assetDetails.cpuProfilingPromptExists(); @@ -213,6 +222,42 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await setInfrastructureProfilingIntegrationUiSetting(false); await pageObjects.assetDetails.cpuProfilingPromptMissing(); }); + + describe('Alerts Section with alerts', () => { + before(async () => { + await navigateToNodeDetails('demo-stack-apache-01', 'demo-stack-apache-01'); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await pageObjects.timePicker.setAbsoluteRange( + START_HOST_ALERTS_DATE.format(DATE_PICKER_FORMAT), + END_HOST_ALERTS_DATE.format(DATE_PICKER_FORMAT) + ); + + await pageObjects.assetDetails.clickOverviewTab(); + }); + + after(async () => { + await navigateToNodeDetails('Jennys-MBP.fritz.box', 'Jennys-MBP.fritz.box'); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await pageObjects.timePicker.setAbsoluteRange( + START_HOST_PROCESSES_DATE.format(DATE_PICKER_FORMAT), + END_HOST_PROCESSES_DATE.format(DATE_PICKER_FORMAT) + ); + }); + + it('should show / hide alerts section with active alerts and show / hide closed section content', async () => { + await pageObjects.assetDetails.alertsSectionCollapsibleExist(); + // Expanded by default + await pageObjects.assetDetails.alertsSectionClosedContentMissing(); + // Collapse + await pageObjects.assetDetails.alertsSectionCollapsibleClick(); + await pageObjects.assetDetails.alertsSectionClosedContentExist(); + // Expand + await pageObjects.assetDetails.alertsSectionCollapsibleClick(); + await pageObjects.assetDetails.alertsSectionClosedContentMissing(); + }); + }); }); describe('Metadata Tab', () => { diff --git a/x-pack/test/functional/page_objects/asset_details.ts b/x-pack/test/functional/page_objects/asset_details.ts index 5e1ea574f8a81..cd34d9c2ca10b 100644 --- a/x-pack/test/functional/page_objects/asset_details.ts +++ b/x-pack/test/functional/page_objects/asset_details.ts @@ -89,6 +89,24 @@ export function AssetDetailsProvider({ getService }: FtrProviderContext) { return await testSubjects.existOrFail('infraAssetDetailsMetricsCollapsible'); }, + async alertsSectionCollapsibleClick() { + return await testSubjects.click('infraAssetDetailsAlertsCollapsible'); + }, + + async alertsSectionClosedContentExist() { + return await testSubjects.existOrFail('infraAssetDetailsAlertsClosedContentWithAlerts'); + }, + async alertsSectionClosedContentMissing() { + return await testSubjects.missingOrFail('infraAssetDetailsAlertsClosedContentWithAlerts'); + }, + + async alertsSectionClosedContentNoAlertsExist() { + return await testSubjects.existOrFail('infraAssetDetailsAlertsClosedContentNoAlerts'); + }, + async alertsSectionClosedContentNoAlertsMissing() { + return await testSubjects.missingOrFail('infraAssetDetailsAlertsClosedContentNoAlerts'); + }, + // Metadata async clickMetadataTab() { return testSubjects.click('infraAssetDetailsMetadataTab'); From d0fbec8e49019631f07430ef644f64b3e9513a77 Mon Sep 17 00:00:00 2001 From: James Gowdy <jgowdy@elastic.co> Date: Fri, 9 Feb 2024 10:42:58 +0000 Subject: [PATCH 067/104] [ML] Adding delay to deletion model to avoid flickering (#176424) Fixes https://github.com/elastic/kibana/issues/173790 We now wait 1 second before showing the model. This should hopefully reduce the chance of briefly seeing the initial `Checking to see...` modal. https://github.com/elastic/kibana/assets/22172091/0d86bdfd-3e31-4b67-af6c-48b2d7681a00 --- .../delete_space_aware_item_check_modal.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx b/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx index d436a52f7ccb3..22500f936e705 100644 --- a/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx +++ b/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx @@ -21,6 +21,7 @@ import { EuiText, EuiSpacer, } from '@elastic/eui'; +import useDebounce from 'react-use/lib/useDebounce'; import type { CanDeleteMLSpaceAwareItemsResponse, MlSavedObjectType, @@ -246,12 +247,16 @@ export const DeleteSpaceAwareItemCheckModal: FC<Props> = ({ const [itemCheckRespSummary, setItemCheckRespSummary] = useState< CanDeleteMLSpaceAwareItemsSummary | undefined >(); + const [showModal, setShowModal] = useState<boolean>(false); const { savedObjects: { canDeleteMLSpaceAwareItems, removeItemFromCurrentSpace }, } = useMlApiContext(); const { displayErrorToast, displaySuccessToast } = useToastNotificationService(); + // delay showing the modal to avoid flickering + useDebounce(() => setShowModal(true), 1000); + useEffect(() => { setIsLoading(true); // Do the spaces check and set the content for the modal and buttons depending on results @@ -321,6 +326,10 @@ export const DeleteSpaceAwareItemCheckModal: FC<Props> = ({ } }; + if (showModal === false) { + return null; + } + return ( <EuiModal onClose={onCloseCallback} data-test-subj="mlDeleteSpaceAwareItemCheckModalOverlay"> <> From 3e0d73837519167473a43841ae98a68fe7850a49 Mon Sep 17 00:00:00 2001 From: Navarone Feekery <13634519+navarone-feekery@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:59:19 +0100 Subject: [PATCH 068/104] [Search] Enable API key management for Native Connectors (#176327) ### Changes - Show the API key configuration section in Native Connector configuration pages - Allow `generateApiKey` to accept params for native connectors - Create/update secret with encoded API key as appropriate - Unit tests --- packages/kbn-search-connectors/lib/index.ts | 1 + .../lib/update_connector_secret.test.ts | 42 ++++ .../lib/update_connector_secret.ts | 24 +++ ...nerate_connector_api_key_api_logic.test.ts | 30 ++- .../generate_connector_api_key_api_logic.ts | 18 +- .../connector/api_key_configuration.tsx | 47 +++-- .../connector/connector_configuration.tsx | 7 +- .../native_connector_configuration.tsx | 23 ++ .../lib/connectors/add_connector.test.ts | 24 +-- .../server/lib/connectors/add_connector.ts | 11 +- .../lib/indices/generate_api_key.test.ts | 199 +++++++++++++++++- .../server/lib/indices/generate_api_key.ts | 42 +++- .../routes/enterprise_search/indices.ts | 8 +- 13 files changed, 409 insertions(+), 67 deletions(-) create mode 100644 packages/kbn-search-connectors/lib/update_connector_secret.test.ts create mode 100644 packages/kbn-search-connectors/lib/update_connector_secret.ts diff --git a/packages/kbn-search-connectors/lib/index.ts b/packages/kbn-search-connectors/lib/index.ts index e0a1caea66422..e7269a0620b62 100644 --- a/packages/kbn-search-connectors/lib/index.ts +++ b/packages/kbn-search-connectors/lib/index.ts @@ -23,5 +23,6 @@ export * from './update_connector_configuration'; export * from './update_connector_index_name'; export * from './update_connector_name_and_description'; export * from './update_connector_scheduling'; +export * from './update_connector_secret'; export * from './update_connector_service_type'; export * from './update_connector_status'; diff --git a/packages/kbn-search-connectors/lib/update_connector_secret.test.ts b/packages/kbn-search-connectors/lib/update_connector_secret.test.ts new file mode 100644 index 0000000000000..80eb98a37babd --- /dev/null +++ b/packages/kbn-search-connectors/lib/update_connector_secret.test.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; + +import { updateConnectorSecret } from './update_connector_secret'; + +describe('updateConnectorSecret lib function', () => { + const mockClient = { + transport: { + request: jest.fn(), + }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + jest.useFakeTimers(); + }); + + it('should update a connector secret', async () => { + mockClient.transport.request.mockImplementation(() => ({ + result: 'created', + })); + + await expect( + updateConnectorSecret(mockClient as unknown as ElasticsearchClient, 'my-secret', 'secret-id') + ).resolves.toEqual({ result: 'created' }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/_connector/_secret/secret-id', + body: { + value: 'my-secret', + }, + }); + jest.useRealTimers(); + }); +}); diff --git a/packages/kbn-search-connectors/lib/update_connector_secret.ts b/packages/kbn-search-connectors/lib/update_connector_secret.ts new file mode 100644 index 0000000000000..516818b7e9b8d --- /dev/null +++ b/packages/kbn-search-connectors/lib/update_connector_secret.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { ConnectorsAPIUpdateResponse } from '../types/connectors_api'; + +export const updateConnectorSecret = async ( + client: ElasticsearchClient, + value: string, + secretId: string +) => { + return await client.transport.request<ConnectorsAPIUpdateResponse>({ + method: 'PUT', + path: `/_connector/_secret/${secretId}`, + body: { + value, + }, + }); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.test.ts index 524bc70e9b279..55161f5912cfe 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.test.ts @@ -11,19 +11,43 @@ import { nextTick } from '@kbn/test-jest-helpers'; import { generateApiKey } from './generate_connector_api_key_api_logic'; +jest.mock('@kbn/search-connectors', () => ({ + createConnectorSecret: jest.fn(), + updateConnectorSecret: jest.fn(), +})); + describe('generateConnectorApiKeyApiLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('generateApiKey', () => { + describe('generateApiKey for connector clients', () => { + it('calls correct api', async () => { + const promise = Promise.resolve('result'); + http.post.mockReturnValue(promise); + const result = generateApiKey({ indexName: 'indexName', isNative: false, secretId: null }); + await nextTick(); + expect(http.post).toHaveBeenCalledWith( + '/internal/enterprise_search/indices/indexName/api_key', + { + body: '{"is_native":false,"secret_id":null}', + } + ); + await expect(result).resolves.toEqual('result'); + }); + }); + + describe('generateApiKey for native connectors', () => { it('calls correct api', async () => { const promise = Promise.resolve('result'); http.post.mockReturnValue(promise); - const result = generateApiKey({ indexName: 'indexName' }); + const result = generateApiKey({ indexName: 'indexName', isNative: true, secretId: '1234' }); await nextTick(); expect(http.post).toHaveBeenCalledWith( - '/internal/enterprise_search/indices/indexName/api_key' + '/internal/enterprise_search/indices/indexName/api_key', + { + body: '{"is_native":true,"secret_id":"1234"}', + } ); await expect(result).resolves.toEqual('result'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.ts index ace963d9208be..ebca9c99add0d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_api_key_api_logic.ts @@ -15,9 +15,23 @@ export interface ApiKey { name: string; } -export const generateApiKey = async ({ indexName }: { indexName: string }) => { +export const generateApiKey = async ({ + indexName, + isNative, + secretId, +}: { + indexName: string; + isNative: boolean; + secretId: string | null; +}) => { const route = `/internal/enterprise_search/indices/${indexName}/api_key`; - return await HttpLogic.values.http.post<ApiKey>(route); + const params = { + is_native: isNative, + secret_id: secretId, + }; + return await HttpLogic.values.http.post<ApiKey>(route, { + body: JSON.stringify(params), + }); }; export const GenerateConnectorApiKeyApiLogic = createApiLogic( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx index fdc36863f4925..b2233bb4c9ee1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx @@ -61,10 +61,12 @@ const ConfirmModal: React.FC<{ </EuiConfirmModal> ); -export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = ({ - hasApiKey, - indexName, -}) => { +export const ApiKeyConfig: React.FC<{ + hasApiKey: boolean; + indexName: string; + isNative: boolean; + secretId: string | null; +}> = ({ hasApiKey, indexName, isNative, secretId }) => { const { makeRequest, apiReset } = useActions(GenerateConnectorApiKeyApiLogic); const { data, status } = useValues(GenerateConnectorApiKeyApiLogic); useEffect(() => { @@ -76,7 +78,7 @@ export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = if (hasApiKey || data) { setIsModalVisible(true); } else { - makeRequest({ indexName }); + makeRequest({ indexName, isNative, secretId }); } }; @@ -87,7 +89,7 @@ export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = }; const onConfirm = () => { - makeRequest({ indexName }); + makeRequest({ indexName, isNative, secretId }); setIsModalVisible(false); }; @@ -96,17 +98,28 @@ export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = {isModalVisible && <ConfirmModal onCancel={onCancel} onConfirm={onConfirm} />} <EuiFlexItem> <EuiText size="s"> - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.description', - { - defaultMessage: - 'First, generate an Elasticsearch API key. This {apiKeyName} key will enable read and write permissions for the connector to index documents to the created {indexName} index. Save the key in a safe place, as you will need it to configure your connector.', - values: { - apiKeyName: `${indexName}-connector`, - indexName, - }, - } - )} + {isNative + ? i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.apiKey.description', + { + defaultMessage: `This native connector's API key {apiKeyName} is managed internally by Elasticsearch. The connector uses this API key to index documents into the {indexName} index. To rollover your API key, click "Generate API key".`, + values: { + apiKeyName: `${indexName}-connector`, + indexName, + }, + } + ) + : i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.description', + { + defaultMessage: + 'First, generate an Elasticsearch API key. This {apiKeyName} key will enable read and write permissions for the connector to index documents to the created {indexName} index. Save the key in a safe place, as you will need it to configure your connector.', + values: { + apiKeyName: `${indexName}-connector`, + indexName, + }, + } + )} </EuiText> </EuiFlexItem> <EuiFlexItem> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx index e338b7d1f193b..748815d4421b6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx @@ -95,7 +95,12 @@ export const ConnectorConfiguration: React.FC = () => { steps={[ { children: ( - <ApiKeyConfig indexName={indexName} hasApiKey={!!index.connector.api_key_id} /> + <ApiKeyConfig + indexName={indexName} + hasApiKey={!!index.connector.api_key_id} + isNative={false} + secretId={null} + /> ), status: hasApiKey ? 'complete' : 'incomplete', title: i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx index fce32710a580d..3457e3c709fca 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx @@ -30,9 +30,11 @@ import { HttpLogic } from '../../../../../shared/http'; import { CONNECTOR_ICONS } from '../../../../../shared/icons/connector_icons'; import { KibanaLogic } from '../../../../../shared/kibana'; +import { GenerateConnectorApiKeyApiLogic } from '../../../../api/connector/generate_connector_api_key_api_logic'; import { hasConfiguredConfiguration } from '../../../../utils/has_configured_configuration'; import { isConnectorIndex } from '../../../../utils/indices'; import { IndexViewLogic } from '../../index_view_logic'; +import { ApiKeyConfig } from '../api_key_configuration'; import { ConnectorNameAndDescription } from '../connector_name_and_description/connector_name_and_description'; import { BETA_CONNECTORS, NATIVE_CONNECTORS } from '../constants'; @@ -45,6 +47,7 @@ export const NativeConnectorConfiguration: React.FC = () => { const { index } = useValues(IndexViewLogic); const { config } = useValues(KibanaLogic); const { errorConnectingMessage } = useValues(HttpLogic); + const { data: apiKeyData } = useValues(GenerateConnectorApiKeyApiLogic); if (!isConnectorIndex(index)) { return <></>; @@ -74,6 +77,8 @@ export const NativeConnectorConfiguration: React.FC = () => { const hasResearched = hasDescription || hasConfigured || hasConfiguredAdvanced; const icon = nativeConnector.icon; + const hasApiKey = !!(index.connector.api_key_id ?? apiKeyData); + // TODO service_type === "" is considered unknown/custom connector multipleplaces replace all of them with a better solution const isBeta = !index.connector.service_type || @@ -140,6 +145,24 @@ export const NativeConnectorConfiguration: React.FC = () => { ), titleSize: 'xs', }, + { + children: ( + <ApiKeyConfig + indexName={index.connector.name} + hasApiKey={hasApiKey} + isNative + secretId={index.connector.api_key_secret_id} + /> + ), + status: hasApiKey ? 'complete' : 'incomplete', + title: i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.steps.regenerateApiKeyTitle', + { + defaultMessage: 'Regenerate API key', + } + ), + titleSize: 'xs', + }, { children: <ConnectorNameAndDescription />, status: hasDescription ? 'complete' : 'incomplete', diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts index de2d2d2db3927..61c250ebc27e5 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts @@ -11,8 +11,6 @@ import { createConnector, fetchConnectorByIndexName, deleteConnectorById, - createConnectorSecret, - updateConnectorApiKeyId, } from '@kbn/search-connectors'; import { ErrorCode } from '../../../common/types/error_codes'; @@ -27,8 +25,6 @@ jest.mock('@kbn/search-connectors', () => ({ createConnector: jest.fn(), deleteConnectorById: jest.fn(), fetchConnectorByIndexName: jest.fn(), - createConnectorSecret: jest.fn(), - updateConnectorApiKeyId: jest.fn(), })); jest.mock('../crawler/fetch_crawlers', () => ({ fetchCrawlerByIndexName: jest.fn() })); jest.mock('../indices/generate_api_key', () => ({ generateApiKey: jest.fn() })); @@ -76,10 +72,7 @@ describe('addConnector lib function', () => { (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); - (generateApiKey as jest.Mock).mockImplementation(() => undefined); - (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); - (updateConnectorApiKeyId as jest.Mock).mockImplementation(() => undefined); await expect( addConnector(mockClient as unknown as IScopedClusterClient, { @@ -108,8 +101,6 @@ describe('addConnector lib function', () => { // non-native connector should not generate API key or update secrets storage expect(generateApiKey).toBeCalledTimes(0); - expect(createConnectorSecret).toBeCalledTimes(0); - expect(updateConnectorApiKeyId).toBeCalledTimes(0); }); it('should add a native connector', async () => { @@ -122,13 +113,10 @@ describe('addConnector lib function', () => { (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); - (generateApiKey as jest.Mock).mockImplementation(() => ({ id: 'api-key-id', encoded: 'encoded-api-key', })); - (createConnectorSecret as jest.Mock).mockImplementation(() => ({ id: 'connector-secret-id' })); - (updateConnectorApiKeyId as jest.Mock).mockImplementation(() => ({ acknowledged: true })); await expect( addConnector(mockClient as unknown as IScopedClusterClient, { @@ -156,14 +144,7 @@ describe('addConnector lib function', () => { }); // native connector should generate API key and update secrets storage - expect(generateApiKey).toHaveBeenCalledWith(mockClient, 'index_name'); - expect(createConnectorSecret).toHaveBeenCalledWith(mockClient.asCurrentUser, 'encoded-api-key'); - expect(updateConnectorApiKeyId).toHaveBeenCalledWith( - mockClient.asCurrentUser, - 'fakeId', - 'api-key-id', - 'connector-secret-id' - ); + expect(generateApiKey).toHaveBeenCalledWith(mockClient, 'index_name', true, null); }); it('should reject if index already exists', async () => { @@ -254,13 +235,10 @@ describe('addConnector lib function', () => { (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => ({ id: 'connectorId' })); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); - (generateApiKey as jest.Mock).mockImplementation(() => ({ id: 'api-key-id', encoded: 'encoded-api-key', })); - (createConnectorSecret as jest.Mock).mockImplementation(() => ({ id: 'connector-secret-id' })); - (updateConnectorApiKeyId as jest.Mock).mockImplementation(() => ({ acknowledged: true })); await expect( addConnector(mockClient as unknown as IScopedClusterClient, { diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts index 3c5265234bb9a..0f15f2767079f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts @@ -9,11 +9,9 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { createConnector, - createConnectorSecret, Connector, ConnectorStatus, deleteConnectorById, - updateConnectorApiKeyId, } from '@kbn/search-connectors'; import { fetchConnectorByIndexName, NATIVE_CONNECTOR_DEFINITIONS } from '@kbn/search-connectors'; @@ -97,14 +95,7 @@ export const addConnector = async ( input.isNative && input.serviceType !== ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE ) { - const apiKey = await generateApiKey(client, index); - const connectorSecret = await createConnectorSecret(client.asCurrentUser, apiKey.encoded); - await updateConnectorApiKeyId( - client.asCurrentUser, - connector.id, - apiKey.id, - connectorSecret.id - ); + await generateApiKey(client, index, true, null); } return connector; diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts index 92c87b354a470..541566ee2d19d 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts @@ -7,11 +7,22 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX } from '@kbn/search-connectors'; +import { + CONNECTORS_INDEX, + createConnectorSecret, + updateConnectorSecret, +} from '@kbn/search-connectors'; import { generateApiKey } from './generate_api_key'; -describe('generateApiKey lib function', () => { +jest.mock('@kbn/search-connectors', () => ({ + CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX: '.search-acl-filter-', + CONNECTORS_INDEX: '.elastic-connectors', + createConnectorSecret: jest.fn(), + updateConnectorSecret: jest.fn(), +})); + +describe('generateApiKey lib function for connector clients', () => { const mockClient = { asCurrentUser: { index: jest.fn(), @@ -47,9 +58,11 @@ describe('generateApiKey lib function', () => { encoded: 'encoded', id: 'apiKeyId', })); + (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); + (updateConnectorSecret as jest.Mock).mockImplementation(() => undefined); await expect( - generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name') + generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name', false, null) ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); expect(mockClient.asCurrentUser.index).not.toHaveBeenCalled(); expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ @@ -66,6 +79,8 @@ describe('generateApiKey lib function', () => { }, }, }); + expect(createConnectorSecret).toBeCalledTimes(0); + expect(updateConnectorSecret).toBeCalledTimes(0); }); it('should create an API key plus connector for connectors', async () => { mockClient.asCurrentUser.search.mockImplementation(() => @@ -83,9 +98,11 @@ describe('generateApiKey lib function', () => { encoded: 'encoded', id: 'apiKeyId', })); + (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); + (updateConnectorSecret as jest.Mock).mockImplementation(() => undefined); await expect( - generateApiKey(mockClient as unknown as IScopedClusterClient, 'search-test') + generateApiKey(mockClient as unknown as IScopedClusterClient, 'search-test', false, null) ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ name: 'search-test-connector', @@ -107,6 +124,8 @@ describe('generateApiKey lib function', () => { index: CONNECTORS_INDEX, }); expect(mockClient.asCurrentUser.security.invalidateApiKey).not.toHaveBeenCalled(); + expect(createConnectorSecret).toBeCalledTimes(0); + expect(updateConnectorSecret).toBeCalledTimes(0); }); it('should invalidate API key if already defined', async () => { mockClient.asCurrentUser.search.mockImplementation(() => @@ -130,9 +149,11 @@ describe('generateApiKey lib function', () => { encoded: 'encoded', id: 'apiKeyId', })); + (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); + (updateConnectorSecret as jest.Mock).mockImplementation(() => undefined); await expect( - generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name') + generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name', false, null) ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ name: 'index_name-connector', @@ -154,7 +175,173 @@ describe('generateApiKey lib function', () => { index: CONNECTORS_INDEX, }); expect(mockClient.asCurrentUser.security.invalidateApiKey).toHaveBeenCalledWith({ - id: '1', + ids: ['1'], + }); + expect(createConnectorSecret).toBeCalledTimes(0); + expect(updateConnectorSecret).toBeCalledTimes(0); + }); +}); + +describe('generateApiKey lib function for native connectors', () => { + const mockClient = { + asCurrentUser: { + index: jest.fn(), + indices: { + create: jest.fn(), + }, + search: jest.fn(), + security: { + createApiKey: jest.fn(), + invalidateApiKey: jest.fn(), + }, + }, + asInternalUser: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should create an API key if index does not have a connector', async () => { + mockClient.asCurrentUser.search.mockImplementation(() => + Promise.resolve({ + hits: { + hits: [], + }, + }) + ); + mockClient.asCurrentUser.index.mockImplementation(() => ({ + _id: 'connectorId', + _source: 'Document', + })); + mockClient.asCurrentUser.security.createApiKey.mockImplementation(() => ({ + encoded: 'encoded', + id: 'apiKeyId', + })); + (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); + (updateConnectorSecret as jest.Mock).mockImplementation(() => undefined); + + await expect( + generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name', true, null) + ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); + expect(mockClient.asCurrentUser.index).not.toHaveBeenCalled(); + expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ + name: 'index_name-connector', + role_descriptors: { + ['index-name-connector-role']: { + cluster: ['monitor'], + index: [ + { + names: ['index_name', '.search-acl-filter-index_name', `${CONNECTORS_INDEX}*`], + privileges: ['all'], + }, + ], + }, + }, + }); + expect(createConnectorSecret).toBeCalledTimes(0); + expect(updateConnectorSecret).toBeCalledTimes(0); + }); + it('should create an API key plus connector for connectors', async () => { + mockClient.asCurrentUser.search.mockImplementation(() => + Promise.resolve({ + hits: { + hits: [{ _id: 'connectorId', _source: { doc: 'doc' } }], + }, + }) + ); + mockClient.asCurrentUser.index.mockImplementation(() => ({ + _id: 'connectorId', + _source: 'Document', + })); + mockClient.asCurrentUser.security.createApiKey.mockImplementation(() => ({ + encoded: 'encoded', + id: 'apiKeyId', + })); + (createConnectorSecret as jest.Mock).mockImplementation(() => ({ + id: '1234', + })); + (updateConnectorSecret as jest.Mock).mockImplementation(() => undefined); + + await expect( + generateApiKey(mockClient as unknown as IScopedClusterClient, 'search-test', true, null) + ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); + expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ + name: 'search-test-connector', + role_descriptors: { + ['search-test-connector-role']: { + cluster: ['monitor'], + index: [ + { + names: ['search-test', '.search-acl-filter-search-test', `${CONNECTORS_INDEX}*`], + privileges: ['all'], + }, + ], + }, + }, + }); + expect(mockClient.asCurrentUser.index).toHaveBeenCalledWith({ + document: { api_key_id: 'apiKeyId', api_key_secret_id: '1234', doc: 'doc' }, + id: 'connectorId', + index: CONNECTORS_INDEX, + }); + expect(mockClient.asCurrentUser.security.invalidateApiKey).not.toHaveBeenCalled(); + expect(createConnectorSecret).toHaveBeenCalledWith(mockClient.asCurrentUser, 'encoded'); + expect(updateConnectorSecret).toBeCalledTimes(0); + }); + it('should invalidate API key if already defined', async () => { + mockClient.asCurrentUser.search.mockImplementation(() => + Promise.resolve({ + hits: { + hits: [ + { + _id: 'connectorId', + _source: { api_key_id: '1', doc: 'doc' }, + fields: { api_key_id: '1' }, + }, + ], + }, + }) + ); + mockClient.asCurrentUser.index.mockImplementation(() => ({ + _id: 'connectorId', + _source: 'Document', + })); + mockClient.asCurrentUser.security.createApiKey.mockImplementation(() => ({ + encoded: 'encoded', + id: 'apiKeyId', + })); + (createConnectorSecret as jest.Mock).mockImplementation(() => undefined); + (updateConnectorSecret as jest.Mock).mockImplementation(() => ({ + result: 'updated', + })); + + await expect( + generateApiKey(mockClient as unknown as IScopedClusterClient, 'index_name', true, '1234') + ).resolves.toEqual({ encoded: 'encoded', id: 'apiKeyId' }); + expect(mockClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ + name: 'index_name-connector', + role_descriptors: { + ['index-name-connector-role']: { + cluster: ['monitor'], + index: [ + { + names: ['index_name', '.search-acl-filter-index_name', `${CONNECTORS_INDEX}*`], + privileges: ['all'], + }, + ], + }, + }, + }); + expect(mockClient.asCurrentUser.index).toHaveBeenCalledWith({ + document: { api_key_id: 'apiKeyId', api_key_secret_id: '1234', doc: 'doc' }, + id: 'connectorId', + index: CONNECTORS_INDEX, + }); + expect(mockClient.asCurrentUser.security.invalidateApiKey).toHaveBeenCalledWith({ + ids: ['1'], }); + expect(createConnectorSecret).toBeCalledTimes(0); + expect(updateConnectorSecret).toHaveBeenCalledWith(mockClient.asCurrentUser, 'encoded', '1234'); }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts index fb2ddbaad9f9d..01955cb004b24 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts @@ -11,11 +11,18 @@ import { ConnectorDocument, CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, CONNECTORS_INDEX, + createConnectorSecret, + updateConnectorSecret, } from '@kbn/search-connectors'; import { toAlphanumeric } from '../../../common/utils/to_alphanumeric'; -export const generateApiKey = async (client: IScopedClusterClient, indexName: string) => { +export const generateApiKey = async ( + client: IScopedClusterClient, + indexName: string, + isNative: boolean, + secretId: string | null +) => { const aclIndexName = `${CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX}${indexName}`; const apiKeyResult = await client.asCurrentUser.security.createApiKey({ @@ -32,20 +39,47 @@ export const generateApiKey = async (client: IScopedClusterClient, indexName: st }, }, }); + const connectorResult = await client.asCurrentUser.search<ConnectorDocument>({ index: CONNECTORS_INDEX, query: { term: { index_name: indexName } }, }); const connector = connectorResult.hits.hits[0]; if (connector) { - if (connector.fields?.api_key_id) { - await client.asCurrentUser.security.invalidateApiKey({ id: connector.fields.api_key_id }); + const apiKeyFields = isNative + ? { + api_key_id: apiKeyResult.id, + api_key_secret_id: await storeConnectorSecret(client, apiKeyResult.encoded, secretId), + } + : { + api_key_id: apiKeyResult.id, + }; + + if (connector._source?.api_key_id) { + await client.asCurrentUser.security.invalidateApiKey({ ids: [connector._source.api_key_id] }); } await client.asCurrentUser.index({ - document: { ...connector._source, api_key_id: apiKeyResult.id }, + document: { + ...connector._source, + ...apiKeyFields, + }, id: connector._id, index: CONNECTORS_INDEX, }); } return apiKeyResult; }; + +const storeConnectorSecret = async ( + client: IScopedClusterClient, + value: string, + secretId: string | null +) => { + if (secretId === null) { + const connectorSecretResult = await createConnectorSecret(client.asCurrentUser, value); + return connectorSecretResult.id; + } + + await updateConnectorSecret(client.asCurrentUser, value, secretId); + return secretId; +}; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index fdbeca1e82ff9..9872f4d7c7a66 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -278,6 +278,10 @@ export function registerIndexRoutes({ { path: '/internal/enterprise_search/indices/{indexName}/api_key', validate: { + body: schema.object({ + is_native: schema.boolean(), + secret_id: schema.maybe(schema.nullable(schema.string())), + }), params: schema.object({ indexName: schema.string(), }), @@ -285,9 +289,11 @@ export function registerIndexRoutes({ }, elasticsearchErrorHandler(log, async (context, request, response) => { const indexName = decodeURIComponent(request.params.indexName); + const { is_native: isNative, secret_id: secretId } = request.body; + const { client } = (await context.core).elasticsearch; - const apiKey = await generateApiKey(client, indexName); + const apiKey = await generateApiKey(client, indexName, isNative, secretId || null); return response.ok({ body: apiKey, From 2c0fd46961677c913928a452ef5073feeec8f220 Mon Sep 17 00:00:00 2001 From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:07:18 +0000 Subject: [PATCH 069/104] [Index Management] Fix index template simulate request (#176183) Fixes https://github.com/elastic/kibana/issues/165889 ## Summary This PR fixes the simulate request for index templates. Previously, it would fail when we simulate an index template which references a component template that is not created yet, because the `ignore_missing_component_templates` option wasn't configured. This PR adds this property to the template format so that it is sent as part of the simulate request. **How to test:** 1. Start Es with `yarn es snapshot` and Kibana with `yarn start`. 2. Go to Dev Tools. 3. Create an index template that references a component template: ``` PUT _index_template/test-template { "index_patterns": ["test-*"], "composed_of": ["some_component_template"], "ignore_missing_component_templates": ["some_component_template"] } ``` 4. Go to Stack Management -> Index Management -> Index Templates. 5. Click on the created index template to open the details flyout. 6. Click on the "Preview" tab and verify that the simulate request was successful. --- .../index_management/common/lib/template_serialization.ts | 4 ++++ x-pack/plugins/index_management/common/types/templates.ts | 2 ++ .../server/routes/api/templates/validate_schemas.ts | 1 + .../apis/management/index_management/templates.ts | 6 ++++++ .../test_suites/common/index_management/index_templates.ts | 2 ++ 5 files changed, 15 insertions(+) diff --git a/x-pack/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts index 5ec150a85aa17..80a5514969f54 100644 --- a/x-pack/plugins/index_management/common/lib/template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/template_serialization.ts @@ -23,6 +23,7 @@ export function serializeTemplate(templateDeserialized: TemplateDeserialized): T indexPatterns, template, composedOf, + ignoreMissingComponentTemplates, dataStream, _meta, allowAutoCreate, @@ -35,6 +36,7 @@ export function serializeTemplate(templateDeserialized: TemplateDeserialized): T index_patterns: indexPatterns, data_stream: dataStream, composed_of: composedOf, + ignore_missing_component_templates: ignoreMissingComponentTemplates, allow_auto_create: allowAutoCreate, _meta, }; @@ -52,6 +54,7 @@ export function deserializeTemplate( priority, _meta, composed_of: composedOf, + ignore_missing_component_templates: ignoreMissingComponentTemplates, data_stream: dataStream, deprecated, allow_auto_create: allowAutoCreate, @@ -76,6 +79,7 @@ export function deserializeTemplate( template, ilmPolicy: settings?.index?.lifecycle, composedOf: composedOf ?? [], + ignoreMissingComponentTemplates: ignoreMissingComponentTemplates ?? [], dataStream, allowAutoCreate, _meta, diff --git a/x-pack/plugins/index_management/common/types/templates.ts b/x-pack/plugins/index_management/common/types/templates.ts index e2f530b4ad502..9205605c70010 100644 --- a/x-pack/plugins/index_management/common/types/templates.ts +++ b/x-pack/plugins/index_management/common/types/templates.ts @@ -23,6 +23,7 @@ export interface TemplateSerialized { }; deprecated?: boolean; composed_of?: string[]; + ignore_missing_component_templates?: string[]; version?: number; priority?: number; _meta?: { [key: string]: any }; @@ -45,6 +46,7 @@ export interface TemplateDeserialized { }; lifecycle?: DataRetention; composedOf?: string[]; // Composable template only + ignoreMissingComponentTemplates?: string[]; version?: number; priority?: number; // Composable template only allowAutoCreate?: boolean; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts b/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts index b9020585ed676..1f5c5e2a3b82e 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts @@ -28,6 +28,7 @@ export const templateSchema = schema.object({ }) ), composedOf: schema.maybe(schema.arrayOf(schema.string())), + ignoreMissingComponentTemplates: schema.maybe(schema.arrayOf(schema.string())), dataStream: schema.maybe( schema.object( { diff --git a/x-pack/test/api_integration/apis/management/index_management/templates.ts b/x-pack/test/api_integration/apis/management/index_management/templates.ts index a3b2ce50e04b5..6d0e79993d040 100644 --- a/x-pack/test/api_integration/apis/management/index_management/templates.ts +++ b/x-pack/test/api_integration/apis/management/index_management/templates.ts @@ -96,6 +96,7 @@ export default function ({ getService }: FtrProviderContext) { 'hasMappings', 'priority', 'composedOf', + 'ignoreMissingComponentTemplates', 'version', '_kbnMeta', ].sort(); @@ -119,6 +120,7 @@ export default function ({ getService }: FtrProviderContext) { 'version', '_kbnMeta', 'composedOf', + 'ignoreMissingComponentTemplates', ].sort(); expect(Object.keys(legacyTemplateFound).sort()).to.eql(expectedLegacyKeys); @@ -139,6 +141,7 @@ export default function ({ getService }: FtrProviderContext) { 'hasMappings', 'priority', 'composedOf', + 'ignoreMissingComponentTemplates', 'dataStream', 'version', '_kbnMeta', @@ -162,6 +165,7 @@ export default function ({ getService }: FtrProviderContext) { 'hasMappings', 'priority', 'composedOf', + 'ignoreMissingComponentTemplates', 'version', '_kbnMeta', ].sort(); @@ -183,6 +187,7 @@ export default function ({ getService }: FtrProviderContext) { 'indexPatterns', 'template', 'composedOf', + 'ignoreMissingComponentTemplates', 'priority', 'version', '_kbnMeta', @@ -207,6 +212,7 @@ export default function ({ getService }: FtrProviderContext) { 'version', '_kbnMeta', 'composedOf', + 'ignoreMissingComponentTemplates', ].sort(); const expectedTemplateKeys = ['aliases', 'mappings', 'settings'].sort(); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts index 6546d94afe391..82fd6dd057ae5 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index_templates.ts @@ -104,6 +104,7 @@ export default function ({ getService }: FtrProviderContext) { 'hasMappings', '_kbnMeta', 'composedOf', + 'ignoreMissingComponentTemplates', ].sort(); expect(Object.keys(indexTemplateFound).sort()).to.eql(expectedKeys); @@ -124,6 +125,7 @@ export default function ({ getService }: FtrProviderContext) { 'template', '_kbnMeta', 'composedOf', + 'ignoreMissingComponentTemplates', ].sort(); expect(body.name).to.eql(templateName); From 5ff2f987a515345f325ab2421fbf1c137c71b93c Mon Sep 17 00:00:00 2001 From: Tiago Vila Verde <tiago.vilaverde@elastic.co> Date: Fri, 9 Feb 2024 12:33:20 +0100 Subject: [PATCH 070/104] [Security Solution][Entity Analytics] More detailed privilege control for Asset Criticality assignment (#176333) ## Summary This PR fixes a bug where users with `read` access and without `write` access would not be able to see the Criticality assigned to an entity. The criticality component would only check whether a user has _all_ the required privileges, which didn't account for read-only case. By adding more granular and detailed information to the privileges API call, we can now show the currently assigned criticality but hide the `Change/Create` button if the user does not have `write` access. https://github.com/elastic/kibana/assets/2423976/00845ac7-11f4-429c-990b-c068dfb19f6b ### How to test 1. Login in as a `superuser` 2. Assign criticality to some entity via the expandable flyout. 3. Create a role with read-only/read-write or no access to the criticality index <img width="1352" alt="Screenshot 2024-01-31 at 09 58 04" src="https://github.com/elastic/security-team/assets/7609147/22477433-63e8-4ccf-a077-275725a600aa"> 4. Create a user(s) with the new role(s) 5. Login with that user and open the expandable flyout 6. Check that the criticality is only shown for users with `read` privilege and that the update button only shows for users with `write` privileges ### Checklist Delete any items that are not applicable to this PR. - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --- .../api/entity_analytics/common/common.gen.ts | 2 + .../common/common.schema.yaml | 28 +++++---- .../asset_criticality_selector.tsx | 46 ++++++++------- .../use_asset_criticality.ts | 2 +- .../utils/check_and_format_privileges.test.ts | 59 ++++++++++++++++++- .../utils/check_and_format_privileges.ts | 17 ++++++ 6 files changed, 117 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts index 908043ab7335e..2c58f0461967b 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.gen.ts @@ -19,6 +19,8 @@ import { z } from 'zod'; export type EntityAnalyticsPrivileges = z.infer<typeof EntityAnalyticsPrivileges>; export const EntityAnalyticsPrivileges = z.object({ has_all_required: z.boolean(), + has_read_permissions: z.boolean().optional(), + has_write_permissions: z.boolean().optional(), privileges: z.object({ elasticsearch: z.object({ cluster: z diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.schema.yaml index b16729ccc38b3..9285503c322f0 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/common/common.schema.yaml @@ -3,7 +3,7 @@ info: title: Entity Analytics Common Schema description: Common schema for Entity Analytics version: 1.0.0 -paths: { } +paths: {} components: schemas: EntityAnalyticsPrivileges: @@ -11,6 +11,10 @@ components: properties: has_all_required: type: boolean + has_read_permissions: + type: boolean + has_write_permissions: + type: boolean privileges: type: object properties: @@ -20,19 +24,19 @@ components: cluster: type: object properties: - manage_index_templates: - type: boolean - manage_transform: - type: boolean + manage_index_templates: + type: boolean + manage_transform: + type: boolean index: type: object additionalProperties: - type: object - properties: - read: - type: boolean - write: - type: boolean + type: object + properties: + read: + type: boolean + write: + type: boolean required: - elasticsearch required: @@ -176,8 +180,6 @@ components: items: $ref: '#/components/schemas/RiskScoreInput' - - RiskScoreWeight: description: "Configuration used to tune risk scoring. Weights can be used to change the score contribution of risk inputs for hosts and users at both a global level and also for Risk Input categories (e.g. 'category_1')." type: object diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx index fa161ea239ac3..c23fe47e9f4ff 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx @@ -44,7 +44,7 @@ const AssetCriticalityComponent: React.FC<Props> = ({ entity }) => { const criticality = useAssetCriticalityData(entity, modal); const { euiTheme } = useEuiTheme(); - if (criticality.privileges.isLoading || !criticality.privileges.data?.has_all_required) { + if (criticality.privileges.isLoading || !criticality.privileges.data?.has_read_permissions) { return null; } @@ -87,27 +87,29 @@ const AssetCriticalityComponent: React.FC<Props> = ({ entity }) => { /> </EuiText> </EuiFlexItem> - <EuiFlexItem css={{ flexGrow: 'unset' }}> - <EuiButtonEmpty - data-test-subj="asset-criticality-change-btn" - iconType="arrowStart" - iconSide="left" - flush="right" - onClick={() => modal.toggle(true)} - > - {criticality.status === 'update' ? ( - <FormattedMessage - id="xpack.securitySolution.entityAnalytics.assetCriticality.changeButton" - defaultMessage="Change" - /> - ) : ( - <FormattedMessage - id="xpack.securitySolution.entityAnalytics.assetCriticality.createButton" - defaultMessage="Create" - /> - )} - </EuiButtonEmpty> - </EuiFlexItem> + {criticality.privileges.data?.has_write_permissions && ( + <EuiFlexItem css={{ flexGrow: 'unset' }}> + <EuiButtonEmpty + data-test-subj="asset-criticality-change-btn" + iconType="arrowStart" + iconSide="left" + flush="right" + onClick={() => modal.toggle(true)} + > + {criticality.status === 'update' ? ( + <FormattedMessage + id="xpack.securitySolution.entityAnalytics.assetCriticality.changeButton" + defaultMessage="Change" + /> + ) : ( + <FormattedMessage + id="xpack.securitySolution.entityAnalytics.assetCriticality.createButton" + defaultMessage="Create" + /> + )} + </EuiButtonEmpty> + </EuiFlexItem> + )} </EuiFlexGroup> )} </EuiAccordion> diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/use_asset_criticality.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/use_asset_criticality.ts index 5ac7d176a7b44..893f157d045cf 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/use_asset_criticality.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/use_asset_criticality.ts @@ -40,7 +40,7 @@ export const useAssetCriticalityData = (entity: Entity, modal: ModalState): Stat queryKey: QUERY_KEYS.doc, queryFn: () => fetchAssetCriticality({ idField: `${entity.type}.name`, idValue: entity.name }), retry: (failureCount, error) => error.body.statusCode === 404 && failureCount > 0, - enabled: privileges.data?.has_all_required, + enabled: !!privileges.data?.has_read_permissions, }); const mutation = useMutation({ diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.test.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.test.ts index 0001dfdac4143..04f4e95272116 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.test.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { _formatPrivileges } from './check_and_format_privileges'; +import { ASSET_CRITICALITY_INDEX_PATTERN } from '../../../../common/entity_analytics/asset_criticality/constants'; +import { _formatPrivileges, hasReadWritePermissions } from './check_and_format_privileges'; describe('_formatPrivileges', () => { it('should correctly format elasticsearch index privileges', () => { @@ -146,4 +147,60 @@ describe('_formatPrivileges', () => { }, }); }); + + it('should correctly extract read and write permissions from elasticsearch cluster privileges', () => { + const privileges = { + elasticsearch: { + cluster: [ + { + privilege: 'read', + authorized: true, + }, + { + privilege: 'write', + authorized: false, + }, + ], + index: {}, + }, + kibana: [], + }; + + const result = hasReadWritePermissions(privileges.elasticsearch); + + expect(result).toEqual({ + has_read_permissions: true, + has_write_permissions: false, + }); + }); + it('should correctly extract read and write permissions from elasticsearch index privileges', () => { + const privileges = { + elasticsearch: { + cluster: [], + index: { + [ASSET_CRITICALITY_INDEX_PATTERN]: [ + { + privilege: 'read', + authorized: true, + }, + { + privilege: 'write', + authorized: false, + }, + ], + }, + }, + kibana: [], + }; + + const result = hasReadWritePermissions( + privileges.elasticsearch, + ASSET_CRITICALITY_INDEX_PATTERN + ); + + expect(result).toEqual({ + has_read_permissions: true, + has_write_permissions: false, + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.ts index 52348ad1be879..0c9ac9036fad2 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/check_and_format_privileges.ts @@ -11,6 +11,7 @@ import type { CheckPrivilegesResponse, SecurityPluginStart, } from '@kbn/security-plugin/server'; +import { ASSET_CRITICALITY_INDEX_PATTERN } from '../../../../common/entity_analytics/asset_criticality/constants'; import type { EntityAnalyticsPrivileges } from '../../../../common/api/entity_analytics/common'; const groupPrivilegesByName = <PrivilegeName extends string>( privileges: Array<{ @@ -69,5 +70,21 @@ export async function checkAndFormatPrivileges({ return { privileges: _formatPrivileges(privileges), has_all_required: hasAllRequested, + ...hasReadWritePermissions(privileges.elasticsearch, ASSET_CRITICALITY_INDEX_PATTERN), }; } + +export const hasReadWritePermissions = ( + { index, cluster }: CheckPrivilegesResponse['privileges']['elasticsearch'], + indexKey = '' +) => { + const has = + (type: string) => + ({ privilege, authorized }: { privilege: string; authorized: boolean }) => + privilege === type && authorized; + return { + has_read_permissions: index[indexKey]?.some(has('read')) || cluster.some(has('read')), + + has_write_permissions: index[indexKey]?.some(has('write')) || cluster.some(has('write')), + }; +}; From 8d43c0e7180e5f94c5e708064f0c0a25ce7c4e6d Mon Sep 17 00:00:00 2001 From: Ying Mao <ying.mao@elastic.co> Date: Fri, 9 Feb 2024 07:55:26 -0500 Subject: [PATCH 071/104] [Response Ops][Alerting] Removing unnecessary error log when getting the rules setting saved object (#176538) Resolves https://github.com/elastic/kibana/issues/174534 ## Summary Removing extra error log that was unneeded and did not check for a saved object not found error before logging. Since the `getSettings` function is only used internally by the client, I removed the logger altogether and let the calling function catch and handle the error. ## To Verify Start up ES and Kibana and create a rule. On the first run, you should see 2 INFO logs for creating the settings but no error logs. ``` [2024-02-08T12:53:44.327-05:00][INFO ][plugins.alerting] Creating new default flapping rules settings for current space. [2024-02-08T12:49:41.780-05:00][INFO ][plugins.alerting] Creating new default query delay rules settings for current space. ``` --- .../server/rules_settings_client.mock.ts | 4 ---- .../rules_settings_flapping_client.test.ts | 3 +++ .../flapping/rules_settings_flapping_client.ts | 17 ++++++----------- .../rules_settings_query_delay_client.test.ts | 5 +++-- .../rules_settings_query_delay_client.ts | 17 ++++++----------- 5 files changed, 18 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts index 12703161fdb46..5e3479b10e0ab 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts +++ b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts @@ -23,14 +23,10 @@ const createRulesSettingsClientMock = () => { const flappingMocked: RulesSettingsFlappingClientMock = { get: jest.fn().mockReturnValue(DEFAULT_FLAPPING_SETTINGS), update: jest.fn(), - getSettings: jest.fn(), - createSettings: jest.fn(), }; const queryDelayMocked: RulesSettingsQueryDelayClientMock = { get: jest.fn().mockReturnValue(DEFAULT_QUERY_DELAY_SETTINGS), update: jest.fn(), - getSettings: jest.fn(), - createSettings: jest.fn(), }; const mocked: RulesSettingsClientMock = { flapping: jest.fn().mockReturnValue(flappingMocked), diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts index 19f978a8985f1..213d1a94a38eb 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts @@ -215,6 +215,7 @@ describe('RulesSettingsFlappingClient', () => { references: [], }); + // @ts-expect-error access private method const result = await client.createSettings(); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); @@ -249,6 +250,7 @@ describe('RulesSettingsFlappingClient', () => { attributes: mockAttributes, references: [], }); + // @ts-expect-error access private method const result = await client.getSettings(); expect(result.attributes).toEqual(mockAttributes); }); @@ -262,6 +264,7 @@ describe('RulesSettingsFlappingClient', () => { RULES_SETTINGS_FLAPPING_SAVED_OBJECT_ID ) ); + // @ts-expect-error access private method await expect(client.getSettings()).rejects.toThrowError(); }); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts index 0bf6f2af025fe..724da9cffa149 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts @@ -130,19 +130,14 @@ export class RulesSettingsFlappingClient { } } - public async getSettings(): Promise<SavedObject<RulesSettings>> { - try { - return await this.savedObjectsClient.get<RulesSettings>( - RULES_SETTINGS_SAVED_OBJECT_TYPE, - RULES_SETTINGS_FLAPPING_SAVED_OBJECT_ID - ); - } catch (e) { - this.logger.error(`Failed to get flapping rules setting for current space. Error: ${e}`); - throw e; - } + private async getSettings(): Promise<SavedObject<RulesSettings>> { + return await this.savedObjectsClient.get<RulesSettings>( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_FLAPPING_SAVED_OBJECT_ID + ); } - public async createSettings(): Promise<SavedObject<RulesSettings>> { + private async createSettings(): Promise<SavedObject<RulesSettings>> { const modificationMetadata = await this.getModificationMetadata(); try { return await this.savedObjectsClient.create<RulesSettings>( diff --git a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts index 213ece8cd6fe4..84d707d388a44 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts +++ b/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts @@ -179,7 +179,7 @@ describe('RulesSettingsQueryDelayClient', () => { attributes: mockAttributes, references: [], }); - + // @ts-expect-error access private method const result = await client.createSettings(); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); @@ -221,7 +221,7 @@ describe('RulesSettingsQueryDelayClient', () => { attributes: mockAttributes, references: [], }); - + // @ts-expect-error access private method const result = await client.createSettings(); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); @@ -254,6 +254,7 @@ describe('RulesSettingsQueryDelayClient', () => { attributes: mockAttributes, references: [], }); + // @ts-expect-error access private method const result = await client.getSettings(); expect(result.attributes).toEqual(mockAttributes); }); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts index ac394dca17180..c8dc863a02920 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts +++ b/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts @@ -121,19 +121,14 @@ export class RulesSettingsQueryDelayClient { } } - public async getSettings(): Promise<SavedObject<RulesSettings>> { - try { - return await this.savedObjectsClient.get<RulesSettings>( - RULES_SETTINGS_SAVED_OBJECT_TYPE, - RULES_SETTINGS_QUERY_DELAY_SAVED_OBJECT_ID - ); - } catch (e) { - this.logger.error(`Failed to get query delay rules setting for current space. Error: ${e}`); - throw e; - } + private async getSettings(): Promise<SavedObject<RulesSettings>> { + return await this.savedObjectsClient.get<RulesSettings>( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_QUERY_DELAY_SAVED_OBJECT_ID + ); } - public async createSettings(): Promise<SavedObject<RulesSettings>> { + private async createSettings(): Promise<SavedObject<RulesSettings>> { const modificationMetadata = await this.getModificationMetadata(); const defaultQueryDelaySettings = this.isServerless ? DEFAULT_SERVERLESS_QUERY_DELAY_SETTINGS From 7bbea56c169c575190634046230903877dd8984b Mon Sep 17 00:00:00 2001 From: Marco Liberati <dej611@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:25:28 +0100 Subject: [PATCH 072/104] [ES|QL] New sync with ES changes (#176283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Sync with https://github.com/elastic/elasticsearch/pull/104958 for support of builtin fn in STATS * validation ✅ * autocomplete ✅ * also fixed `STATS BY <field>` syntax ![new_stats](https://github.com/elastic/kibana/assets/924948/735f9842-b1d3-4aa0-9d51-4b2f9b136ed3) Sync with https://github.com/elastic/elasticsearch/pull/104913 for new `log` function * validation ✅ - also warning for negative values * autocomplete ✅ ![add_log](https://github.com/elastic/kibana/assets/924948/146b945d-a23b-45ec-9df2-2d2b291e883b) Sync with https://github.com/elastic/elasticsearch/pull/105064 for removal of `PROJECT` command * validation ✅ (both new and legacy syntax supported) * autocomplete ✅ (will only suggest new syntax) ![remove_project](https://github.com/elastic/kibana/assets/924948/b6f40afe-a26d-4917-b7a1-d8ae97c5368b) Sync with https://github.com/elastic/elasticsearch/pull/105221 for removal of mandatory brackets for `METADATA` command option * validation ✅ (added warning deprecation message when using brackets) * autocomplete ✅ ![fix_metadata](https://github.com/elastic/kibana/assets/924948/c65db176-dd94-45f3-9524-45453e62f51a) Sync with https://github.com/elastic/elasticsearch/pull/105224 for change of syntax for ENRICH ccq mode * validation ✅ * autocomplete ✅ (not directly promoted, the user has to type `_` to trigger it) * hover ✅ * code actions ✅ ![fix_ccq_enrich](https://github.com/elastic/kibana/assets/924948/0900edd9-a0a7-4ac8-bc12-e39a72359984) ![fix_ccq_enrich_2](https://github.com/elastic/kibana/assets/924948/74b0908f-d385-4723-b3d4-c09108f47a73) Do not merge until those 5 get merged. Additional things in this PR: * Added more tests for `callbacks` not passed scenario * covered more cases like those with `dissect` * Added more tests for signature params number (calling a function with an extra arg should return an error) * Cleaned up some more unused code * Improved messages on too many arguments for functions ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../kbn-monaco/src/esql/antlr/esql_lexer.g4 | 6 +- .../src/esql/antlr/esql_lexer.interp | 5 +- .../src/esql/antlr/esql_lexer.tokens | 229 ++- .../kbn-monaco/src/esql/antlr/esql_lexer.ts | 1447 +++++++------- .../kbn-monaco/src/esql/antlr/esql_parser.g4 | 18 +- .../src/esql/antlr/esql_parser.interp | 7 +- .../src/esql/antlr/esql_parser.tokens | 229 ++- .../kbn-monaco/src/esql/antlr/esql_parser.ts | 1750 ++++++++--------- .../src/esql/antlr/esql_parser_listener.ts | 36 +- .../src/esql/lib/ast/ast_factory.ts | 16 +- .../src/esql/lib/ast/ast_helpers.ts | 31 +- .../src/esql/lib/ast/ast_position_utils.ts | 5 +- .../kbn-monaco/src/esql/lib/ast/ast_walker.ts | 33 +- .../lib/ast/autocomplete/autocomplete.test.ts | 84 +- .../esql/lib/ast/autocomplete/autocomplete.ts | 54 +- .../esql/lib/ast/autocomplete/factories.ts | 49 +- .../esql/lib/ast/code_actions/actions.test.ts | 57 +- .../src/esql/lib/ast/code_actions/actions.ts | 61 +- .../src/esql/lib/ast/definitions/builtin.ts | 9 +- .../src/esql/lib/ast/definitions/commands.ts | 119 +- .../src/esql/lib/ast/definitions/functions.ts | 49 +- .../src/esql/lib/ast/definitions/options.ts | 12 +- .../src/esql/lib/ast/definitions/settings.ts | 44 +- .../src/esql/lib/ast/definitions/types.ts | 6 +- .../src/esql/lib/ast/hover/hover.test.ts | 11 + .../src/esql/lib/ast/hover/hover.ts | 75 +- .../src/esql/lib/ast/shared/context.ts | 9 +- .../src/esql/lib/ast/shared/helpers.ts | 6 - packages/kbn-monaco/src/esql/lib/ast/types.ts | 1 - .../src/esql/lib/ast/validation/errors.ts | 12 +- .../src/esql/lib/ast/validation/resources.ts | 2 +- .../src/esql/lib/ast/validation/types.ts | 4 +- .../lib/ast/validation/validation.test.ts | 401 +++- .../src/esql/lib/ast/validation/validation.ts | 198 +- 34 files changed, 2696 insertions(+), 2379 deletions(-) diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 b/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 index 4000c050cb20b..82fba96eeed10 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 @@ -19,7 +19,6 @@ INLINESTATS : I N L I N E S T A T S -> pushMode(EXPRESSION_MODE); KEEP : K E E P -> pushMode(PROJECT_MODE); LIMIT : L I M I T -> pushMode(EXPRESSION_MODE); MV_EXPAND : M V UNDERSCORE E X P A N D -> pushMode(MVEXPAND_MODE); -PROJECT : P R O J E C T -> pushMode(PROJECT_MODE); RENAME : R E N A M E -> pushMode(RENAME_MODE); ROW : R O W -> pushMode(EXPRESSION_MODE); SHOW : S H O W -> pushMode(SHOW_MODE); @@ -218,7 +217,7 @@ FROM_WS : WS -> channel(HIDDEN) ; // -// DROP, KEEP, PROJECT +// DROP, KEEP // mode PROJECT_MODE; PROJECT_PIPE : PIPE -> type(PIPE), popMode; @@ -299,7 +298,8 @@ fragment ENRICH_POLICY_NAME_BODY : ~[\\/?"<>| ,#\t\r\n:] ; ENRICH_POLICY_NAME - : (LETTER | DIGIT) ENRICH_POLICY_NAME_BODY* + // allow prefix for the policy to specify its resolution + : (ENRICH_POLICY_NAME_BODY+ COLON)? ENRICH_POLICY_NAME_BODY+ ; ENRICH_QUOTED_IDENTIFIER diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp b/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp index 51248244df48b..94bd0af8ab463 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp @@ -24,7 +24,6 @@ null null null null -null '|' null null @@ -119,7 +118,6 @@ INLINESTATS KEEP LIMIT MV_EXPAND -PROJECT RENAME ROW SHOW @@ -226,7 +224,6 @@ INLINESTATS KEEP LIMIT MV_EXPAND -PROJECT RENAME ROW SHOW @@ -414,4 +411,4 @@ SHOW_MODE SETTING_MODE atn: -[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 107, 1267, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 4, 178, 9, 178, 4, 179, 9, 179, 4, 180, 9, 180, 4, 181, 9, 181, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 6, 20, 528, 10, 20, 13, 20, 14, 20, 529, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 7, 21, 538, 10, 21, 12, 21, 14, 21, 541, 11, 21, 3, 21, 5, 21, 544, 10, 21, 3, 21, 5, 21, 547, 10, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 7, 22, 556, 10, 22, 12, 22, 14, 22, 559, 11, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 6, 23, 567, 10, 23, 13, 23, 14, 23, 568, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 5, 34, 610, 10, 34, 3, 34, 6, 34, 613, 10, 34, 13, 34, 14, 34, 614, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 5, 37, 624, 10, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 5, 39, 631, 10, 39, 3, 40, 3, 40, 3, 40, 7, 40, 636, 10, 40, 12, 40, 14, 40, 639, 11, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 7, 40, 647, 10, 40, 12, 40, 14, 40, 650, 11, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 5, 40, 657, 10, 40, 3, 40, 5, 40, 660, 10, 40, 5, 40, 662, 10, 40, 3, 41, 6, 41, 665, 10, 41, 13, 41, 14, 41, 666, 3, 42, 6, 42, 670, 10, 42, 13, 42, 14, 42, 671, 3, 42, 3, 42, 7, 42, 676, 10, 42, 12, 42, 14, 42, 679, 11, 42, 3, 42, 3, 42, 6, 42, 683, 10, 42, 13, 42, 14, 42, 684, 3, 42, 6, 42, 688, 10, 42, 13, 42, 14, 42, 689, 3, 42, 3, 42, 7, 42, 694, 10, 42, 12, 42, 14, 42, 697, 11, 42, 5, 42, 699, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 6, 42, 705, 10, 42, 13, 42, 14, 42, 706, 3, 42, 3, 42, 5, 42, 711, 10, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 73, 3, 73, 3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 7, 79, 839, 10, 79, 12, 79, 14, 79, 842, 11, 79, 3, 79, 3, 79, 5, 79, 846, 10, 79, 3, 79, 6, 79, 849, 10, 79, 13, 79, 14, 79, 850, 5, 79, 853, 10, 79, 3, 80, 3, 80, 6, 80, 857, 10, 80, 13, 80, 14, 80, 858, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 5, 90, 908, 10, 90, 3, 91, 6, 91, 911, 10, 91, 13, 91, 14, 91, 912, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 5, 99, 948, 10, 99, 3, 100, 3, 100, 5, 100, 952, 10, 100, 3, 100, 7, 100, 955, 10, 100, 12, 100, 14, 100, 958, 11, 100, 3, 100, 3, 100, 5, 100, 962, 10, 100, 3, 100, 6, 100, 965, 10, 100, 13, 100, 14, 100, 966, 5, 100, 969, 10, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 119, 3, 119, 3, 119, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 5, 121, 1057, 10, 121, 3, 121, 7, 121, 1060, 10, 121, 12, 121, 14, 121, 1063, 11, 121, 3, 122, 3, 122, 3, 122, 3, 122, 3, 123, 3, 123, 3, 123, 3, 123, 3, 124, 3, 124, 3, 124, 3, 124, 3, 125, 3, 125, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 3, 147, 3, 148, 3, 148, 3, 148, 3, 148, 3, 149, 3, 149, 3, 149, 3, 149, 3, 150, 3, 150, 3, 150, 3, 150, 3, 150, 3, 151, 3, 151, 3, 152, 3, 152, 3, 152, 3, 152, 3, 152, 6, 152, 1200, 10, 152, 13, 152, 14, 152, 1201, 3, 153, 3, 153, 3, 153, 3, 153, 3, 154, 3, 154, 3, 154, 3, 154, 3, 155, 3, 155, 3, 155, 3, 155, 3, 156, 3, 156, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 3, 176, 3, 177, 3, 177, 3, 178, 3, 178, 3, 179, 3, 179, 3, 180, 3, 180, 3, 181, 3, 181, 4, 557, 648, 2, 2, 182, 13, 2, 3, 15, 2, 4, 17, 2, 5, 19, 2, 6, 21, 2, 7, 23, 2, 8, 25, 2, 9, 27, 2, 10, 29, 2, 11, 31, 2, 12, 33, 2, 13, 35, 2, 14, 37, 2, 15, 39, 2, 16, 41, 2, 17, 43, 2, 18, 45, 2, 19, 47, 2, 20, 49, 2, 21, 51, 2, 22, 53, 2, 23, 55, 2, 24, 57, 2, 2, 59, 2, 2, 61, 2, 25, 63, 2, 26, 65, 2, 27, 67, 2, 28, 69, 2, 2, 71, 2, 2, 73, 2, 2, 75, 2, 2, 77, 2, 2, 79, 2, 2, 81, 2, 2, 83, 2, 2, 85, 2, 2, 87, 2, 2, 89, 2, 29, 91, 2, 30, 93, 2, 31, 95, 2, 32, 97, 2, 33, 99, 2, 34, 101, 2, 35, 103, 2, 36, 105, 2, 37, 107, 2, 38, 109, 2, 39, 111, 2, 40, 113, 2, 41, 115, 2, 42, 117, 2, 43, 119, 2, 44, 121, 2, 45, 123, 2, 46, 125, 2, 47, 127, 2, 48, 129, 2, 49, 131, 2, 50, 133, 2, 51, 135, 2, 52, 137, 2, 53, 139, 2, 54, 141, 2, 55, 143, 2, 56, 145, 2, 57, 147, 2, 58, 149, 2, 59, 151, 2, 60, 153, 2, 61, 155, 2, 62, 157, 2, 63, 159, 2, 64, 161, 2, 65, 163, 2, 66, 165, 2, 67, 167, 2, 68, 169, 2, 69, 171, 2, 70, 173, 2, 71, 175, 2, 72, 177, 2, 2, 179, 2, 2, 181, 2, 2, 183, 2, 2, 185, 2, 2, 187, 2, 73, 189, 2, 2, 191, 2, 74, 193, 2, 2, 195, 2, 75, 197, 2, 76, 199, 2, 77, 201, 2, 2, 203, 2, 2, 205, 2, 2, 207, 2, 2, 209, 2, 78, 211, 2, 2, 213, 2, 2, 215, 2, 79, 217, 2, 80, 219, 2, 81, 221, 2, 2, 223, 2, 2, 225, 2, 2, 227, 2, 2, 229, 2, 82, 231, 2, 2, 233, 2, 2, 235, 2, 83, 237, 2, 84, 239, 2, 85, 241, 2, 2, 243, 2, 2, 245, 2, 86, 247, 2, 87, 249, 2, 2, 251, 2, 88, 253, 2, 2, 255, 2, 2, 257, 2, 89, 259, 2, 90, 261, 2, 91, 263, 2, 2, 265, 2, 2, 267, 2, 2, 269, 2, 2, 271, 2, 2, 273, 2, 2, 275, 2, 2, 277, 2, 92, 279, 2, 93, 281, 2, 94, 283, 2, 2, 285, 2, 2, 287, 2, 2, 289, 2, 2, 291, 2, 95, 293, 2, 96, 295, 2, 97, 297, 2, 2, 299, 2, 98, 301, 2, 99, 303, 2, 100, 305, 2, 101, 307, 2, 102, 309, 2, 2, 311, 2, 103, 313, 2, 104, 315, 2, 105, 317, 2, 106, 319, 2, 107, 321, 2, 2, 323, 2, 2, 325, 2, 2, 327, 2, 2, 329, 2, 2, 331, 2, 2, 333, 2, 2, 335, 2, 2, 337, 2, 2, 339, 2, 2, 341, 2, 2, 343, 2, 2, 345, 2, 2, 347, 2, 2, 349, 2, 2, 351, 2, 2, 353, 2, 2, 355, 2, 2, 357, 2, 2, 359, 2, 2, 361, 2, 2, 363, 2, 2, 365, 2, 2, 367, 2, 2, 369, 2, 2, 371, 2, 2, 13, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 40, 8, 2, 11, 12, 15, 15, 34, 34, 49, 49, 93, 93, 95, 95, 4, 2, 12, 12, 15, 15, 5, 2, 11, 12, 15, 15, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 36, 36, 94, 94, 112, 112, 116, 116, 118, 118, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 3, 2, 98, 98, 12, 2, 11, 12, 15, 15, 34, 34, 46, 46, 49, 49, 63, 63, 93, 93, 95, 95, 98, 98, 126, 126, 4, 2, 44, 44, 49, 49, 13, 2, 11, 12, 15, 15, 34, 34, 36, 37, 46, 46, 49, 49, 60, 60, 62, 62, 64, 65, 94, 94, 126, 126, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 1268, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 3, 57, 3, 2, 2, 2, 3, 59, 3, 2, 2, 2, 3, 61, 3, 2, 2, 2, 3, 63, 3, 2, 2, 2, 3, 65, 3, 2, 2, 2, 4, 67, 3, 2, 2, 2, 4, 89, 3, 2, 2, 2, 4, 91, 3, 2, 2, 2, 4, 93, 3, 2, 2, 2, 4, 95, 3, 2, 2, 2, 4, 97, 3, 2, 2, 2, 4, 99, 3, 2, 2, 2, 4, 101, 3, 2, 2, 2, 4, 103, 3, 2, 2, 2, 4, 105, 3, 2, 2, 2, 4, 107, 3, 2, 2, 2, 4, 109, 3, 2, 2, 2, 4, 111, 3, 2, 2, 2, 4, 113, 3, 2, 2, 2, 4, 115, 3, 2, 2, 2, 4, 117, 3, 2, 2, 2, 4, 119, 3, 2, 2, 2, 4, 121, 3, 2, 2, 2, 4, 123, 3, 2, 2, 2, 4, 125, 3, 2, 2, 2, 4, 127, 3, 2, 2, 2, 4, 129, 3, 2, 2, 2, 4, 131, 3, 2, 2, 2, 4, 133, 3, 2, 2, 2, 4, 135, 3, 2, 2, 2, 4, 137, 3, 2, 2, 2, 4, 139, 3, 2, 2, 2, 4, 141, 3, 2, 2, 2, 4, 143, 3, 2, 2, 2, 4, 145, 3, 2, 2, 2, 4, 147, 3, 2, 2, 2, 4, 149, 3, 2, 2, 2, 4, 151, 3, 2, 2, 2, 4, 153, 3, 2, 2, 2, 4, 155, 3, 2, 2, 2, 4, 157, 3, 2, 2, 2, 4, 159, 3, 2, 2, 2, 4, 161, 3, 2, 2, 2, 4, 163, 3, 2, 2, 2, 4, 165, 3, 2, 2, 2, 4, 167, 3, 2, 2, 2, 4, 169, 3, 2, 2, 2, 4, 171, 3, 2, 2, 2, 4, 173, 3, 2, 2, 2, 4, 175, 3, 2, 2, 2, 5, 177, 3, 2, 2, 2, 5, 179, 3, 2, 2, 2, 5, 181, 3, 2, 2, 2, 5, 183, 3, 2, 2, 2, 5, 185, 3, 2, 2, 2, 5, 187, 3, 2, 2, 2, 5, 191, 3, 2, 2, 2, 5, 193, 3, 2, 2, 2, 5, 195, 3, 2, 2, 2, 5, 197, 3, 2, 2, 2, 5, 199, 3, 2, 2, 2, 6, 201, 3, 2, 2, 2, 6, 203, 3, 2, 2, 2, 6, 205, 3, 2, 2, 2, 6, 209, 3, 2, 2, 2, 6, 211, 3, 2, 2, 2, 6, 213, 3, 2, 2, 2, 6, 215, 3, 2, 2, 2, 6, 217, 3, 2, 2, 2, 6, 219, 3, 2, 2, 2, 7, 221, 3, 2, 2, 2, 7, 223, 3, 2, 2, 2, 7, 225, 3, 2, 2, 2, 7, 227, 3, 2, 2, 2, 7, 229, 3, 2, 2, 2, 7, 231, 3, 2, 2, 2, 7, 233, 3, 2, 2, 2, 7, 235, 3, 2, 2, 2, 7, 237, 3, 2, 2, 2, 7, 239, 3, 2, 2, 2, 8, 241, 3, 2, 2, 2, 8, 243, 3, 2, 2, 2, 8, 245, 3, 2, 2, 2, 8, 247, 3, 2, 2, 2, 8, 251, 3, 2, 2, 2, 8, 253, 3, 2, 2, 2, 8, 255, 3, 2, 2, 2, 8, 257, 3, 2, 2, 2, 8, 259, 3, 2, 2, 2, 8, 261, 3, 2, 2, 2, 9, 263, 3, 2, 2, 2, 9, 265, 3, 2, 2, 2, 9, 267, 3, 2, 2, 2, 9, 269, 3, 2, 2, 2, 9, 271, 3, 2, 2, 2, 9, 273, 3, 2, 2, 2, 9, 275, 3, 2, 2, 2, 9, 277, 3, 2, 2, 2, 9, 279, 3, 2, 2, 2, 9, 281, 3, 2, 2, 2, 10, 283, 3, 2, 2, 2, 10, 285, 3, 2, 2, 2, 10, 287, 3, 2, 2, 2, 10, 289, 3, 2, 2, 2, 10, 291, 3, 2, 2, 2, 10, 293, 3, 2, 2, 2, 10, 295, 3, 2, 2, 2, 11, 297, 3, 2, 2, 2, 11, 299, 3, 2, 2, 2, 11, 301, 3, 2, 2, 2, 11, 303, 3, 2, 2, 2, 11, 305, 3, 2, 2, 2, 11, 307, 3, 2, 2, 2, 12, 309, 3, 2, 2, 2, 12, 311, 3, 2, 2, 2, 12, 313, 3, 2, 2, 2, 12, 315, 3, 2, 2, 2, 12, 317, 3, 2, 2, 2, 12, 319, 3, 2, 2, 2, 13, 373, 3, 2, 2, 2, 15, 383, 3, 2, 2, 2, 17, 390, 3, 2, 2, 2, 19, 399, 3, 2, 2, 2, 21, 406, 3, 2, 2, 2, 23, 416, 3, 2, 2, 2, 25, 423, 3, 2, 2, 2, 27, 430, 3, 2, 2, 2, 29, 444, 3, 2, 2, 2, 31, 451, 3, 2, 2, 2, 33, 459, 3, 2, 2, 2, 35, 471, 3, 2, 2, 2, 37, 481, 3, 2, 2, 2, 39, 490, 3, 2, 2, 2, 41, 496, 3, 2, 2, 2, 43, 503, 3, 2, 2, 2, 45, 510, 3, 2, 2, 2, 47, 518, 3, 2, 2, 2, 49, 527, 3, 2, 2, 2, 51, 533, 3, 2, 2, 2, 53, 550, 3, 2, 2, 2, 55, 566, 3, 2, 2, 2, 57, 572, 3, 2, 2, 2, 59, 577, 3, 2, 2, 2, 61, 582, 3, 2, 2, 2, 63, 586, 3, 2, 2, 2, 65, 590, 3, 2, 2, 2, 67, 594, 3, 2, 2, 2, 69, 598, 3, 2, 2, 2, 71, 600, 3, 2, 2, 2, 73, 602, 3, 2, 2, 2, 75, 605, 3, 2, 2, 2, 77, 607, 3, 2, 2, 2, 79, 616, 3, 2, 2, 2, 81, 618, 3, 2, 2, 2, 83, 623, 3, 2, 2, 2, 85, 625, 3, 2, 2, 2, 87, 630, 3, 2, 2, 2, 89, 661, 3, 2, 2, 2, 91, 664, 3, 2, 2, 2, 93, 710, 3, 2, 2, 2, 95, 712, 3, 2, 2, 2, 97, 715, 3, 2, 2, 2, 99, 719, 3, 2, 2, 2, 101, 723, 3, 2, 2, 2, 103, 725, 3, 2, 2, 2, 105, 727, 3, 2, 2, 2, 107, 732, 3, 2, 2, 2, 109, 734, 3, 2, 2, 2, 111, 740, 3, 2, 2, 2, 113, 746, 3, 2, 2, 2, 115, 751, 3, 2, 2, 2, 117, 753, 3, 2, 2, 2, 119, 756, 3, 2, 2, 2, 121, 759, 3, 2, 2, 2, 123, 764, 3, 2, 2, 2, 125, 768, 3, 2, 2, 2, 127, 773, 3, 2, 2, 2, 129, 779, 3, 2, 2, 2, 131, 782, 3, 2, 2, 2, 133, 784, 3, 2, 2, 2, 135, 790, 3, 2, 2, 2, 137, 792, 3, 2, 2, 2, 139, 797, 3, 2, 2, 2, 141, 800, 3, 2, 2, 2, 143, 803, 3, 2, 2, 2, 145, 806, 3, 2, 2, 2, 147, 808, 3, 2, 2, 2, 149, 811, 3, 2, 2, 2, 151, 813, 3, 2, 2, 2, 153, 816, 3, 2, 2, 2, 155, 818, 3, 2, 2, 2, 157, 820, 3, 2, 2, 2, 159, 822, 3, 2, 2, 2, 161, 824, 3, 2, 2, 2, 163, 826, 3, 2, 2, 2, 165, 831, 3, 2, 2, 2, 167, 852, 3, 2, 2, 2, 169, 854, 3, 2, 2, 2, 171, 862, 3, 2, 2, 2, 173, 866, 3, 2, 2, 2, 175, 870, 3, 2, 2, 2, 177, 874, 3, 2, 2, 2, 179, 879, 3, 2, 2, 2, 181, 883, 3, 2, 2, 2, 183, 887, 3, 2, 2, 2, 185, 891, 3, 2, 2, 2, 187, 895, 3, 2, 2, 2, 189, 907, 3, 2, 2, 2, 191, 910, 3, 2, 2, 2, 193, 914, 3, 2, 2, 2, 195, 918, 3, 2, 2, 2, 197, 922, 3, 2, 2, 2, 199, 926, 3, 2, 2, 2, 201, 930, 3, 2, 2, 2, 203, 935, 3, 2, 2, 2, 205, 939, 3, 2, 2, 2, 207, 947, 3, 2, 2, 2, 209, 968, 3, 2, 2, 2, 211, 970, 3, 2, 2, 2, 213, 974, 3, 2, 2, 2, 215, 978, 3, 2, 2, 2, 217, 982, 3, 2, 2, 2, 219, 986, 3, 2, 2, 2, 221, 990, 3, 2, 2, 2, 223, 995, 3, 2, 2, 2, 225, 999, 3, 2, 2, 2, 227, 1003, 3, 2, 2, 2, 229, 1007, 3, 2, 2, 2, 231, 1010, 3, 2, 2, 2, 233, 1014, 3, 2, 2, 2, 235, 1018, 3, 2, 2, 2, 237, 1022, 3, 2, 2, 2, 239, 1026, 3, 2, 2, 2, 241, 1030, 3, 2, 2, 2, 243, 1035, 3, 2, 2, 2, 245, 1040, 3, 2, 2, 2, 247, 1045, 3, 2, 2, 2, 249, 1052, 3, 2, 2, 2, 251, 1056, 3, 2, 2, 2, 253, 1064, 3, 2, 2, 2, 255, 1068, 3, 2, 2, 2, 257, 1072, 3, 2, 2, 2, 259, 1076, 3, 2, 2, 2, 261, 1080, 3, 2, 2, 2, 263, 1084, 3, 2, 2, 2, 265, 1090, 3, 2, 2, 2, 267, 1094, 3, 2, 2, 2, 269, 1098, 3, 2, 2, 2, 271, 1102, 3, 2, 2, 2, 273, 1106, 3, 2, 2, 2, 275, 1110, 3, 2, 2, 2, 277, 1114, 3, 2, 2, 2, 279, 1118, 3, 2, 2, 2, 281, 1122, 3, 2, 2, 2, 283, 1126, 3, 2, 2, 2, 285, 1131, 3, 2, 2, 2, 287, 1135, 3, 2, 2, 2, 289, 1139, 3, 2, 2, 2, 291, 1143, 3, 2, 2, 2, 293, 1147, 3, 2, 2, 2, 295, 1151, 3, 2, 2, 2, 297, 1155, 3, 2, 2, 2, 299, 1160, 3, 2, 2, 2, 301, 1165, 3, 2, 2, 2, 303, 1175, 3, 2, 2, 2, 305, 1179, 3, 2, 2, 2, 307, 1183, 3, 2, 2, 2, 309, 1187, 3, 2, 2, 2, 311, 1192, 3, 2, 2, 2, 313, 1199, 3, 2, 2, 2, 315, 1203, 3, 2, 2, 2, 317, 1207, 3, 2, 2, 2, 319, 1211, 3, 2, 2, 2, 321, 1215, 3, 2, 2, 2, 323, 1217, 3, 2, 2, 2, 325, 1219, 3, 2, 2, 2, 327, 1221, 3, 2, 2, 2, 329, 1223, 3, 2, 2, 2, 331, 1225, 3, 2, 2, 2, 333, 1227, 3, 2, 2, 2, 335, 1229, 3, 2, 2, 2, 337, 1231, 3, 2, 2, 2, 339, 1233, 3, 2, 2, 2, 341, 1235, 3, 2, 2, 2, 343, 1237, 3, 2, 2, 2, 345, 1239, 3, 2, 2, 2, 347, 1241, 3, 2, 2, 2, 349, 1243, 3, 2, 2, 2, 351, 1245, 3, 2, 2, 2, 353, 1247, 3, 2, 2, 2, 355, 1249, 3, 2, 2, 2, 357, 1251, 3, 2, 2, 2, 359, 1253, 3, 2, 2, 2, 361, 1255, 3, 2, 2, 2, 363, 1257, 3, 2, 2, 2, 365, 1259, 3, 2, 2, 2, 367, 1261, 3, 2, 2, 2, 369, 1263, 3, 2, 2, 2, 371, 1265, 3, 2, 2, 2, 373, 374, 5, 327, 159, 2, 374, 375, 5, 337, 164, 2, 375, 376, 5, 357, 174, 2, 376, 377, 5, 357, 174, 2, 377, 378, 5, 329, 160, 2, 378, 379, 5, 325, 158, 2, 379, 380, 5, 359, 175, 2, 380, 381, 3, 2, 2, 2, 381, 382, 8, 2, 2, 2, 382, 14, 3, 2, 2, 2, 383, 384, 5, 327, 159, 2, 384, 385, 5, 355, 173, 2, 385, 386, 5, 349, 170, 2, 386, 387, 5, 351, 171, 2, 387, 388, 3, 2, 2, 2, 388, 389, 8, 3, 3, 2, 389, 16, 3, 2, 2, 2, 390, 391, 5, 329, 160, 2, 391, 392, 5, 347, 169, 2, 392, 393, 5, 355, 173, 2, 393, 394, 5, 337, 164, 2, 394, 395, 5, 325, 158, 2, 395, 396, 5, 335, 163, 2, 396, 397, 3, 2, 2, 2, 397, 398, 8, 4, 4, 2, 398, 18, 3, 2, 2, 2, 399, 400, 5, 329, 160, 2, 400, 401, 5, 363, 177, 2, 401, 402, 5, 321, 156, 2, 402, 403, 5, 343, 167, 2, 403, 404, 3, 2, 2, 2, 404, 405, 8, 5, 2, 2, 405, 20, 3, 2, 2, 2, 406, 407, 5, 329, 160, 2, 407, 408, 5, 367, 179, 2, 408, 409, 5, 351, 171, 2, 409, 410, 5, 343, 167, 2, 410, 411, 5, 321, 156, 2, 411, 412, 5, 337, 164, 2, 412, 413, 5, 347, 169, 2, 413, 414, 3, 2, 2, 2, 414, 415, 8, 6, 5, 2, 415, 22, 3, 2, 2, 2, 416, 417, 5, 331, 161, 2, 417, 418, 5, 355, 173, 2, 418, 419, 5, 349, 170, 2, 419, 420, 5, 345, 168, 2, 420, 421, 3, 2, 2, 2, 421, 422, 8, 7, 6, 2, 422, 24, 3, 2, 2, 2, 423, 424, 5, 333, 162, 2, 424, 425, 5, 355, 173, 2, 425, 426, 5, 349, 170, 2, 426, 427, 5, 341, 166, 2, 427, 428, 3, 2, 2, 2, 428, 429, 8, 8, 2, 2, 429, 26, 3, 2, 2, 2, 430, 431, 5, 337, 164, 2, 431, 432, 5, 347, 169, 2, 432, 433, 5, 343, 167, 2, 433, 434, 5, 337, 164, 2, 434, 435, 5, 347, 169, 2, 435, 436, 5, 329, 160, 2, 436, 437, 5, 357, 174, 2, 437, 438, 5, 359, 175, 2, 438, 439, 5, 321, 156, 2, 439, 440, 5, 359, 175, 2, 440, 441, 5, 357, 174, 2, 441, 442, 3, 2, 2, 2, 442, 443, 8, 9, 2, 2, 443, 28, 3, 2, 2, 2, 444, 445, 5, 341, 166, 2, 445, 446, 5, 329, 160, 2, 446, 447, 5, 329, 160, 2, 447, 448, 5, 351, 171, 2, 448, 449, 3, 2, 2, 2, 449, 450, 8, 10, 3, 2, 450, 30, 3, 2, 2, 2, 451, 452, 5, 343, 167, 2, 452, 453, 5, 337, 164, 2, 453, 454, 5, 345, 168, 2, 454, 455, 5, 337, 164, 2, 455, 456, 5, 359, 175, 2, 456, 457, 3, 2, 2, 2, 457, 458, 8, 11, 2, 2, 458, 32, 3, 2, 2, 2, 459, 460, 5, 345, 168, 2, 460, 461, 5, 363, 177, 2, 461, 462, 5, 85, 38, 2, 462, 463, 5, 329, 160, 2, 463, 464, 5, 367, 179, 2, 464, 465, 5, 351, 171, 2, 465, 466, 5, 321, 156, 2, 466, 467, 5, 347, 169, 2, 467, 468, 5, 327, 159, 2, 468, 469, 3, 2, 2, 2, 469, 470, 8, 12, 7, 2, 470, 34, 3, 2, 2, 2, 471, 472, 5, 351, 171, 2, 472, 473, 5, 355, 173, 2, 473, 474, 5, 349, 170, 2, 474, 475, 5, 339, 165, 2, 475, 476, 5, 329, 160, 2, 476, 477, 5, 325, 158, 2, 477, 478, 5, 359, 175, 2, 478, 479, 3, 2, 2, 2, 479, 480, 8, 13, 3, 2, 480, 36, 3, 2, 2, 2, 481, 482, 5, 355, 173, 2, 482, 483, 5, 329, 160, 2, 483, 484, 5, 347, 169, 2, 484, 485, 5, 321, 156, 2, 485, 486, 5, 345, 168, 2, 486, 487, 5, 329, 160, 2, 487, 488, 3, 2, 2, 2, 488, 489, 8, 14, 8, 2, 489, 38, 3, 2, 2, 2, 490, 491, 5, 355, 173, 2, 491, 492, 5, 349, 170, 2, 492, 493, 5, 365, 178, 2, 493, 494, 3, 2, 2, 2, 494, 495, 8, 15, 2, 2, 495, 40, 3, 2, 2, 2, 496, 497, 5, 357, 174, 2, 497, 498, 5, 335, 163, 2, 498, 499, 5, 349, 170, 2, 499, 500, 5, 365, 178, 2, 500, 501, 3, 2, 2, 2, 501, 502, 8, 16, 9, 2, 502, 42, 3, 2, 2, 2, 503, 504, 5, 357, 174, 2, 504, 505, 5, 349, 170, 2, 505, 506, 5, 355, 173, 2, 506, 507, 5, 359, 175, 2, 507, 508, 3, 2, 2, 2, 508, 509, 8, 17, 2, 2, 509, 44, 3, 2, 2, 2, 510, 511, 5, 357, 174, 2, 511, 512, 5, 359, 175, 2, 512, 513, 5, 321, 156, 2, 513, 514, 5, 359, 175, 2, 514, 515, 5, 357, 174, 2, 515, 516, 3, 2, 2, 2, 516, 517, 8, 18, 2, 2, 517, 46, 3, 2, 2, 2, 518, 519, 5, 365, 178, 2, 519, 520, 5, 335, 163, 2, 520, 521, 5, 329, 160, 2, 521, 522, 5, 355, 173, 2, 522, 523, 5, 329, 160, 2, 523, 524, 3, 2, 2, 2, 524, 525, 8, 19, 2, 2, 525, 48, 3, 2, 2, 2, 526, 528, 10, 2, 2, 2, 527, 526, 3, 2, 2, 2, 528, 529, 3, 2, 2, 2, 529, 527, 3, 2, 2, 2, 529, 530, 3, 2, 2, 2, 530, 531, 3, 2, 2, 2, 531, 532, 8, 20, 2, 2, 532, 50, 3, 2, 2, 2, 533, 534, 7, 49, 2, 2, 534, 535, 7, 49, 2, 2, 535, 539, 3, 2, 2, 2, 536, 538, 10, 3, 2, 2, 537, 536, 3, 2, 2, 2, 538, 541, 3, 2, 2, 2, 539, 537, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 543, 3, 2, 2, 2, 541, 539, 3, 2, 2, 2, 542, 544, 7, 15, 2, 2, 543, 542, 3, 2, 2, 2, 543, 544, 3, 2, 2, 2, 544, 546, 3, 2, 2, 2, 545, 547, 7, 12, 2, 2, 546, 545, 3, 2, 2, 2, 546, 547, 3, 2, 2, 2, 547, 548, 3, 2, 2, 2, 548, 549, 8, 21, 10, 2, 549, 52, 3, 2, 2, 2, 550, 551, 7, 49, 2, 2, 551, 552, 7, 44, 2, 2, 552, 557, 3, 2, 2, 2, 553, 556, 5, 53, 22, 2, 554, 556, 11, 2, 2, 2, 555, 553, 3, 2, 2, 2, 555, 554, 3, 2, 2, 2, 556, 559, 3, 2, 2, 2, 557, 558, 3, 2, 2, 2, 557, 555, 3, 2, 2, 2, 558, 560, 3, 2, 2, 2, 559, 557, 3, 2, 2, 2, 560, 561, 7, 44, 2, 2, 561, 562, 7, 49, 2, 2, 562, 563, 3, 2, 2, 2, 563, 564, 8, 22, 10, 2, 564, 54, 3, 2, 2, 2, 565, 567, 9, 4, 2, 2, 566, 565, 3, 2, 2, 2, 567, 568, 3, 2, 2, 2, 568, 566, 3, 2, 2, 2, 568, 569, 3, 2, 2, 2, 569, 570, 3, 2, 2, 2, 570, 571, 8, 23, 10, 2, 571, 56, 3, 2, 2, 2, 572, 573, 5, 163, 77, 2, 573, 574, 3, 2, 2, 2, 574, 575, 8, 24, 11, 2, 575, 576, 8, 24, 12, 2, 576, 58, 3, 2, 2, 2, 577, 578, 5, 67, 29, 2, 578, 579, 3, 2, 2, 2, 579, 580, 8, 25, 13, 2, 580, 581, 8, 25, 14, 2, 581, 60, 3, 2, 2, 2, 582, 583, 5, 55, 23, 2, 583, 584, 3, 2, 2, 2, 584, 585, 8, 26, 10, 2, 585, 62, 3, 2, 2, 2, 586, 587, 5, 51, 21, 2, 587, 588, 3, 2, 2, 2, 588, 589, 8, 27, 10, 2, 589, 64, 3, 2, 2, 2, 590, 591, 5, 53, 22, 2, 591, 592, 3, 2, 2, 2, 592, 593, 8, 28, 10, 2, 593, 66, 3, 2, 2, 2, 594, 595, 7, 126, 2, 2, 595, 596, 3, 2, 2, 2, 596, 597, 8, 29, 14, 2, 597, 68, 3, 2, 2, 2, 598, 599, 9, 5, 2, 2, 599, 70, 3, 2, 2, 2, 600, 601, 9, 6, 2, 2, 601, 72, 3, 2, 2, 2, 602, 603, 7, 94, 2, 2, 603, 604, 9, 7, 2, 2, 604, 74, 3, 2, 2, 2, 605, 606, 10, 8, 2, 2, 606, 76, 3, 2, 2, 2, 607, 609, 9, 9, 2, 2, 608, 610, 9, 10, 2, 2, 609, 608, 3, 2, 2, 2, 609, 610, 3, 2, 2, 2, 610, 612, 3, 2, 2, 2, 611, 613, 5, 69, 30, 2, 612, 611, 3, 2, 2, 2, 613, 614, 3, 2, 2, 2, 614, 612, 3, 2, 2, 2, 614, 615, 3, 2, 2, 2, 615, 78, 3, 2, 2, 2, 616, 617, 7, 66, 2, 2, 617, 80, 3, 2, 2, 2, 618, 619, 7, 98, 2, 2, 619, 82, 3, 2, 2, 2, 620, 624, 10, 11, 2, 2, 621, 622, 7, 98, 2, 2, 622, 624, 7, 98, 2, 2, 623, 620, 3, 2, 2, 2, 623, 621, 3, 2, 2, 2, 624, 84, 3, 2, 2, 2, 625, 626, 7, 97, 2, 2, 626, 86, 3, 2, 2, 2, 627, 631, 5, 71, 31, 2, 628, 631, 5, 69, 30, 2, 629, 631, 5, 85, 38, 2, 630, 627, 3, 2, 2, 2, 630, 628, 3, 2, 2, 2, 630, 629, 3, 2, 2, 2, 631, 88, 3, 2, 2, 2, 632, 637, 7, 36, 2, 2, 633, 636, 5, 73, 32, 2, 634, 636, 5, 75, 33, 2, 635, 633, 3, 2, 2, 2, 635, 634, 3, 2, 2, 2, 636, 639, 3, 2, 2, 2, 637, 635, 3, 2, 2, 2, 637, 638, 3, 2, 2, 2, 638, 640, 3, 2, 2, 2, 639, 637, 3, 2, 2, 2, 640, 662, 7, 36, 2, 2, 641, 642, 7, 36, 2, 2, 642, 643, 7, 36, 2, 2, 643, 644, 7, 36, 2, 2, 644, 648, 3, 2, 2, 2, 645, 647, 10, 3, 2, 2, 646, 645, 3, 2, 2, 2, 647, 650, 3, 2, 2, 2, 648, 649, 3, 2, 2, 2, 648, 646, 3, 2, 2, 2, 649, 651, 3, 2, 2, 2, 650, 648, 3, 2, 2, 2, 651, 652, 7, 36, 2, 2, 652, 653, 7, 36, 2, 2, 653, 654, 7, 36, 2, 2, 654, 656, 3, 2, 2, 2, 655, 657, 7, 36, 2, 2, 656, 655, 3, 2, 2, 2, 656, 657, 3, 2, 2, 2, 657, 659, 3, 2, 2, 2, 658, 660, 7, 36, 2, 2, 659, 658, 3, 2, 2, 2, 659, 660, 3, 2, 2, 2, 660, 662, 3, 2, 2, 2, 661, 632, 3, 2, 2, 2, 661, 641, 3, 2, 2, 2, 662, 90, 3, 2, 2, 2, 663, 665, 5, 69, 30, 2, 664, 663, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 666, 664, 3, 2, 2, 2, 666, 667, 3, 2, 2, 2, 667, 92, 3, 2, 2, 2, 668, 670, 5, 69, 30, 2, 669, 668, 3, 2, 2, 2, 670, 671, 3, 2, 2, 2, 671, 669, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, 672, 673, 3, 2, 2, 2, 673, 677, 5, 107, 49, 2, 674, 676, 5, 69, 30, 2, 675, 674, 3, 2, 2, 2, 676, 679, 3, 2, 2, 2, 677, 675, 3, 2, 2, 2, 677, 678, 3, 2, 2, 2, 678, 711, 3, 2, 2, 2, 679, 677, 3, 2, 2, 2, 680, 682, 5, 107, 49, 2, 681, 683, 5, 69, 30, 2, 682, 681, 3, 2, 2, 2, 683, 684, 3, 2, 2, 2, 684, 682, 3, 2, 2, 2, 684, 685, 3, 2, 2, 2, 685, 711, 3, 2, 2, 2, 686, 688, 5, 69, 30, 2, 687, 686, 3, 2, 2, 2, 688, 689, 3, 2, 2, 2, 689, 687, 3, 2, 2, 2, 689, 690, 3, 2, 2, 2, 690, 698, 3, 2, 2, 2, 691, 695, 5, 107, 49, 2, 692, 694, 5, 69, 30, 2, 693, 692, 3, 2, 2, 2, 694, 697, 3, 2, 2, 2, 695, 693, 3, 2, 2, 2, 695, 696, 3, 2, 2, 2, 696, 699, 3, 2, 2, 2, 697, 695, 3, 2, 2, 2, 698, 691, 3, 2, 2, 2, 698, 699, 3, 2, 2, 2, 699, 700, 3, 2, 2, 2, 700, 701, 5, 77, 34, 2, 701, 711, 3, 2, 2, 2, 702, 704, 5, 107, 49, 2, 703, 705, 5, 69, 30, 2, 704, 703, 3, 2, 2, 2, 705, 706, 3, 2, 2, 2, 706, 704, 3, 2, 2, 2, 706, 707, 3, 2, 2, 2, 707, 708, 3, 2, 2, 2, 708, 709, 5, 77, 34, 2, 709, 711, 3, 2, 2, 2, 710, 669, 3, 2, 2, 2, 710, 680, 3, 2, 2, 2, 710, 687, 3, 2, 2, 2, 710, 702, 3, 2, 2, 2, 711, 94, 3, 2, 2, 2, 712, 713, 5, 323, 157, 2, 713, 714, 5, 369, 180, 2, 714, 96, 3, 2, 2, 2, 715, 716, 5, 321, 156, 2, 716, 717, 5, 347, 169, 2, 717, 718, 5, 327, 159, 2, 718, 98, 3, 2, 2, 2, 719, 720, 5, 321, 156, 2, 720, 721, 5, 357, 174, 2, 721, 722, 5, 325, 158, 2, 722, 100, 3, 2, 2, 2, 723, 724, 7, 63, 2, 2, 724, 102, 3, 2, 2, 2, 725, 726, 7, 46, 2, 2, 726, 104, 3, 2, 2, 2, 727, 728, 5, 327, 159, 2, 728, 729, 5, 329, 160, 2, 729, 730, 5, 357, 174, 2, 730, 731, 5, 325, 158, 2, 731, 106, 3, 2, 2, 2, 732, 733, 7, 48, 2, 2, 733, 108, 3, 2, 2, 2, 734, 735, 5, 331, 161, 2, 735, 736, 5, 321, 156, 2, 736, 737, 5, 343, 167, 2, 737, 738, 5, 357, 174, 2, 738, 739, 5, 329, 160, 2, 739, 110, 3, 2, 2, 2, 740, 741, 5, 331, 161, 2, 741, 742, 5, 337, 164, 2, 742, 743, 5, 355, 173, 2, 743, 744, 5, 357, 174, 2, 744, 745, 5, 359, 175, 2, 745, 112, 3, 2, 2, 2, 746, 747, 5, 343, 167, 2, 747, 748, 5, 321, 156, 2, 748, 749, 5, 357, 174, 2, 749, 750, 5, 359, 175, 2, 750, 114, 3, 2, 2, 2, 751, 752, 7, 42, 2, 2, 752, 116, 3, 2, 2, 2, 753, 754, 5, 337, 164, 2, 754, 755, 5, 347, 169, 2, 755, 118, 3, 2, 2, 2, 756, 757, 5, 337, 164, 2, 757, 758, 5, 357, 174, 2, 758, 120, 3, 2, 2, 2, 759, 760, 5, 343, 167, 2, 760, 761, 5, 337, 164, 2, 761, 762, 5, 341, 166, 2, 762, 763, 5, 329, 160, 2, 763, 122, 3, 2, 2, 2, 764, 765, 5, 347, 169, 2, 765, 766, 5, 349, 170, 2, 766, 767, 5, 359, 175, 2, 767, 124, 3, 2, 2, 2, 768, 769, 5, 347, 169, 2, 769, 770, 5, 361, 176, 2, 770, 771, 5, 343, 167, 2, 771, 772, 5, 343, 167, 2, 772, 126, 3, 2, 2, 2, 773, 774, 5, 347, 169, 2, 774, 775, 5, 361, 176, 2, 775, 776, 5, 343, 167, 2, 776, 777, 5, 343, 167, 2, 777, 778, 5, 357, 174, 2, 778, 128, 3, 2, 2, 2, 779, 780, 5, 349, 170, 2, 780, 781, 5, 355, 173, 2, 781, 130, 3, 2, 2, 2, 782, 783, 7, 65, 2, 2, 783, 132, 3, 2, 2, 2, 784, 785, 5, 355, 173, 2, 785, 786, 5, 343, 167, 2, 786, 787, 5, 337, 164, 2, 787, 788, 5, 341, 166, 2, 788, 789, 5, 329, 160, 2, 789, 134, 3, 2, 2, 2, 790, 791, 7, 43, 2, 2, 791, 136, 3, 2, 2, 2, 792, 793, 5, 359, 175, 2, 793, 794, 5, 355, 173, 2, 794, 795, 5, 361, 176, 2, 795, 796, 5, 329, 160, 2, 796, 138, 3, 2, 2, 2, 797, 798, 7, 63, 2, 2, 798, 799, 7, 63, 2, 2, 799, 140, 3, 2, 2, 2, 800, 801, 7, 63, 2, 2, 801, 802, 7, 128, 2, 2, 802, 142, 3, 2, 2, 2, 803, 804, 7, 35, 2, 2, 804, 805, 7, 63, 2, 2, 805, 144, 3, 2, 2, 2, 806, 807, 7, 62, 2, 2, 807, 146, 3, 2, 2, 2, 808, 809, 7, 62, 2, 2, 809, 810, 7, 63, 2, 2, 810, 148, 3, 2, 2, 2, 811, 812, 7, 64, 2, 2, 812, 150, 3, 2, 2, 2, 813, 814, 7, 64, 2, 2, 814, 815, 7, 63, 2, 2, 815, 152, 3, 2, 2, 2, 816, 817, 7, 45, 2, 2, 817, 154, 3, 2, 2, 2, 818, 819, 7, 47, 2, 2, 819, 156, 3, 2, 2, 2, 820, 821, 7, 44, 2, 2, 821, 158, 3, 2, 2, 2, 822, 823, 7, 49, 2, 2, 823, 160, 3, 2, 2, 2, 824, 825, 7, 39, 2, 2, 825, 162, 3, 2, 2, 2, 826, 827, 7, 93, 2, 2, 827, 828, 3, 2, 2, 2, 828, 829, 8, 77, 2, 2, 829, 830, 8, 77, 2, 2, 830, 164, 3, 2, 2, 2, 831, 832, 7, 95, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 8, 78, 14, 2, 834, 835, 8, 78, 14, 2, 835, 166, 3, 2, 2, 2, 836, 840, 5, 71, 31, 2, 837, 839, 5, 87, 39, 2, 838, 837, 3, 2, 2, 2, 839, 842, 3, 2, 2, 2, 840, 838, 3, 2, 2, 2, 840, 841, 3, 2, 2, 2, 841, 853, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 843, 846, 5, 85, 38, 2, 844, 846, 5, 79, 35, 2, 845, 843, 3, 2, 2, 2, 845, 844, 3, 2, 2, 2, 846, 848, 3, 2, 2, 2, 847, 849, 5, 87, 39, 2, 848, 847, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 848, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 853, 3, 2, 2, 2, 852, 836, 3, 2, 2, 2, 852, 845, 3, 2, 2, 2, 853, 168, 3, 2, 2, 2, 854, 856, 5, 81, 36, 2, 855, 857, 5, 83, 37, 2, 856, 855, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 856, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 3, 2, 2, 2, 860, 861, 5, 81, 36, 2, 861, 170, 3, 2, 2, 2, 862, 863, 5, 51, 21, 2, 863, 864, 3, 2, 2, 2, 864, 865, 8, 81, 10, 2, 865, 172, 3, 2, 2, 2, 866, 867, 5, 53, 22, 2, 867, 868, 3, 2, 2, 2, 868, 869, 8, 82, 10, 2, 869, 174, 3, 2, 2, 2, 870, 871, 5, 55, 23, 2, 871, 872, 3, 2, 2, 2, 872, 873, 8, 83, 10, 2, 873, 176, 3, 2, 2, 2, 874, 875, 5, 67, 29, 2, 875, 876, 3, 2, 2, 2, 876, 877, 8, 84, 13, 2, 877, 878, 8, 84, 14, 2, 878, 178, 3, 2, 2, 2, 879, 880, 5, 163, 77, 2, 880, 881, 3, 2, 2, 2, 881, 882, 8, 85, 11, 2, 882, 180, 3, 2, 2, 2, 883, 884, 5, 165, 78, 2, 884, 885, 3, 2, 2, 2, 885, 886, 8, 86, 15, 2, 886, 182, 3, 2, 2, 2, 887, 888, 5, 103, 47, 2, 888, 889, 3, 2, 2, 2, 889, 890, 8, 87, 16, 2, 890, 184, 3, 2, 2, 2, 891, 892, 5, 101, 46, 2, 892, 893, 3, 2, 2, 2, 893, 894, 8, 88, 17, 2, 894, 186, 3, 2, 2, 2, 895, 896, 5, 345, 168, 2, 896, 897, 5, 329, 160, 2, 897, 898, 5, 359, 175, 2, 898, 899, 5, 321, 156, 2, 899, 900, 5, 327, 159, 2, 900, 901, 5, 321, 156, 2, 901, 902, 5, 359, 175, 2, 902, 903, 5, 321, 156, 2, 903, 188, 3, 2, 2, 2, 904, 908, 10, 12, 2, 2, 905, 906, 7, 49, 2, 2, 906, 908, 10, 13, 2, 2, 907, 904, 3, 2, 2, 2, 907, 905, 3, 2, 2, 2, 908, 190, 3, 2, 2, 2, 909, 911, 5, 189, 90, 2, 910, 909, 3, 2, 2, 2, 911, 912, 3, 2, 2, 2, 912, 910, 3, 2, 2, 2, 912, 913, 3, 2, 2, 2, 913, 192, 3, 2, 2, 2, 914, 915, 5, 169, 80, 2, 915, 916, 3, 2, 2, 2, 916, 917, 8, 92, 18, 2, 917, 194, 3, 2, 2, 2, 918, 919, 5, 51, 21, 2, 919, 920, 3, 2, 2, 2, 920, 921, 8, 93, 10, 2, 921, 196, 3, 2, 2, 2, 922, 923, 5, 53, 22, 2, 923, 924, 3, 2, 2, 2, 924, 925, 8, 94, 10, 2, 925, 198, 3, 2, 2, 2, 926, 927, 5, 55, 23, 2, 927, 928, 3, 2, 2, 2, 928, 929, 8, 95, 10, 2, 929, 200, 3, 2, 2, 2, 930, 931, 5, 67, 29, 2, 931, 932, 3, 2, 2, 2, 932, 933, 8, 96, 13, 2, 933, 934, 8, 96, 14, 2, 934, 202, 3, 2, 2, 2, 935, 936, 5, 107, 49, 2, 936, 937, 3, 2, 2, 2, 937, 938, 8, 97, 19, 2, 938, 204, 3, 2, 2, 2, 939, 940, 5, 103, 47, 2, 940, 941, 3, 2, 2, 2, 941, 942, 8, 98, 16, 2, 942, 206, 3, 2, 2, 2, 943, 948, 5, 71, 31, 2, 944, 948, 5, 69, 30, 2, 945, 948, 5, 85, 38, 2, 946, 948, 5, 157, 74, 2, 947, 943, 3, 2, 2, 2, 947, 944, 3, 2, 2, 2, 947, 945, 3, 2, 2, 2, 947, 946, 3, 2, 2, 2, 948, 208, 3, 2, 2, 2, 949, 952, 5, 71, 31, 2, 950, 952, 5, 157, 74, 2, 951, 949, 3, 2, 2, 2, 951, 950, 3, 2, 2, 2, 952, 956, 3, 2, 2, 2, 953, 955, 5, 207, 99, 2, 954, 953, 3, 2, 2, 2, 955, 958, 3, 2, 2, 2, 956, 954, 3, 2, 2, 2, 956, 957, 3, 2, 2, 2, 957, 969, 3, 2, 2, 2, 958, 956, 3, 2, 2, 2, 959, 962, 5, 85, 38, 2, 960, 962, 5, 79, 35, 2, 961, 959, 3, 2, 2, 2, 961, 960, 3, 2, 2, 2, 962, 964, 3, 2, 2, 2, 963, 965, 5, 207, 99, 2, 964, 963, 3, 2, 2, 2, 965, 966, 3, 2, 2, 2, 966, 964, 3, 2, 2, 2, 966, 967, 3, 2, 2, 2, 967, 969, 3, 2, 2, 2, 968, 951, 3, 2, 2, 2, 968, 961, 3, 2, 2, 2, 969, 210, 3, 2, 2, 2, 970, 971, 5, 209, 100, 2, 971, 972, 3, 2, 2, 2, 972, 973, 8, 101, 20, 2, 973, 212, 3, 2, 2, 2, 974, 975, 5, 169, 80, 2, 975, 976, 3, 2, 2, 2, 976, 977, 8, 102, 18, 2, 977, 214, 3, 2, 2, 2, 978, 979, 5, 51, 21, 2, 979, 980, 3, 2, 2, 2, 980, 981, 8, 103, 10, 2, 981, 216, 3, 2, 2, 2, 982, 983, 5, 53, 22, 2, 983, 984, 3, 2, 2, 2, 984, 985, 8, 104, 10, 2, 985, 218, 3, 2, 2, 2, 986, 987, 5, 55, 23, 2, 987, 988, 3, 2, 2, 2, 988, 989, 8, 105, 10, 2, 989, 220, 3, 2, 2, 2, 990, 991, 5, 67, 29, 2, 991, 992, 3, 2, 2, 2, 992, 993, 8, 106, 13, 2, 993, 994, 8, 106, 14, 2, 994, 222, 3, 2, 2, 2, 995, 996, 5, 101, 46, 2, 996, 997, 3, 2, 2, 2, 997, 998, 8, 107, 17, 2, 998, 224, 3, 2, 2, 2, 999, 1000, 5, 103, 47, 2, 1000, 1001, 3, 2, 2, 2, 1001, 1002, 8, 108, 16, 2, 1002, 226, 3, 2, 2, 2, 1003, 1004, 5, 107, 49, 2, 1004, 1005, 3, 2, 2, 2, 1005, 1006, 8, 109, 19, 2, 1006, 228, 3, 2, 2, 2, 1007, 1008, 5, 321, 156, 2, 1008, 1009, 5, 357, 174, 2, 1009, 230, 3, 2, 2, 2, 1010, 1011, 5, 169, 80, 2, 1011, 1012, 3, 2, 2, 2, 1012, 1013, 8, 111, 18, 2, 1013, 232, 3, 2, 2, 2, 1014, 1015, 5, 209, 100, 2, 1015, 1016, 3, 2, 2, 2, 1016, 1017, 8, 112, 20, 2, 1017, 234, 3, 2, 2, 2, 1018, 1019, 5, 51, 21, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1021, 8, 113, 10, 2, 1021, 236, 3, 2, 2, 2, 1022, 1023, 5, 53, 22, 2, 1023, 1024, 3, 2, 2, 2, 1024, 1025, 8, 114, 10, 2, 1025, 238, 3, 2, 2, 2, 1026, 1027, 5, 55, 23, 2, 1027, 1028, 3, 2, 2, 2, 1028, 1029, 8, 115, 10, 2, 1029, 240, 3, 2, 2, 2, 1030, 1031, 5, 67, 29, 2, 1031, 1032, 3, 2, 2, 2, 1032, 1033, 8, 116, 13, 2, 1033, 1034, 8, 116, 14, 2, 1034, 242, 3, 2, 2, 2, 1035, 1036, 5, 163, 77, 2, 1036, 1037, 3, 2, 2, 2, 1037, 1038, 8, 117, 11, 2, 1038, 1039, 8, 117, 21, 2, 1039, 244, 3, 2, 2, 2, 1040, 1041, 5, 349, 170, 2, 1041, 1042, 5, 347, 169, 2, 1042, 1043, 3, 2, 2, 2, 1043, 1044, 8, 118, 22, 2, 1044, 246, 3, 2, 2, 2, 1045, 1046, 5, 365, 178, 2, 1046, 1047, 5, 337, 164, 2, 1047, 1048, 5, 359, 175, 2, 1048, 1049, 5, 335, 163, 2, 1049, 1050, 3, 2, 2, 2, 1050, 1051, 8, 119, 22, 2, 1051, 248, 3, 2, 2, 2, 1052, 1053, 10, 14, 2, 2, 1053, 250, 3, 2, 2, 2, 1054, 1057, 5, 71, 31, 2, 1055, 1057, 5, 69, 30, 2, 1056, 1054, 3, 2, 2, 2, 1056, 1055, 3, 2, 2, 2, 1057, 1061, 3, 2, 2, 2, 1058, 1060, 5, 249, 120, 2, 1059, 1058, 3, 2, 2, 2, 1060, 1063, 3, 2, 2, 2, 1061, 1059, 3, 2, 2, 2, 1061, 1062, 3, 2, 2, 2, 1062, 252, 3, 2, 2, 2, 1063, 1061, 3, 2, 2, 2, 1064, 1065, 5, 169, 80, 2, 1065, 1066, 3, 2, 2, 2, 1066, 1067, 8, 122, 18, 2, 1067, 254, 3, 2, 2, 2, 1068, 1069, 5, 251, 121, 2, 1069, 1070, 3, 2, 2, 2, 1070, 1071, 8, 123, 23, 2, 1071, 256, 3, 2, 2, 2, 1072, 1073, 5, 51, 21, 2, 1073, 1074, 3, 2, 2, 2, 1074, 1075, 8, 124, 10, 2, 1075, 258, 3, 2, 2, 2, 1076, 1077, 5, 53, 22, 2, 1077, 1078, 3, 2, 2, 2, 1078, 1079, 8, 125, 10, 2, 1079, 260, 3, 2, 2, 2, 1080, 1081, 5, 55, 23, 2, 1081, 1082, 3, 2, 2, 2, 1082, 1083, 8, 126, 10, 2, 1083, 262, 3, 2, 2, 2, 1084, 1085, 5, 67, 29, 2, 1085, 1086, 3, 2, 2, 2, 1086, 1087, 8, 127, 13, 2, 1087, 1088, 8, 127, 14, 2, 1088, 1089, 8, 127, 14, 2, 1089, 264, 3, 2, 2, 2, 1090, 1091, 5, 101, 46, 2, 1091, 1092, 3, 2, 2, 2, 1092, 1093, 8, 128, 17, 2, 1093, 266, 3, 2, 2, 2, 1094, 1095, 5, 103, 47, 2, 1095, 1096, 3, 2, 2, 2, 1096, 1097, 8, 129, 16, 2, 1097, 268, 3, 2, 2, 2, 1098, 1099, 5, 107, 49, 2, 1099, 1100, 3, 2, 2, 2, 1100, 1101, 8, 130, 19, 2, 1101, 270, 3, 2, 2, 2, 1102, 1103, 5, 247, 119, 2, 1103, 1104, 3, 2, 2, 2, 1104, 1105, 8, 131, 24, 2, 1105, 272, 3, 2, 2, 2, 1106, 1107, 5, 209, 100, 2, 1107, 1108, 3, 2, 2, 2, 1108, 1109, 8, 132, 20, 2, 1109, 274, 3, 2, 2, 2, 1110, 1111, 5, 169, 80, 2, 1111, 1112, 3, 2, 2, 2, 1112, 1113, 8, 133, 18, 2, 1113, 276, 3, 2, 2, 2, 1114, 1115, 5, 51, 21, 2, 1115, 1116, 3, 2, 2, 2, 1116, 1117, 8, 134, 10, 2, 1117, 278, 3, 2, 2, 2, 1118, 1119, 5, 53, 22, 2, 1119, 1120, 3, 2, 2, 2, 1120, 1121, 8, 135, 10, 2, 1121, 280, 3, 2, 2, 2, 1122, 1123, 5, 55, 23, 2, 1123, 1124, 3, 2, 2, 2, 1124, 1125, 8, 136, 10, 2, 1125, 282, 3, 2, 2, 2, 1126, 1127, 5, 67, 29, 2, 1127, 1128, 3, 2, 2, 2, 1128, 1129, 8, 137, 13, 2, 1129, 1130, 8, 137, 14, 2, 1130, 284, 3, 2, 2, 2, 1131, 1132, 5, 107, 49, 2, 1132, 1133, 3, 2, 2, 2, 1133, 1134, 8, 138, 19, 2, 1134, 286, 3, 2, 2, 2, 1135, 1136, 5, 169, 80, 2, 1136, 1137, 3, 2, 2, 2, 1137, 1138, 8, 139, 18, 2, 1138, 288, 3, 2, 2, 2, 1139, 1140, 5, 167, 79, 2, 1140, 1141, 3, 2, 2, 2, 1141, 1142, 8, 140, 25, 2, 1142, 290, 3, 2, 2, 2, 1143, 1144, 5, 51, 21, 2, 1144, 1145, 3, 2, 2, 2, 1145, 1146, 8, 141, 10, 2, 1146, 292, 3, 2, 2, 2, 1147, 1148, 5, 53, 22, 2, 1148, 1149, 3, 2, 2, 2, 1149, 1150, 8, 142, 10, 2, 1150, 294, 3, 2, 2, 2, 1151, 1152, 5, 55, 23, 2, 1152, 1153, 3, 2, 2, 2, 1153, 1154, 8, 143, 10, 2, 1154, 296, 3, 2, 2, 2, 1155, 1156, 5, 67, 29, 2, 1156, 1157, 3, 2, 2, 2, 1157, 1158, 8, 144, 13, 2, 1158, 1159, 8, 144, 14, 2, 1159, 298, 3, 2, 2, 2, 1160, 1161, 5, 337, 164, 2, 1161, 1162, 5, 347, 169, 2, 1162, 1163, 5, 331, 161, 2, 1163, 1164, 5, 349, 170, 2, 1164, 300, 3, 2, 2, 2, 1165, 1166, 5, 331, 161, 2, 1166, 1167, 5, 361, 176, 2, 1167, 1168, 5, 347, 169, 2, 1168, 1169, 5, 325, 158, 2, 1169, 1170, 5, 359, 175, 2, 1170, 1171, 5, 337, 164, 2, 1171, 1172, 5, 349, 170, 2, 1172, 1173, 5, 347, 169, 2, 1173, 1174, 5, 357, 174, 2, 1174, 302, 3, 2, 2, 2, 1175, 1176, 5, 51, 21, 2, 1176, 1177, 3, 2, 2, 2, 1177, 1178, 8, 147, 10, 2, 1178, 304, 3, 2, 2, 2, 1179, 1180, 5, 53, 22, 2, 1180, 1181, 3, 2, 2, 2, 1181, 1182, 8, 148, 10, 2, 1182, 306, 3, 2, 2, 2, 1183, 1184, 5, 55, 23, 2, 1184, 1185, 3, 2, 2, 2, 1185, 1186, 8, 149, 10, 2, 1186, 308, 3, 2, 2, 2, 1187, 1188, 5, 165, 78, 2, 1188, 1189, 3, 2, 2, 2, 1189, 1190, 8, 150, 15, 2, 1190, 1191, 8, 150, 14, 2, 1191, 310, 3, 2, 2, 2, 1192, 1193, 7, 60, 2, 2, 1193, 312, 3, 2, 2, 2, 1194, 1200, 5, 79, 35, 2, 1195, 1200, 5, 69, 30, 2, 1196, 1200, 5, 107, 49, 2, 1197, 1200, 5, 71, 31, 2, 1198, 1200, 5, 85, 38, 2, 1199, 1194, 3, 2, 2, 2, 1199, 1195, 3, 2, 2, 2, 1199, 1196, 3, 2, 2, 2, 1199, 1197, 3, 2, 2, 2, 1199, 1198, 3, 2, 2, 2, 1200, 1201, 3, 2, 2, 2, 1201, 1199, 3, 2, 2, 2, 1201, 1202, 3, 2, 2, 2, 1202, 314, 3, 2, 2, 2, 1203, 1204, 5, 51, 21, 2, 1204, 1205, 3, 2, 2, 2, 1205, 1206, 8, 153, 10, 2, 1206, 316, 3, 2, 2, 2, 1207, 1208, 5, 53, 22, 2, 1208, 1209, 3, 2, 2, 2, 1209, 1210, 8, 154, 10, 2, 1210, 318, 3, 2, 2, 2, 1211, 1212, 5, 55, 23, 2, 1212, 1213, 3, 2, 2, 2, 1213, 1214, 8, 155, 10, 2, 1214, 320, 3, 2, 2, 2, 1215, 1216, 9, 15, 2, 2, 1216, 322, 3, 2, 2, 2, 1217, 1218, 9, 16, 2, 2, 1218, 324, 3, 2, 2, 2, 1219, 1220, 9, 17, 2, 2, 1220, 326, 3, 2, 2, 2, 1221, 1222, 9, 18, 2, 2, 1222, 328, 3, 2, 2, 2, 1223, 1224, 9, 9, 2, 2, 1224, 330, 3, 2, 2, 2, 1225, 1226, 9, 19, 2, 2, 1226, 332, 3, 2, 2, 2, 1227, 1228, 9, 20, 2, 2, 1228, 334, 3, 2, 2, 2, 1229, 1230, 9, 21, 2, 2, 1230, 336, 3, 2, 2, 2, 1231, 1232, 9, 22, 2, 2, 1232, 338, 3, 2, 2, 2, 1233, 1234, 9, 23, 2, 2, 1234, 340, 3, 2, 2, 2, 1235, 1236, 9, 24, 2, 2, 1236, 342, 3, 2, 2, 2, 1237, 1238, 9, 25, 2, 2, 1238, 344, 3, 2, 2, 2, 1239, 1240, 9, 26, 2, 2, 1240, 346, 3, 2, 2, 2, 1241, 1242, 9, 27, 2, 2, 1242, 348, 3, 2, 2, 2, 1243, 1244, 9, 28, 2, 2, 1244, 350, 3, 2, 2, 2, 1245, 1246, 9, 29, 2, 2, 1246, 352, 3, 2, 2, 2, 1247, 1248, 9, 30, 2, 2, 1248, 354, 3, 2, 2, 2, 1249, 1250, 9, 31, 2, 2, 1250, 356, 3, 2, 2, 2, 1251, 1252, 9, 32, 2, 2, 1252, 358, 3, 2, 2, 2, 1253, 1254, 9, 33, 2, 2, 1254, 360, 3, 2, 2, 2, 1255, 1256, 9, 34, 2, 2, 1256, 362, 3, 2, 2, 2, 1257, 1258, 9, 35, 2, 2, 1258, 364, 3, 2, 2, 2, 1259, 1260, 9, 36, 2, 2, 1260, 366, 3, 2, 2, 2, 1261, 1262, 9, 37, 2, 2, 1262, 368, 3, 2, 2, 2, 1263, 1264, 9, 38, 2, 2, 1264, 370, 3, 2, 2, 2, 1265, 1266, 9, 39, 2, 2, 1266, 372, 3, 2, 2, 2, 56, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 529, 539, 543, 546, 555, 557, 568, 609, 614, 623, 630, 635, 637, 648, 656, 659, 661, 666, 671, 677, 684, 689, 695, 698, 706, 710, 840, 845, 850, 852, 858, 907, 912, 947, 951, 956, 961, 966, 968, 1056, 1061, 1199, 1201, 26, 7, 4, 2, 7, 6, 2, 7, 8, 2, 7, 3, 2, 7, 5, 2, 7, 10, 2, 7, 7, 2, 7, 11, 2, 2, 3, 2, 9, 66, 2, 7, 2, 2, 9, 28, 2, 6, 2, 2, 9, 67, 2, 9, 36, 2, 9, 35, 2, 9, 69, 2, 9, 38, 2, 9, 78, 2, 7, 12, 2, 7, 9, 2, 9, 88, 2, 9, 87, 2, 9, 68, 2] \ No newline at end of file +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 106, 1259, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 4, 178, 9, 178, 4, 179, 9, 179, 4, 180, 9, 180, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 6, 19, 516, 10, 19, 13, 19, 14, 19, 517, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 7, 20, 526, 10, 20, 12, 20, 14, 20, 529, 11, 20, 3, 20, 5, 20, 532, 10, 20, 3, 20, 5, 20, 535, 10, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 7, 21, 544, 10, 21, 12, 21, 14, 21, 547, 11, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 6, 22, 555, 10, 22, 13, 22, 14, 22, 556, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 598, 10, 33, 3, 33, 6, 33, 601, 10, 33, 13, 33, 14, 33, 602, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 5, 36, 612, 10, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 5, 38, 619, 10, 38, 3, 39, 3, 39, 3, 39, 7, 39, 624, 10, 39, 12, 39, 14, 39, 627, 11, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 7, 39, 635, 10, 39, 12, 39, 14, 39, 638, 11, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 5, 39, 645, 10, 39, 3, 39, 5, 39, 648, 10, 39, 5, 39, 650, 10, 39, 3, 40, 6, 40, 653, 10, 40, 13, 40, 14, 40, 654, 3, 41, 6, 41, 658, 10, 41, 13, 41, 14, 41, 659, 3, 41, 3, 41, 7, 41, 664, 10, 41, 12, 41, 14, 41, 667, 11, 41, 3, 41, 3, 41, 6, 41, 671, 10, 41, 13, 41, 14, 41, 672, 3, 41, 6, 41, 676, 10, 41, 13, 41, 14, 41, 677, 3, 41, 3, 41, 7, 41, 682, 10, 41, 12, 41, 14, 41, 685, 11, 41, 5, 41, 687, 10, 41, 3, 41, 3, 41, 3, 41, 3, 41, 6, 41, 693, 10, 41, 13, 41, 14, 41, 694, 3, 41, 3, 41, 5, 41, 699, 10, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 73, 3, 73, 3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 7, 78, 827, 10, 78, 12, 78, 14, 78, 830, 11, 78, 3, 78, 3, 78, 5, 78, 834, 10, 78, 3, 78, 6, 78, 837, 10, 78, 13, 78, 14, 78, 838, 5, 78, 841, 10, 78, 3, 79, 3, 79, 6, 79, 845, 10, 79, 13, 79, 14, 79, 846, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 5, 89, 896, 10, 89, 3, 90, 6, 90, 899, 10, 90, 13, 90, 14, 90, 900, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 5, 98, 936, 10, 98, 3, 99, 3, 99, 5, 99, 940, 10, 99, 3, 99, 7, 99, 943, 10, 99, 12, 99, 14, 99, 946, 11, 99, 3, 99, 3, 99, 5, 99, 950, 10, 99, 3, 99, 6, 99, 953, 10, 99, 13, 99, 14, 99, 954, 5, 99, 957, 10, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 6, 120, 1044, 10, 120, 13, 120, 14, 120, 1045, 3, 120, 3, 120, 5, 120, 1050, 10, 120, 3, 120, 6, 120, 1053, 10, 120, 13, 120, 14, 120, 1054, 3, 121, 3, 121, 3, 121, 3, 121, 3, 122, 3, 122, 3, 122, 3, 122, 3, 123, 3, 123, 3, 123, 3, 123, 3, 124, 3, 124, 3, 124, 3, 124, 3, 125, 3, 125, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 3, 147, 3, 148, 3, 148, 3, 148, 3, 148, 3, 149, 3, 149, 3, 149, 3, 149, 3, 149, 3, 150, 3, 150, 3, 151, 3, 151, 3, 151, 3, 151, 3, 151, 6, 151, 1192, 10, 151, 13, 151, 14, 151, 1193, 3, 152, 3, 152, 3, 152, 3, 152, 3, 153, 3, 153, 3, 153, 3, 153, 3, 154, 3, 154, 3, 154, 3, 154, 3, 155, 3, 155, 3, 156, 3, 156, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 3, 176, 3, 177, 3, 177, 3, 178, 3, 178, 3, 179, 3, 179, 3, 180, 3, 180, 4, 545, 636, 2, 2, 181, 13, 2, 3, 15, 2, 4, 17, 2, 5, 19, 2, 6, 21, 2, 7, 23, 2, 8, 25, 2, 9, 27, 2, 10, 29, 2, 11, 31, 2, 12, 33, 2, 13, 35, 2, 14, 37, 2, 15, 39, 2, 16, 41, 2, 17, 43, 2, 18, 45, 2, 19, 47, 2, 20, 49, 2, 21, 51, 2, 22, 53, 2, 23, 55, 2, 2, 57, 2, 2, 59, 2, 24, 61, 2, 25, 63, 2, 26, 65, 2, 27, 67, 2, 2, 69, 2, 2, 71, 2, 2, 73, 2, 2, 75, 2, 2, 77, 2, 2, 79, 2, 2, 81, 2, 2, 83, 2, 2, 85, 2, 2, 87, 2, 28, 89, 2, 29, 91, 2, 30, 93, 2, 31, 95, 2, 32, 97, 2, 33, 99, 2, 34, 101, 2, 35, 103, 2, 36, 105, 2, 37, 107, 2, 38, 109, 2, 39, 111, 2, 40, 113, 2, 41, 115, 2, 42, 117, 2, 43, 119, 2, 44, 121, 2, 45, 123, 2, 46, 125, 2, 47, 127, 2, 48, 129, 2, 49, 131, 2, 50, 133, 2, 51, 135, 2, 52, 137, 2, 53, 139, 2, 54, 141, 2, 55, 143, 2, 56, 145, 2, 57, 147, 2, 58, 149, 2, 59, 151, 2, 60, 153, 2, 61, 155, 2, 62, 157, 2, 63, 159, 2, 64, 161, 2, 65, 163, 2, 66, 165, 2, 67, 167, 2, 68, 169, 2, 69, 171, 2, 70, 173, 2, 71, 175, 2, 2, 177, 2, 2, 179, 2, 2, 181, 2, 2, 183, 2, 2, 185, 2, 72, 187, 2, 2, 189, 2, 73, 191, 2, 2, 193, 2, 74, 195, 2, 75, 197, 2, 76, 199, 2, 2, 201, 2, 2, 203, 2, 2, 205, 2, 2, 207, 2, 77, 209, 2, 2, 211, 2, 2, 213, 2, 78, 215, 2, 79, 217, 2, 80, 219, 2, 2, 221, 2, 2, 223, 2, 2, 225, 2, 2, 227, 2, 81, 229, 2, 2, 231, 2, 2, 233, 2, 82, 235, 2, 83, 237, 2, 84, 239, 2, 2, 241, 2, 2, 243, 2, 85, 245, 2, 86, 247, 2, 2, 249, 2, 87, 251, 2, 2, 253, 2, 2, 255, 2, 88, 257, 2, 89, 259, 2, 90, 261, 2, 2, 263, 2, 2, 265, 2, 2, 267, 2, 2, 269, 2, 2, 271, 2, 2, 273, 2, 2, 275, 2, 91, 277, 2, 92, 279, 2, 93, 281, 2, 2, 283, 2, 2, 285, 2, 2, 287, 2, 2, 289, 2, 94, 291, 2, 95, 293, 2, 96, 295, 2, 2, 297, 2, 97, 299, 2, 98, 301, 2, 99, 303, 2, 100, 305, 2, 101, 307, 2, 2, 309, 2, 102, 311, 2, 103, 313, 2, 104, 315, 2, 105, 317, 2, 106, 319, 2, 2, 321, 2, 2, 323, 2, 2, 325, 2, 2, 327, 2, 2, 329, 2, 2, 331, 2, 2, 333, 2, 2, 335, 2, 2, 337, 2, 2, 339, 2, 2, 341, 2, 2, 343, 2, 2, 345, 2, 2, 347, 2, 2, 349, 2, 2, 351, 2, 2, 353, 2, 2, 355, 2, 2, 357, 2, 2, 359, 2, 2, 361, 2, 2, 363, 2, 2, 365, 2, 2, 367, 2, 2, 369, 2, 2, 13, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 40, 8, 2, 11, 12, 15, 15, 34, 34, 49, 49, 93, 93, 95, 95, 4, 2, 12, 12, 15, 15, 5, 2, 11, 12, 15, 15, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 36, 36, 94, 94, 112, 112, 116, 116, 118, 118, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 3, 2, 98, 98, 12, 2, 11, 12, 15, 15, 34, 34, 46, 46, 49, 49, 63, 63, 93, 93, 95, 95, 98, 98, 126, 126, 4, 2, 44, 44, 49, 49, 13, 2, 11, 12, 15, 15, 34, 34, 36, 37, 46, 46, 49, 49, 60, 60, 62, 62, 64, 65, 94, 94, 126, 126, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 1261, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 3, 55, 3, 2, 2, 2, 3, 57, 3, 2, 2, 2, 3, 59, 3, 2, 2, 2, 3, 61, 3, 2, 2, 2, 3, 63, 3, 2, 2, 2, 4, 65, 3, 2, 2, 2, 4, 87, 3, 2, 2, 2, 4, 89, 3, 2, 2, 2, 4, 91, 3, 2, 2, 2, 4, 93, 3, 2, 2, 2, 4, 95, 3, 2, 2, 2, 4, 97, 3, 2, 2, 2, 4, 99, 3, 2, 2, 2, 4, 101, 3, 2, 2, 2, 4, 103, 3, 2, 2, 2, 4, 105, 3, 2, 2, 2, 4, 107, 3, 2, 2, 2, 4, 109, 3, 2, 2, 2, 4, 111, 3, 2, 2, 2, 4, 113, 3, 2, 2, 2, 4, 115, 3, 2, 2, 2, 4, 117, 3, 2, 2, 2, 4, 119, 3, 2, 2, 2, 4, 121, 3, 2, 2, 2, 4, 123, 3, 2, 2, 2, 4, 125, 3, 2, 2, 2, 4, 127, 3, 2, 2, 2, 4, 129, 3, 2, 2, 2, 4, 131, 3, 2, 2, 2, 4, 133, 3, 2, 2, 2, 4, 135, 3, 2, 2, 2, 4, 137, 3, 2, 2, 2, 4, 139, 3, 2, 2, 2, 4, 141, 3, 2, 2, 2, 4, 143, 3, 2, 2, 2, 4, 145, 3, 2, 2, 2, 4, 147, 3, 2, 2, 2, 4, 149, 3, 2, 2, 2, 4, 151, 3, 2, 2, 2, 4, 153, 3, 2, 2, 2, 4, 155, 3, 2, 2, 2, 4, 157, 3, 2, 2, 2, 4, 159, 3, 2, 2, 2, 4, 161, 3, 2, 2, 2, 4, 163, 3, 2, 2, 2, 4, 165, 3, 2, 2, 2, 4, 167, 3, 2, 2, 2, 4, 169, 3, 2, 2, 2, 4, 171, 3, 2, 2, 2, 4, 173, 3, 2, 2, 2, 5, 175, 3, 2, 2, 2, 5, 177, 3, 2, 2, 2, 5, 179, 3, 2, 2, 2, 5, 181, 3, 2, 2, 2, 5, 183, 3, 2, 2, 2, 5, 185, 3, 2, 2, 2, 5, 189, 3, 2, 2, 2, 5, 191, 3, 2, 2, 2, 5, 193, 3, 2, 2, 2, 5, 195, 3, 2, 2, 2, 5, 197, 3, 2, 2, 2, 6, 199, 3, 2, 2, 2, 6, 201, 3, 2, 2, 2, 6, 203, 3, 2, 2, 2, 6, 207, 3, 2, 2, 2, 6, 209, 3, 2, 2, 2, 6, 211, 3, 2, 2, 2, 6, 213, 3, 2, 2, 2, 6, 215, 3, 2, 2, 2, 6, 217, 3, 2, 2, 2, 7, 219, 3, 2, 2, 2, 7, 221, 3, 2, 2, 2, 7, 223, 3, 2, 2, 2, 7, 225, 3, 2, 2, 2, 7, 227, 3, 2, 2, 2, 7, 229, 3, 2, 2, 2, 7, 231, 3, 2, 2, 2, 7, 233, 3, 2, 2, 2, 7, 235, 3, 2, 2, 2, 7, 237, 3, 2, 2, 2, 8, 239, 3, 2, 2, 2, 8, 241, 3, 2, 2, 2, 8, 243, 3, 2, 2, 2, 8, 245, 3, 2, 2, 2, 8, 249, 3, 2, 2, 2, 8, 251, 3, 2, 2, 2, 8, 253, 3, 2, 2, 2, 8, 255, 3, 2, 2, 2, 8, 257, 3, 2, 2, 2, 8, 259, 3, 2, 2, 2, 9, 261, 3, 2, 2, 2, 9, 263, 3, 2, 2, 2, 9, 265, 3, 2, 2, 2, 9, 267, 3, 2, 2, 2, 9, 269, 3, 2, 2, 2, 9, 271, 3, 2, 2, 2, 9, 273, 3, 2, 2, 2, 9, 275, 3, 2, 2, 2, 9, 277, 3, 2, 2, 2, 9, 279, 3, 2, 2, 2, 10, 281, 3, 2, 2, 2, 10, 283, 3, 2, 2, 2, 10, 285, 3, 2, 2, 2, 10, 287, 3, 2, 2, 2, 10, 289, 3, 2, 2, 2, 10, 291, 3, 2, 2, 2, 10, 293, 3, 2, 2, 2, 11, 295, 3, 2, 2, 2, 11, 297, 3, 2, 2, 2, 11, 299, 3, 2, 2, 2, 11, 301, 3, 2, 2, 2, 11, 303, 3, 2, 2, 2, 11, 305, 3, 2, 2, 2, 12, 307, 3, 2, 2, 2, 12, 309, 3, 2, 2, 2, 12, 311, 3, 2, 2, 2, 12, 313, 3, 2, 2, 2, 12, 315, 3, 2, 2, 2, 12, 317, 3, 2, 2, 2, 13, 371, 3, 2, 2, 2, 15, 381, 3, 2, 2, 2, 17, 388, 3, 2, 2, 2, 19, 397, 3, 2, 2, 2, 21, 404, 3, 2, 2, 2, 23, 414, 3, 2, 2, 2, 25, 421, 3, 2, 2, 2, 27, 428, 3, 2, 2, 2, 29, 442, 3, 2, 2, 2, 31, 449, 3, 2, 2, 2, 33, 457, 3, 2, 2, 2, 35, 469, 3, 2, 2, 2, 37, 478, 3, 2, 2, 2, 39, 484, 3, 2, 2, 2, 41, 491, 3, 2, 2, 2, 43, 498, 3, 2, 2, 2, 45, 506, 3, 2, 2, 2, 47, 515, 3, 2, 2, 2, 49, 521, 3, 2, 2, 2, 51, 538, 3, 2, 2, 2, 53, 554, 3, 2, 2, 2, 55, 560, 3, 2, 2, 2, 57, 565, 3, 2, 2, 2, 59, 570, 3, 2, 2, 2, 61, 574, 3, 2, 2, 2, 63, 578, 3, 2, 2, 2, 65, 582, 3, 2, 2, 2, 67, 586, 3, 2, 2, 2, 69, 588, 3, 2, 2, 2, 71, 590, 3, 2, 2, 2, 73, 593, 3, 2, 2, 2, 75, 595, 3, 2, 2, 2, 77, 604, 3, 2, 2, 2, 79, 606, 3, 2, 2, 2, 81, 611, 3, 2, 2, 2, 83, 613, 3, 2, 2, 2, 85, 618, 3, 2, 2, 2, 87, 649, 3, 2, 2, 2, 89, 652, 3, 2, 2, 2, 91, 698, 3, 2, 2, 2, 93, 700, 3, 2, 2, 2, 95, 703, 3, 2, 2, 2, 97, 707, 3, 2, 2, 2, 99, 711, 3, 2, 2, 2, 101, 713, 3, 2, 2, 2, 103, 715, 3, 2, 2, 2, 105, 720, 3, 2, 2, 2, 107, 722, 3, 2, 2, 2, 109, 728, 3, 2, 2, 2, 111, 734, 3, 2, 2, 2, 113, 739, 3, 2, 2, 2, 115, 741, 3, 2, 2, 2, 117, 744, 3, 2, 2, 2, 119, 747, 3, 2, 2, 2, 121, 752, 3, 2, 2, 2, 123, 756, 3, 2, 2, 2, 125, 761, 3, 2, 2, 2, 127, 767, 3, 2, 2, 2, 129, 770, 3, 2, 2, 2, 131, 772, 3, 2, 2, 2, 133, 778, 3, 2, 2, 2, 135, 780, 3, 2, 2, 2, 137, 785, 3, 2, 2, 2, 139, 788, 3, 2, 2, 2, 141, 791, 3, 2, 2, 2, 143, 794, 3, 2, 2, 2, 145, 796, 3, 2, 2, 2, 147, 799, 3, 2, 2, 2, 149, 801, 3, 2, 2, 2, 151, 804, 3, 2, 2, 2, 153, 806, 3, 2, 2, 2, 155, 808, 3, 2, 2, 2, 157, 810, 3, 2, 2, 2, 159, 812, 3, 2, 2, 2, 161, 814, 3, 2, 2, 2, 163, 819, 3, 2, 2, 2, 165, 840, 3, 2, 2, 2, 167, 842, 3, 2, 2, 2, 169, 850, 3, 2, 2, 2, 171, 854, 3, 2, 2, 2, 173, 858, 3, 2, 2, 2, 175, 862, 3, 2, 2, 2, 177, 867, 3, 2, 2, 2, 179, 871, 3, 2, 2, 2, 181, 875, 3, 2, 2, 2, 183, 879, 3, 2, 2, 2, 185, 883, 3, 2, 2, 2, 187, 895, 3, 2, 2, 2, 189, 898, 3, 2, 2, 2, 191, 902, 3, 2, 2, 2, 193, 906, 3, 2, 2, 2, 195, 910, 3, 2, 2, 2, 197, 914, 3, 2, 2, 2, 199, 918, 3, 2, 2, 2, 201, 923, 3, 2, 2, 2, 203, 927, 3, 2, 2, 2, 205, 935, 3, 2, 2, 2, 207, 956, 3, 2, 2, 2, 209, 958, 3, 2, 2, 2, 211, 962, 3, 2, 2, 2, 213, 966, 3, 2, 2, 2, 215, 970, 3, 2, 2, 2, 217, 974, 3, 2, 2, 2, 219, 978, 3, 2, 2, 2, 221, 983, 3, 2, 2, 2, 223, 987, 3, 2, 2, 2, 225, 991, 3, 2, 2, 2, 227, 995, 3, 2, 2, 2, 229, 998, 3, 2, 2, 2, 231, 1002, 3, 2, 2, 2, 233, 1006, 3, 2, 2, 2, 235, 1010, 3, 2, 2, 2, 237, 1014, 3, 2, 2, 2, 239, 1018, 3, 2, 2, 2, 241, 1023, 3, 2, 2, 2, 243, 1028, 3, 2, 2, 2, 245, 1033, 3, 2, 2, 2, 247, 1040, 3, 2, 2, 2, 249, 1049, 3, 2, 2, 2, 251, 1056, 3, 2, 2, 2, 253, 1060, 3, 2, 2, 2, 255, 1064, 3, 2, 2, 2, 257, 1068, 3, 2, 2, 2, 259, 1072, 3, 2, 2, 2, 261, 1076, 3, 2, 2, 2, 263, 1082, 3, 2, 2, 2, 265, 1086, 3, 2, 2, 2, 267, 1090, 3, 2, 2, 2, 269, 1094, 3, 2, 2, 2, 271, 1098, 3, 2, 2, 2, 273, 1102, 3, 2, 2, 2, 275, 1106, 3, 2, 2, 2, 277, 1110, 3, 2, 2, 2, 279, 1114, 3, 2, 2, 2, 281, 1118, 3, 2, 2, 2, 283, 1123, 3, 2, 2, 2, 285, 1127, 3, 2, 2, 2, 287, 1131, 3, 2, 2, 2, 289, 1135, 3, 2, 2, 2, 291, 1139, 3, 2, 2, 2, 293, 1143, 3, 2, 2, 2, 295, 1147, 3, 2, 2, 2, 297, 1152, 3, 2, 2, 2, 299, 1157, 3, 2, 2, 2, 301, 1167, 3, 2, 2, 2, 303, 1171, 3, 2, 2, 2, 305, 1175, 3, 2, 2, 2, 307, 1179, 3, 2, 2, 2, 309, 1184, 3, 2, 2, 2, 311, 1191, 3, 2, 2, 2, 313, 1195, 3, 2, 2, 2, 315, 1199, 3, 2, 2, 2, 317, 1203, 3, 2, 2, 2, 319, 1207, 3, 2, 2, 2, 321, 1209, 3, 2, 2, 2, 323, 1211, 3, 2, 2, 2, 325, 1213, 3, 2, 2, 2, 327, 1215, 3, 2, 2, 2, 329, 1217, 3, 2, 2, 2, 331, 1219, 3, 2, 2, 2, 333, 1221, 3, 2, 2, 2, 335, 1223, 3, 2, 2, 2, 337, 1225, 3, 2, 2, 2, 339, 1227, 3, 2, 2, 2, 341, 1229, 3, 2, 2, 2, 343, 1231, 3, 2, 2, 2, 345, 1233, 3, 2, 2, 2, 347, 1235, 3, 2, 2, 2, 349, 1237, 3, 2, 2, 2, 351, 1239, 3, 2, 2, 2, 353, 1241, 3, 2, 2, 2, 355, 1243, 3, 2, 2, 2, 357, 1245, 3, 2, 2, 2, 359, 1247, 3, 2, 2, 2, 361, 1249, 3, 2, 2, 2, 363, 1251, 3, 2, 2, 2, 365, 1253, 3, 2, 2, 2, 367, 1255, 3, 2, 2, 2, 369, 1257, 3, 2, 2, 2, 371, 372, 5, 325, 158, 2, 372, 373, 5, 335, 163, 2, 373, 374, 5, 355, 173, 2, 374, 375, 5, 355, 173, 2, 375, 376, 5, 327, 159, 2, 376, 377, 5, 323, 157, 2, 377, 378, 5, 357, 174, 2, 378, 379, 3, 2, 2, 2, 379, 380, 8, 2, 2, 2, 380, 14, 3, 2, 2, 2, 381, 382, 5, 325, 158, 2, 382, 383, 5, 353, 172, 2, 383, 384, 5, 347, 169, 2, 384, 385, 5, 349, 170, 2, 385, 386, 3, 2, 2, 2, 386, 387, 8, 3, 3, 2, 387, 16, 3, 2, 2, 2, 388, 389, 5, 327, 159, 2, 389, 390, 5, 345, 168, 2, 390, 391, 5, 353, 172, 2, 391, 392, 5, 335, 163, 2, 392, 393, 5, 323, 157, 2, 393, 394, 5, 333, 162, 2, 394, 395, 3, 2, 2, 2, 395, 396, 8, 4, 4, 2, 396, 18, 3, 2, 2, 2, 397, 398, 5, 327, 159, 2, 398, 399, 5, 361, 176, 2, 399, 400, 5, 319, 155, 2, 400, 401, 5, 341, 166, 2, 401, 402, 3, 2, 2, 2, 402, 403, 8, 5, 2, 2, 403, 20, 3, 2, 2, 2, 404, 405, 5, 327, 159, 2, 405, 406, 5, 365, 178, 2, 406, 407, 5, 349, 170, 2, 407, 408, 5, 341, 166, 2, 408, 409, 5, 319, 155, 2, 409, 410, 5, 335, 163, 2, 410, 411, 5, 345, 168, 2, 411, 412, 3, 2, 2, 2, 412, 413, 8, 6, 5, 2, 413, 22, 3, 2, 2, 2, 414, 415, 5, 329, 160, 2, 415, 416, 5, 353, 172, 2, 416, 417, 5, 347, 169, 2, 417, 418, 5, 343, 167, 2, 418, 419, 3, 2, 2, 2, 419, 420, 8, 7, 6, 2, 420, 24, 3, 2, 2, 2, 421, 422, 5, 331, 161, 2, 422, 423, 5, 353, 172, 2, 423, 424, 5, 347, 169, 2, 424, 425, 5, 339, 165, 2, 425, 426, 3, 2, 2, 2, 426, 427, 8, 8, 2, 2, 427, 26, 3, 2, 2, 2, 428, 429, 5, 335, 163, 2, 429, 430, 5, 345, 168, 2, 430, 431, 5, 341, 166, 2, 431, 432, 5, 335, 163, 2, 432, 433, 5, 345, 168, 2, 433, 434, 5, 327, 159, 2, 434, 435, 5, 355, 173, 2, 435, 436, 5, 357, 174, 2, 436, 437, 5, 319, 155, 2, 437, 438, 5, 357, 174, 2, 438, 439, 5, 355, 173, 2, 439, 440, 3, 2, 2, 2, 440, 441, 8, 9, 2, 2, 441, 28, 3, 2, 2, 2, 442, 443, 5, 339, 165, 2, 443, 444, 5, 327, 159, 2, 444, 445, 5, 327, 159, 2, 445, 446, 5, 349, 170, 2, 446, 447, 3, 2, 2, 2, 447, 448, 8, 10, 3, 2, 448, 30, 3, 2, 2, 2, 449, 450, 5, 341, 166, 2, 450, 451, 5, 335, 163, 2, 451, 452, 5, 343, 167, 2, 452, 453, 5, 335, 163, 2, 453, 454, 5, 357, 174, 2, 454, 455, 3, 2, 2, 2, 455, 456, 8, 11, 2, 2, 456, 32, 3, 2, 2, 2, 457, 458, 5, 343, 167, 2, 458, 459, 5, 361, 176, 2, 459, 460, 5, 83, 37, 2, 460, 461, 5, 327, 159, 2, 461, 462, 5, 365, 178, 2, 462, 463, 5, 349, 170, 2, 463, 464, 5, 319, 155, 2, 464, 465, 5, 345, 168, 2, 465, 466, 5, 325, 158, 2, 466, 467, 3, 2, 2, 2, 467, 468, 8, 12, 7, 2, 468, 34, 3, 2, 2, 2, 469, 470, 5, 353, 172, 2, 470, 471, 5, 327, 159, 2, 471, 472, 5, 345, 168, 2, 472, 473, 5, 319, 155, 2, 473, 474, 5, 343, 167, 2, 474, 475, 5, 327, 159, 2, 475, 476, 3, 2, 2, 2, 476, 477, 8, 13, 8, 2, 477, 36, 3, 2, 2, 2, 478, 479, 5, 353, 172, 2, 479, 480, 5, 347, 169, 2, 480, 481, 5, 363, 177, 2, 481, 482, 3, 2, 2, 2, 482, 483, 8, 14, 2, 2, 483, 38, 3, 2, 2, 2, 484, 485, 5, 355, 173, 2, 485, 486, 5, 333, 162, 2, 486, 487, 5, 347, 169, 2, 487, 488, 5, 363, 177, 2, 488, 489, 3, 2, 2, 2, 489, 490, 8, 15, 9, 2, 490, 40, 3, 2, 2, 2, 491, 492, 5, 355, 173, 2, 492, 493, 5, 347, 169, 2, 493, 494, 5, 353, 172, 2, 494, 495, 5, 357, 174, 2, 495, 496, 3, 2, 2, 2, 496, 497, 8, 16, 2, 2, 497, 42, 3, 2, 2, 2, 498, 499, 5, 355, 173, 2, 499, 500, 5, 357, 174, 2, 500, 501, 5, 319, 155, 2, 501, 502, 5, 357, 174, 2, 502, 503, 5, 355, 173, 2, 503, 504, 3, 2, 2, 2, 504, 505, 8, 17, 2, 2, 505, 44, 3, 2, 2, 2, 506, 507, 5, 363, 177, 2, 507, 508, 5, 333, 162, 2, 508, 509, 5, 327, 159, 2, 509, 510, 5, 353, 172, 2, 510, 511, 5, 327, 159, 2, 511, 512, 3, 2, 2, 2, 512, 513, 8, 18, 2, 2, 513, 46, 3, 2, 2, 2, 514, 516, 10, 2, 2, 2, 515, 514, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 515, 3, 2, 2, 2, 517, 518, 3, 2, 2, 2, 518, 519, 3, 2, 2, 2, 519, 520, 8, 19, 2, 2, 520, 48, 3, 2, 2, 2, 521, 522, 7, 49, 2, 2, 522, 523, 7, 49, 2, 2, 523, 527, 3, 2, 2, 2, 524, 526, 10, 3, 2, 2, 525, 524, 3, 2, 2, 2, 526, 529, 3, 2, 2, 2, 527, 525, 3, 2, 2, 2, 527, 528, 3, 2, 2, 2, 528, 531, 3, 2, 2, 2, 529, 527, 3, 2, 2, 2, 530, 532, 7, 15, 2, 2, 531, 530, 3, 2, 2, 2, 531, 532, 3, 2, 2, 2, 532, 534, 3, 2, 2, 2, 533, 535, 7, 12, 2, 2, 534, 533, 3, 2, 2, 2, 534, 535, 3, 2, 2, 2, 535, 536, 3, 2, 2, 2, 536, 537, 8, 20, 10, 2, 537, 50, 3, 2, 2, 2, 538, 539, 7, 49, 2, 2, 539, 540, 7, 44, 2, 2, 540, 545, 3, 2, 2, 2, 541, 544, 5, 51, 21, 2, 542, 544, 11, 2, 2, 2, 543, 541, 3, 2, 2, 2, 543, 542, 3, 2, 2, 2, 544, 547, 3, 2, 2, 2, 545, 546, 3, 2, 2, 2, 545, 543, 3, 2, 2, 2, 546, 548, 3, 2, 2, 2, 547, 545, 3, 2, 2, 2, 548, 549, 7, 44, 2, 2, 549, 550, 7, 49, 2, 2, 550, 551, 3, 2, 2, 2, 551, 552, 8, 21, 10, 2, 552, 52, 3, 2, 2, 2, 553, 555, 9, 4, 2, 2, 554, 553, 3, 2, 2, 2, 555, 556, 3, 2, 2, 2, 556, 554, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 558, 3, 2, 2, 2, 558, 559, 8, 22, 10, 2, 559, 54, 3, 2, 2, 2, 560, 561, 5, 161, 76, 2, 561, 562, 3, 2, 2, 2, 562, 563, 8, 23, 11, 2, 563, 564, 8, 23, 12, 2, 564, 56, 3, 2, 2, 2, 565, 566, 5, 65, 28, 2, 566, 567, 3, 2, 2, 2, 567, 568, 8, 24, 13, 2, 568, 569, 8, 24, 14, 2, 569, 58, 3, 2, 2, 2, 570, 571, 5, 53, 22, 2, 571, 572, 3, 2, 2, 2, 572, 573, 8, 25, 10, 2, 573, 60, 3, 2, 2, 2, 574, 575, 5, 49, 20, 2, 575, 576, 3, 2, 2, 2, 576, 577, 8, 26, 10, 2, 577, 62, 3, 2, 2, 2, 578, 579, 5, 51, 21, 2, 579, 580, 3, 2, 2, 2, 580, 581, 8, 27, 10, 2, 581, 64, 3, 2, 2, 2, 582, 583, 7, 126, 2, 2, 583, 584, 3, 2, 2, 2, 584, 585, 8, 28, 14, 2, 585, 66, 3, 2, 2, 2, 586, 587, 9, 5, 2, 2, 587, 68, 3, 2, 2, 2, 588, 589, 9, 6, 2, 2, 589, 70, 3, 2, 2, 2, 590, 591, 7, 94, 2, 2, 591, 592, 9, 7, 2, 2, 592, 72, 3, 2, 2, 2, 593, 594, 10, 8, 2, 2, 594, 74, 3, 2, 2, 2, 595, 597, 9, 9, 2, 2, 596, 598, 9, 10, 2, 2, 597, 596, 3, 2, 2, 2, 597, 598, 3, 2, 2, 2, 598, 600, 3, 2, 2, 2, 599, 601, 5, 67, 29, 2, 600, 599, 3, 2, 2, 2, 601, 602, 3, 2, 2, 2, 602, 600, 3, 2, 2, 2, 602, 603, 3, 2, 2, 2, 603, 76, 3, 2, 2, 2, 604, 605, 7, 66, 2, 2, 605, 78, 3, 2, 2, 2, 606, 607, 7, 98, 2, 2, 607, 80, 3, 2, 2, 2, 608, 612, 10, 11, 2, 2, 609, 610, 7, 98, 2, 2, 610, 612, 7, 98, 2, 2, 611, 608, 3, 2, 2, 2, 611, 609, 3, 2, 2, 2, 612, 82, 3, 2, 2, 2, 613, 614, 7, 97, 2, 2, 614, 84, 3, 2, 2, 2, 615, 619, 5, 69, 30, 2, 616, 619, 5, 67, 29, 2, 617, 619, 5, 83, 37, 2, 618, 615, 3, 2, 2, 2, 618, 616, 3, 2, 2, 2, 618, 617, 3, 2, 2, 2, 619, 86, 3, 2, 2, 2, 620, 625, 7, 36, 2, 2, 621, 624, 5, 71, 31, 2, 622, 624, 5, 73, 32, 2, 623, 621, 3, 2, 2, 2, 623, 622, 3, 2, 2, 2, 624, 627, 3, 2, 2, 2, 625, 623, 3, 2, 2, 2, 625, 626, 3, 2, 2, 2, 626, 628, 3, 2, 2, 2, 627, 625, 3, 2, 2, 2, 628, 650, 7, 36, 2, 2, 629, 630, 7, 36, 2, 2, 630, 631, 7, 36, 2, 2, 631, 632, 7, 36, 2, 2, 632, 636, 3, 2, 2, 2, 633, 635, 10, 3, 2, 2, 634, 633, 3, 2, 2, 2, 635, 638, 3, 2, 2, 2, 636, 637, 3, 2, 2, 2, 636, 634, 3, 2, 2, 2, 637, 639, 3, 2, 2, 2, 638, 636, 3, 2, 2, 2, 639, 640, 7, 36, 2, 2, 640, 641, 7, 36, 2, 2, 641, 642, 7, 36, 2, 2, 642, 644, 3, 2, 2, 2, 643, 645, 7, 36, 2, 2, 644, 643, 3, 2, 2, 2, 644, 645, 3, 2, 2, 2, 645, 647, 3, 2, 2, 2, 646, 648, 7, 36, 2, 2, 647, 646, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 650, 3, 2, 2, 2, 649, 620, 3, 2, 2, 2, 649, 629, 3, 2, 2, 2, 650, 88, 3, 2, 2, 2, 651, 653, 5, 67, 29, 2, 652, 651, 3, 2, 2, 2, 653, 654, 3, 2, 2, 2, 654, 652, 3, 2, 2, 2, 654, 655, 3, 2, 2, 2, 655, 90, 3, 2, 2, 2, 656, 658, 5, 67, 29, 2, 657, 656, 3, 2, 2, 2, 658, 659, 3, 2, 2, 2, 659, 657, 3, 2, 2, 2, 659, 660, 3, 2, 2, 2, 660, 661, 3, 2, 2, 2, 661, 665, 5, 105, 48, 2, 662, 664, 5, 67, 29, 2, 663, 662, 3, 2, 2, 2, 664, 667, 3, 2, 2, 2, 665, 663, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 666, 699, 3, 2, 2, 2, 667, 665, 3, 2, 2, 2, 668, 670, 5, 105, 48, 2, 669, 671, 5, 67, 29, 2, 670, 669, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 672, 673, 3, 2, 2, 2, 673, 699, 3, 2, 2, 2, 674, 676, 5, 67, 29, 2, 675, 674, 3, 2, 2, 2, 676, 677, 3, 2, 2, 2, 677, 675, 3, 2, 2, 2, 677, 678, 3, 2, 2, 2, 678, 686, 3, 2, 2, 2, 679, 683, 5, 105, 48, 2, 680, 682, 5, 67, 29, 2, 681, 680, 3, 2, 2, 2, 682, 685, 3, 2, 2, 2, 683, 681, 3, 2, 2, 2, 683, 684, 3, 2, 2, 2, 684, 687, 3, 2, 2, 2, 685, 683, 3, 2, 2, 2, 686, 679, 3, 2, 2, 2, 686, 687, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 689, 5, 75, 33, 2, 689, 699, 3, 2, 2, 2, 690, 692, 5, 105, 48, 2, 691, 693, 5, 67, 29, 2, 692, 691, 3, 2, 2, 2, 693, 694, 3, 2, 2, 2, 694, 692, 3, 2, 2, 2, 694, 695, 3, 2, 2, 2, 695, 696, 3, 2, 2, 2, 696, 697, 5, 75, 33, 2, 697, 699, 3, 2, 2, 2, 698, 657, 3, 2, 2, 2, 698, 668, 3, 2, 2, 2, 698, 675, 3, 2, 2, 2, 698, 690, 3, 2, 2, 2, 699, 92, 3, 2, 2, 2, 700, 701, 5, 321, 156, 2, 701, 702, 5, 367, 179, 2, 702, 94, 3, 2, 2, 2, 703, 704, 5, 319, 155, 2, 704, 705, 5, 345, 168, 2, 705, 706, 5, 325, 158, 2, 706, 96, 3, 2, 2, 2, 707, 708, 5, 319, 155, 2, 708, 709, 5, 355, 173, 2, 709, 710, 5, 323, 157, 2, 710, 98, 3, 2, 2, 2, 711, 712, 7, 63, 2, 2, 712, 100, 3, 2, 2, 2, 713, 714, 7, 46, 2, 2, 714, 102, 3, 2, 2, 2, 715, 716, 5, 325, 158, 2, 716, 717, 5, 327, 159, 2, 717, 718, 5, 355, 173, 2, 718, 719, 5, 323, 157, 2, 719, 104, 3, 2, 2, 2, 720, 721, 7, 48, 2, 2, 721, 106, 3, 2, 2, 2, 722, 723, 5, 329, 160, 2, 723, 724, 5, 319, 155, 2, 724, 725, 5, 341, 166, 2, 725, 726, 5, 355, 173, 2, 726, 727, 5, 327, 159, 2, 727, 108, 3, 2, 2, 2, 728, 729, 5, 329, 160, 2, 729, 730, 5, 335, 163, 2, 730, 731, 5, 353, 172, 2, 731, 732, 5, 355, 173, 2, 732, 733, 5, 357, 174, 2, 733, 110, 3, 2, 2, 2, 734, 735, 5, 341, 166, 2, 735, 736, 5, 319, 155, 2, 736, 737, 5, 355, 173, 2, 737, 738, 5, 357, 174, 2, 738, 112, 3, 2, 2, 2, 739, 740, 7, 42, 2, 2, 740, 114, 3, 2, 2, 2, 741, 742, 5, 335, 163, 2, 742, 743, 5, 345, 168, 2, 743, 116, 3, 2, 2, 2, 744, 745, 5, 335, 163, 2, 745, 746, 5, 355, 173, 2, 746, 118, 3, 2, 2, 2, 747, 748, 5, 341, 166, 2, 748, 749, 5, 335, 163, 2, 749, 750, 5, 339, 165, 2, 750, 751, 5, 327, 159, 2, 751, 120, 3, 2, 2, 2, 752, 753, 5, 345, 168, 2, 753, 754, 5, 347, 169, 2, 754, 755, 5, 357, 174, 2, 755, 122, 3, 2, 2, 2, 756, 757, 5, 345, 168, 2, 757, 758, 5, 359, 175, 2, 758, 759, 5, 341, 166, 2, 759, 760, 5, 341, 166, 2, 760, 124, 3, 2, 2, 2, 761, 762, 5, 345, 168, 2, 762, 763, 5, 359, 175, 2, 763, 764, 5, 341, 166, 2, 764, 765, 5, 341, 166, 2, 765, 766, 5, 355, 173, 2, 766, 126, 3, 2, 2, 2, 767, 768, 5, 347, 169, 2, 768, 769, 5, 353, 172, 2, 769, 128, 3, 2, 2, 2, 770, 771, 7, 65, 2, 2, 771, 130, 3, 2, 2, 2, 772, 773, 5, 353, 172, 2, 773, 774, 5, 341, 166, 2, 774, 775, 5, 335, 163, 2, 775, 776, 5, 339, 165, 2, 776, 777, 5, 327, 159, 2, 777, 132, 3, 2, 2, 2, 778, 779, 7, 43, 2, 2, 779, 134, 3, 2, 2, 2, 780, 781, 5, 357, 174, 2, 781, 782, 5, 353, 172, 2, 782, 783, 5, 359, 175, 2, 783, 784, 5, 327, 159, 2, 784, 136, 3, 2, 2, 2, 785, 786, 7, 63, 2, 2, 786, 787, 7, 63, 2, 2, 787, 138, 3, 2, 2, 2, 788, 789, 7, 63, 2, 2, 789, 790, 7, 128, 2, 2, 790, 140, 3, 2, 2, 2, 791, 792, 7, 35, 2, 2, 792, 793, 7, 63, 2, 2, 793, 142, 3, 2, 2, 2, 794, 795, 7, 62, 2, 2, 795, 144, 3, 2, 2, 2, 796, 797, 7, 62, 2, 2, 797, 798, 7, 63, 2, 2, 798, 146, 3, 2, 2, 2, 799, 800, 7, 64, 2, 2, 800, 148, 3, 2, 2, 2, 801, 802, 7, 64, 2, 2, 802, 803, 7, 63, 2, 2, 803, 150, 3, 2, 2, 2, 804, 805, 7, 45, 2, 2, 805, 152, 3, 2, 2, 2, 806, 807, 7, 47, 2, 2, 807, 154, 3, 2, 2, 2, 808, 809, 7, 44, 2, 2, 809, 156, 3, 2, 2, 2, 810, 811, 7, 49, 2, 2, 811, 158, 3, 2, 2, 2, 812, 813, 7, 39, 2, 2, 813, 160, 3, 2, 2, 2, 814, 815, 7, 93, 2, 2, 815, 816, 3, 2, 2, 2, 816, 817, 8, 76, 2, 2, 817, 818, 8, 76, 2, 2, 818, 162, 3, 2, 2, 2, 819, 820, 7, 95, 2, 2, 820, 821, 3, 2, 2, 2, 821, 822, 8, 77, 14, 2, 822, 823, 8, 77, 14, 2, 823, 164, 3, 2, 2, 2, 824, 828, 5, 69, 30, 2, 825, 827, 5, 85, 38, 2, 826, 825, 3, 2, 2, 2, 827, 830, 3, 2, 2, 2, 828, 826, 3, 2, 2, 2, 828, 829, 3, 2, 2, 2, 829, 841, 3, 2, 2, 2, 830, 828, 3, 2, 2, 2, 831, 834, 5, 83, 37, 2, 832, 834, 5, 77, 34, 2, 833, 831, 3, 2, 2, 2, 833, 832, 3, 2, 2, 2, 834, 836, 3, 2, 2, 2, 835, 837, 5, 85, 38, 2, 836, 835, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 836, 3, 2, 2, 2, 838, 839, 3, 2, 2, 2, 839, 841, 3, 2, 2, 2, 840, 824, 3, 2, 2, 2, 840, 833, 3, 2, 2, 2, 841, 166, 3, 2, 2, 2, 842, 844, 5, 79, 35, 2, 843, 845, 5, 81, 36, 2, 844, 843, 3, 2, 2, 2, 845, 846, 3, 2, 2, 2, 846, 844, 3, 2, 2, 2, 846, 847, 3, 2, 2, 2, 847, 848, 3, 2, 2, 2, 848, 849, 5, 79, 35, 2, 849, 168, 3, 2, 2, 2, 850, 851, 5, 49, 20, 2, 851, 852, 3, 2, 2, 2, 852, 853, 8, 80, 10, 2, 853, 170, 3, 2, 2, 2, 854, 855, 5, 51, 21, 2, 855, 856, 3, 2, 2, 2, 856, 857, 8, 81, 10, 2, 857, 172, 3, 2, 2, 2, 858, 859, 5, 53, 22, 2, 859, 860, 3, 2, 2, 2, 860, 861, 8, 82, 10, 2, 861, 174, 3, 2, 2, 2, 862, 863, 5, 65, 28, 2, 863, 864, 3, 2, 2, 2, 864, 865, 8, 83, 13, 2, 865, 866, 8, 83, 14, 2, 866, 176, 3, 2, 2, 2, 867, 868, 5, 161, 76, 2, 868, 869, 3, 2, 2, 2, 869, 870, 8, 84, 11, 2, 870, 178, 3, 2, 2, 2, 871, 872, 5, 163, 77, 2, 872, 873, 3, 2, 2, 2, 873, 874, 8, 85, 15, 2, 874, 180, 3, 2, 2, 2, 875, 876, 5, 101, 46, 2, 876, 877, 3, 2, 2, 2, 877, 878, 8, 86, 16, 2, 878, 182, 3, 2, 2, 2, 879, 880, 5, 99, 45, 2, 880, 881, 3, 2, 2, 2, 881, 882, 8, 87, 17, 2, 882, 184, 3, 2, 2, 2, 883, 884, 5, 343, 167, 2, 884, 885, 5, 327, 159, 2, 885, 886, 5, 357, 174, 2, 886, 887, 5, 319, 155, 2, 887, 888, 5, 325, 158, 2, 888, 889, 5, 319, 155, 2, 889, 890, 5, 357, 174, 2, 890, 891, 5, 319, 155, 2, 891, 186, 3, 2, 2, 2, 892, 896, 10, 12, 2, 2, 893, 894, 7, 49, 2, 2, 894, 896, 10, 13, 2, 2, 895, 892, 3, 2, 2, 2, 895, 893, 3, 2, 2, 2, 896, 188, 3, 2, 2, 2, 897, 899, 5, 187, 89, 2, 898, 897, 3, 2, 2, 2, 899, 900, 3, 2, 2, 2, 900, 898, 3, 2, 2, 2, 900, 901, 3, 2, 2, 2, 901, 190, 3, 2, 2, 2, 902, 903, 5, 167, 79, 2, 903, 904, 3, 2, 2, 2, 904, 905, 8, 91, 18, 2, 905, 192, 3, 2, 2, 2, 906, 907, 5, 49, 20, 2, 907, 908, 3, 2, 2, 2, 908, 909, 8, 92, 10, 2, 909, 194, 3, 2, 2, 2, 910, 911, 5, 51, 21, 2, 911, 912, 3, 2, 2, 2, 912, 913, 8, 93, 10, 2, 913, 196, 3, 2, 2, 2, 914, 915, 5, 53, 22, 2, 915, 916, 3, 2, 2, 2, 916, 917, 8, 94, 10, 2, 917, 198, 3, 2, 2, 2, 918, 919, 5, 65, 28, 2, 919, 920, 3, 2, 2, 2, 920, 921, 8, 95, 13, 2, 921, 922, 8, 95, 14, 2, 922, 200, 3, 2, 2, 2, 923, 924, 5, 105, 48, 2, 924, 925, 3, 2, 2, 2, 925, 926, 8, 96, 19, 2, 926, 202, 3, 2, 2, 2, 927, 928, 5, 101, 46, 2, 928, 929, 3, 2, 2, 2, 929, 930, 8, 97, 16, 2, 930, 204, 3, 2, 2, 2, 931, 936, 5, 69, 30, 2, 932, 936, 5, 67, 29, 2, 933, 936, 5, 83, 37, 2, 934, 936, 5, 155, 73, 2, 935, 931, 3, 2, 2, 2, 935, 932, 3, 2, 2, 2, 935, 933, 3, 2, 2, 2, 935, 934, 3, 2, 2, 2, 936, 206, 3, 2, 2, 2, 937, 940, 5, 69, 30, 2, 938, 940, 5, 155, 73, 2, 939, 937, 3, 2, 2, 2, 939, 938, 3, 2, 2, 2, 940, 944, 3, 2, 2, 2, 941, 943, 5, 205, 98, 2, 942, 941, 3, 2, 2, 2, 943, 946, 3, 2, 2, 2, 944, 942, 3, 2, 2, 2, 944, 945, 3, 2, 2, 2, 945, 957, 3, 2, 2, 2, 946, 944, 3, 2, 2, 2, 947, 950, 5, 83, 37, 2, 948, 950, 5, 77, 34, 2, 949, 947, 3, 2, 2, 2, 949, 948, 3, 2, 2, 2, 950, 952, 3, 2, 2, 2, 951, 953, 5, 205, 98, 2, 952, 951, 3, 2, 2, 2, 953, 954, 3, 2, 2, 2, 954, 952, 3, 2, 2, 2, 954, 955, 3, 2, 2, 2, 955, 957, 3, 2, 2, 2, 956, 939, 3, 2, 2, 2, 956, 949, 3, 2, 2, 2, 957, 208, 3, 2, 2, 2, 958, 959, 5, 207, 99, 2, 959, 960, 3, 2, 2, 2, 960, 961, 8, 100, 20, 2, 961, 210, 3, 2, 2, 2, 962, 963, 5, 167, 79, 2, 963, 964, 3, 2, 2, 2, 964, 965, 8, 101, 18, 2, 965, 212, 3, 2, 2, 2, 966, 967, 5, 49, 20, 2, 967, 968, 3, 2, 2, 2, 968, 969, 8, 102, 10, 2, 969, 214, 3, 2, 2, 2, 970, 971, 5, 51, 21, 2, 971, 972, 3, 2, 2, 2, 972, 973, 8, 103, 10, 2, 973, 216, 3, 2, 2, 2, 974, 975, 5, 53, 22, 2, 975, 976, 3, 2, 2, 2, 976, 977, 8, 104, 10, 2, 977, 218, 3, 2, 2, 2, 978, 979, 5, 65, 28, 2, 979, 980, 3, 2, 2, 2, 980, 981, 8, 105, 13, 2, 981, 982, 8, 105, 14, 2, 982, 220, 3, 2, 2, 2, 983, 984, 5, 99, 45, 2, 984, 985, 3, 2, 2, 2, 985, 986, 8, 106, 17, 2, 986, 222, 3, 2, 2, 2, 987, 988, 5, 101, 46, 2, 988, 989, 3, 2, 2, 2, 989, 990, 8, 107, 16, 2, 990, 224, 3, 2, 2, 2, 991, 992, 5, 105, 48, 2, 992, 993, 3, 2, 2, 2, 993, 994, 8, 108, 19, 2, 994, 226, 3, 2, 2, 2, 995, 996, 5, 319, 155, 2, 996, 997, 5, 355, 173, 2, 997, 228, 3, 2, 2, 2, 998, 999, 5, 167, 79, 2, 999, 1000, 3, 2, 2, 2, 1000, 1001, 8, 110, 18, 2, 1001, 230, 3, 2, 2, 2, 1002, 1003, 5, 207, 99, 2, 1003, 1004, 3, 2, 2, 2, 1004, 1005, 8, 111, 20, 2, 1005, 232, 3, 2, 2, 2, 1006, 1007, 5, 49, 20, 2, 1007, 1008, 3, 2, 2, 2, 1008, 1009, 8, 112, 10, 2, 1009, 234, 3, 2, 2, 2, 1010, 1011, 5, 51, 21, 2, 1011, 1012, 3, 2, 2, 2, 1012, 1013, 8, 113, 10, 2, 1013, 236, 3, 2, 2, 2, 1014, 1015, 5, 53, 22, 2, 1015, 1016, 3, 2, 2, 2, 1016, 1017, 8, 114, 10, 2, 1017, 238, 3, 2, 2, 2, 1018, 1019, 5, 65, 28, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1021, 8, 115, 13, 2, 1021, 1022, 8, 115, 14, 2, 1022, 240, 3, 2, 2, 2, 1023, 1024, 5, 161, 76, 2, 1024, 1025, 3, 2, 2, 2, 1025, 1026, 8, 116, 11, 2, 1026, 1027, 8, 116, 21, 2, 1027, 242, 3, 2, 2, 2, 1028, 1029, 5, 347, 169, 2, 1029, 1030, 5, 345, 168, 2, 1030, 1031, 3, 2, 2, 2, 1031, 1032, 8, 117, 22, 2, 1032, 244, 3, 2, 2, 2, 1033, 1034, 5, 363, 177, 2, 1034, 1035, 5, 335, 163, 2, 1035, 1036, 5, 357, 174, 2, 1036, 1037, 5, 333, 162, 2, 1037, 1038, 3, 2, 2, 2, 1038, 1039, 8, 118, 22, 2, 1039, 246, 3, 2, 2, 2, 1040, 1041, 10, 14, 2, 2, 1041, 248, 3, 2, 2, 2, 1042, 1044, 5, 247, 119, 2, 1043, 1042, 3, 2, 2, 2, 1044, 1045, 3, 2, 2, 2, 1045, 1043, 3, 2, 2, 2, 1045, 1046, 3, 2, 2, 2, 1046, 1047, 3, 2, 2, 2, 1047, 1048, 5, 309, 150, 2, 1048, 1050, 3, 2, 2, 2, 1049, 1043, 3, 2, 2, 2, 1049, 1050, 3, 2, 2, 2, 1050, 1052, 3, 2, 2, 2, 1051, 1053, 5, 247, 119, 2, 1052, 1051, 3, 2, 2, 2, 1053, 1054, 3, 2, 2, 2, 1054, 1052, 3, 2, 2, 2, 1054, 1055, 3, 2, 2, 2, 1055, 250, 3, 2, 2, 2, 1056, 1057, 5, 167, 79, 2, 1057, 1058, 3, 2, 2, 2, 1058, 1059, 8, 121, 18, 2, 1059, 252, 3, 2, 2, 2, 1060, 1061, 5, 249, 120, 2, 1061, 1062, 3, 2, 2, 2, 1062, 1063, 8, 122, 23, 2, 1063, 254, 3, 2, 2, 2, 1064, 1065, 5, 49, 20, 2, 1065, 1066, 3, 2, 2, 2, 1066, 1067, 8, 123, 10, 2, 1067, 256, 3, 2, 2, 2, 1068, 1069, 5, 51, 21, 2, 1069, 1070, 3, 2, 2, 2, 1070, 1071, 8, 124, 10, 2, 1071, 258, 3, 2, 2, 2, 1072, 1073, 5, 53, 22, 2, 1073, 1074, 3, 2, 2, 2, 1074, 1075, 8, 125, 10, 2, 1075, 260, 3, 2, 2, 2, 1076, 1077, 5, 65, 28, 2, 1077, 1078, 3, 2, 2, 2, 1078, 1079, 8, 126, 13, 2, 1079, 1080, 8, 126, 14, 2, 1080, 1081, 8, 126, 14, 2, 1081, 262, 3, 2, 2, 2, 1082, 1083, 5, 99, 45, 2, 1083, 1084, 3, 2, 2, 2, 1084, 1085, 8, 127, 17, 2, 1085, 264, 3, 2, 2, 2, 1086, 1087, 5, 101, 46, 2, 1087, 1088, 3, 2, 2, 2, 1088, 1089, 8, 128, 16, 2, 1089, 266, 3, 2, 2, 2, 1090, 1091, 5, 105, 48, 2, 1091, 1092, 3, 2, 2, 2, 1092, 1093, 8, 129, 19, 2, 1093, 268, 3, 2, 2, 2, 1094, 1095, 5, 245, 118, 2, 1095, 1096, 3, 2, 2, 2, 1096, 1097, 8, 130, 24, 2, 1097, 270, 3, 2, 2, 2, 1098, 1099, 5, 207, 99, 2, 1099, 1100, 3, 2, 2, 2, 1100, 1101, 8, 131, 20, 2, 1101, 272, 3, 2, 2, 2, 1102, 1103, 5, 167, 79, 2, 1103, 1104, 3, 2, 2, 2, 1104, 1105, 8, 132, 18, 2, 1105, 274, 3, 2, 2, 2, 1106, 1107, 5, 49, 20, 2, 1107, 1108, 3, 2, 2, 2, 1108, 1109, 8, 133, 10, 2, 1109, 276, 3, 2, 2, 2, 1110, 1111, 5, 51, 21, 2, 1111, 1112, 3, 2, 2, 2, 1112, 1113, 8, 134, 10, 2, 1113, 278, 3, 2, 2, 2, 1114, 1115, 5, 53, 22, 2, 1115, 1116, 3, 2, 2, 2, 1116, 1117, 8, 135, 10, 2, 1117, 280, 3, 2, 2, 2, 1118, 1119, 5, 65, 28, 2, 1119, 1120, 3, 2, 2, 2, 1120, 1121, 8, 136, 13, 2, 1121, 1122, 8, 136, 14, 2, 1122, 282, 3, 2, 2, 2, 1123, 1124, 5, 105, 48, 2, 1124, 1125, 3, 2, 2, 2, 1125, 1126, 8, 137, 19, 2, 1126, 284, 3, 2, 2, 2, 1127, 1128, 5, 167, 79, 2, 1128, 1129, 3, 2, 2, 2, 1129, 1130, 8, 138, 18, 2, 1130, 286, 3, 2, 2, 2, 1131, 1132, 5, 165, 78, 2, 1132, 1133, 3, 2, 2, 2, 1133, 1134, 8, 139, 25, 2, 1134, 288, 3, 2, 2, 2, 1135, 1136, 5, 49, 20, 2, 1136, 1137, 3, 2, 2, 2, 1137, 1138, 8, 140, 10, 2, 1138, 290, 3, 2, 2, 2, 1139, 1140, 5, 51, 21, 2, 1140, 1141, 3, 2, 2, 2, 1141, 1142, 8, 141, 10, 2, 1142, 292, 3, 2, 2, 2, 1143, 1144, 5, 53, 22, 2, 1144, 1145, 3, 2, 2, 2, 1145, 1146, 8, 142, 10, 2, 1146, 294, 3, 2, 2, 2, 1147, 1148, 5, 65, 28, 2, 1148, 1149, 3, 2, 2, 2, 1149, 1150, 8, 143, 13, 2, 1150, 1151, 8, 143, 14, 2, 1151, 296, 3, 2, 2, 2, 1152, 1153, 5, 335, 163, 2, 1153, 1154, 5, 345, 168, 2, 1154, 1155, 5, 329, 160, 2, 1155, 1156, 5, 347, 169, 2, 1156, 298, 3, 2, 2, 2, 1157, 1158, 5, 329, 160, 2, 1158, 1159, 5, 359, 175, 2, 1159, 1160, 5, 345, 168, 2, 1160, 1161, 5, 323, 157, 2, 1161, 1162, 5, 357, 174, 2, 1162, 1163, 5, 335, 163, 2, 1163, 1164, 5, 347, 169, 2, 1164, 1165, 5, 345, 168, 2, 1165, 1166, 5, 355, 173, 2, 1166, 300, 3, 2, 2, 2, 1167, 1168, 5, 49, 20, 2, 1168, 1169, 3, 2, 2, 2, 1169, 1170, 8, 146, 10, 2, 1170, 302, 3, 2, 2, 2, 1171, 1172, 5, 51, 21, 2, 1172, 1173, 3, 2, 2, 2, 1173, 1174, 8, 147, 10, 2, 1174, 304, 3, 2, 2, 2, 1175, 1176, 5, 53, 22, 2, 1176, 1177, 3, 2, 2, 2, 1177, 1178, 8, 148, 10, 2, 1178, 306, 3, 2, 2, 2, 1179, 1180, 5, 163, 77, 2, 1180, 1181, 3, 2, 2, 2, 1181, 1182, 8, 149, 15, 2, 1182, 1183, 8, 149, 14, 2, 1183, 308, 3, 2, 2, 2, 1184, 1185, 7, 60, 2, 2, 1185, 310, 3, 2, 2, 2, 1186, 1192, 5, 77, 34, 2, 1187, 1192, 5, 67, 29, 2, 1188, 1192, 5, 105, 48, 2, 1189, 1192, 5, 69, 30, 2, 1190, 1192, 5, 83, 37, 2, 1191, 1186, 3, 2, 2, 2, 1191, 1187, 3, 2, 2, 2, 1191, 1188, 3, 2, 2, 2, 1191, 1189, 3, 2, 2, 2, 1191, 1190, 3, 2, 2, 2, 1192, 1193, 3, 2, 2, 2, 1193, 1191, 3, 2, 2, 2, 1193, 1194, 3, 2, 2, 2, 1194, 312, 3, 2, 2, 2, 1195, 1196, 5, 49, 20, 2, 1196, 1197, 3, 2, 2, 2, 1197, 1198, 8, 152, 10, 2, 1198, 314, 3, 2, 2, 2, 1199, 1200, 5, 51, 21, 2, 1200, 1201, 3, 2, 2, 2, 1201, 1202, 8, 153, 10, 2, 1202, 316, 3, 2, 2, 2, 1203, 1204, 5, 53, 22, 2, 1204, 1205, 3, 2, 2, 2, 1205, 1206, 8, 154, 10, 2, 1206, 318, 3, 2, 2, 2, 1207, 1208, 9, 15, 2, 2, 1208, 320, 3, 2, 2, 2, 1209, 1210, 9, 16, 2, 2, 1210, 322, 3, 2, 2, 2, 1211, 1212, 9, 17, 2, 2, 1212, 324, 3, 2, 2, 2, 1213, 1214, 9, 18, 2, 2, 1214, 326, 3, 2, 2, 2, 1215, 1216, 9, 9, 2, 2, 1216, 328, 3, 2, 2, 2, 1217, 1218, 9, 19, 2, 2, 1218, 330, 3, 2, 2, 2, 1219, 1220, 9, 20, 2, 2, 1220, 332, 3, 2, 2, 2, 1221, 1222, 9, 21, 2, 2, 1222, 334, 3, 2, 2, 2, 1223, 1224, 9, 22, 2, 2, 1224, 336, 3, 2, 2, 2, 1225, 1226, 9, 23, 2, 2, 1226, 338, 3, 2, 2, 2, 1227, 1228, 9, 24, 2, 2, 1228, 340, 3, 2, 2, 2, 1229, 1230, 9, 25, 2, 2, 1230, 342, 3, 2, 2, 2, 1231, 1232, 9, 26, 2, 2, 1232, 344, 3, 2, 2, 2, 1233, 1234, 9, 27, 2, 2, 1234, 346, 3, 2, 2, 2, 1235, 1236, 9, 28, 2, 2, 1236, 348, 3, 2, 2, 2, 1237, 1238, 9, 29, 2, 2, 1238, 350, 3, 2, 2, 2, 1239, 1240, 9, 30, 2, 2, 1240, 352, 3, 2, 2, 2, 1241, 1242, 9, 31, 2, 2, 1242, 354, 3, 2, 2, 2, 1243, 1244, 9, 32, 2, 2, 1244, 356, 3, 2, 2, 2, 1245, 1246, 9, 33, 2, 2, 1246, 358, 3, 2, 2, 2, 1247, 1248, 9, 34, 2, 2, 1248, 360, 3, 2, 2, 2, 1249, 1250, 9, 35, 2, 2, 1250, 362, 3, 2, 2, 2, 1251, 1252, 9, 36, 2, 2, 1252, 364, 3, 2, 2, 2, 1253, 1254, 9, 37, 2, 2, 1254, 366, 3, 2, 2, 2, 1255, 1256, 9, 38, 2, 2, 1256, 368, 3, 2, 2, 2, 1257, 1258, 9, 39, 2, 2, 1258, 370, 3, 2, 2, 2, 57, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 517, 527, 531, 534, 543, 545, 556, 597, 602, 611, 618, 623, 625, 636, 644, 647, 649, 654, 659, 665, 672, 677, 683, 686, 694, 698, 828, 833, 838, 840, 846, 895, 900, 935, 939, 944, 949, 954, 956, 1045, 1049, 1054, 1191, 1193, 26, 7, 4, 2, 7, 6, 2, 7, 8, 2, 7, 3, 2, 7, 5, 2, 7, 10, 2, 7, 7, 2, 7, 11, 2, 2, 3, 2, 9, 65, 2, 7, 2, 2, 9, 27, 2, 6, 2, 2, 9, 66, 2, 9, 35, 2, 9, 34, 2, 9, 68, 2, 9, 37, 2, 9, 77, 2, 7, 12, 2, 7, 9, 2, 9, 87, 2, 9, 86, 2, 9, 67, 2] \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens b/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens index 4bdf0572a3b8a..1f49f7e26406b 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens @@ -9,118 +9,117 @@ INLINESTATS=8 KEEP=9 LIMIT=10 MV_EXPAND=11 -PROJECT=12 -RENAME=13 -ROW=14 -SHOW=15 -SORT=16 -STATS=17 -WHERE=18 -UNKNOWN_CMD=19 -LINE_COMMENT=20 -MULTILINE_COMMENT=21 -WS=22 -EXPLAIN_WS=23 -EXPLAIN_LINE_COMMENT=24 -EXPLAIN_MULTILINE_COMMENT=25 -PIPE=26 -STRING=27 -INTEGER_LITERAL=28 -DECIMAL_LITERAL=29 -BY=30 -AND=31 -ASC=32 -ASSIGN=33 -COMMA=34 -DESC=35 -DOT=36 -FALSE=37 -FIRST=38 -LAST=39 -LP=40 -IN=41 -IS=42 -LIKE=43 -NOT=44 -NULL=45 -NULLS=46 -OR=47 -PARAM=48 -RLIKE=49 -RP=50 -TRUE=51 -EQ=52 -CIEQ=53 -NEQ=54 -LT=55 -LTE=56 -GT=57 -GTE=58 -PLUS=59 -MINUS=60 -ASTERISK=61 -SLASH=62 -PERCENT=63 -OPENING_BRACKET=64 -CLOSING_BRACKET=65 -UNQUOTED_IDENTIFIER=66 -QUOTED_IDENTIFIER=67 -EXPR_LINE_COMMENT=68 -EXPR_MULTILINE_COMMENT=69 -EXPR_WS=70 -METADATA=71 -FROM_UNQUOTED_IDENTIFIER=72 -FROM_LINE_COMMENT=73 -FROM_MULTILINE_COMMENT=74 -FROM_WS=75 -UNQUOTED_ID_PATTERN=76 -PROJECT_LINE_COMMENT=77 -PROJECT_MULTILINE_COMMENT=78 -PROJECT_WS=79 -AS=80 -RENAME_LINE_COMMENT=81 -RENAME_MULTILINE_COMMENT=82 -RENAME_WS=83 -ON=84 -WITH=85 -ENRICH_POLICY_NAME=86 -ENRICH_LINE_COMMENT=87 -ENRICH_MULTILINE_COMMENT=88 -ENRICH_WS=89 -ENRICH_FIELD_LINE_COMMENT=90 -ENRICH_FIELD_MULTILINE_COMMENT=91 -ENRICH_FIELD_WS=92 -MVEXPAND_LINE_COMMENT=93 -MVEXPAND_MULTILINE_COMMENT=94 -MVEXPAND_WS=95 -INFO=96 -FUNCTIONS=97 -SHOW_LINE_COMMENT=98 -SHOW_MULTILINE_COMMENT=99 -SHOW_WS=100 -COLON=101 -SETTING=102 -SETTING_LINE_COMMENT=103 -SETTTING_MULTILINE_COMMENT=104 -SETTING_WS=105 -'|'=26 -'='=33 -','=34 -'.'=36 -'('=40 -'?'=48 -')'=50 -'=='=52 -'=~'=53 -'!='=54 -'<'=55 -'<='=56 -'>'=57 -'>='=58 -'+'=59 -'-'=60 -'*'=61 -'/'=62 -'%'=63 -']'=65 -':'=101 +RENAME=12 +ROW=13 +SHOW=14 +SORT=15 +STATS=16 +WHERE=17 +UNKNOWN_CMD=18 +LINE_COMMENT=19 +MULTILINE_COMMENT=20 +WS=21 +EXPLAIN_WS=22 +EXPLAIN_LINE_COMMENT=23 +EXPLAIN_MULTILINE_COMMENT=24 +PIPE=25 +STRING=26 +INTEGER_LITERAL=27 +DECIMAL_LITERAL=28 +BY=29 +AND=30 +ASC=31 +ASSIGN=32 +COMMA=33 +DESC=34 +DOT=35 +FALSE=36 +FIRST=37 +LAST=38 +LP=39 +IN=40 +IS=41 +LIKE=42 +NOT=43 +NULL=44 +NULLS=45 +OR=46 +PARAM=47 +RLIKE=48 +RP=49 +TRUE=50 +EQ=51 +CIEQ=52 +NEQ=53 +LT=54 +LTE=55 +GT=56 +GTE=57 +PLUS=58 +MINUS=59 +ASTERISK=60 +SLASH=61 +PERCENT=62 +OPENING_BRACKET=63 +CLOSING_BRACKET=64 +UNQUOTED_IDENTIFIER=65 +QUOTED_IDENTIFIER=66 +EXPR_LINE_COMMENT=67 +EXPR_MULTILINE_COMMENT=68 +EXPR_WS=69 +METADATA=70 +FROM_UNQUOTED_IDENTIFIER=71 +FROM_LINE_COMMENT=72 +FROM_MULTILINE_COMMENT=73 +FROM_WS=74 +UNQUOTED_ID_PATTERN=75 +PROJECT_LINE_COMMENT=76 +PROJECT_MULTILINE_COMMENT=77 +PROJECT_WS=78 +AS=79 +RENAME_LINE_COMMENT=80 +RENAME_MULTILINE_COMMENT=81 +RENAME_WS=82 +ON=83 +WITH=84 +ENRICH_POLICY_NAME=85 +ENRICH_LINE_COMMENT=86 +ENRICH_MULTILINE_COMMENT=87 +ENRICH_WS=88 +ENRICH_FIELD_LINE_COMMENT=89 +ENRICH_FIELD_MULTILINE_COMMENT=90 +ENRICH_FIELD_WS=91 +MVEXPAND_LINE_COMMENT=92 +MVEXPAND_MULTILINE_COMMENT=93 +MVEXPAND_WS=94 +INFO=95 +FUNCTIONS=96 +SHOW_LINE_COMMENT=97 +SHOW_MULTILINE_COMMENT=98 +SHOW_WS=99 +COLON=100 +SETTING=101 +SETTING_LINE_COMMENT=102 +SETTTING_MULTILINE_COMMENT=103 +SETTING_WS=104 +'|'=25 +'='=32 +','=33 +'.'=35 +'('=39 +'?'=47 +')'=49 +'=='=51 +'=~'=52 +'!='=53 +'<'=54 +'<='=55 +'>'=56 +'>='=57 +'+'=58 +'-'=59 +'*'=60 +'/'=61 +'%'=62 +']'=64 +':'=100 diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts b/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts index 1bea52f3e5f29..12f8c8617cd75 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts @@ -28,100 +28,99 @@ export class esql_lexer extends Lexer { public static readonly KEEP = 9; public static readonly LIMIT = 10; public static readonly MV_EXPAND = 11; - public static readonly PROJECT = 12; - public static readonly RENAME = 13; - public static readonly ROW = 14; - public static readonly SHOW = 15; - public static readonly SORT = 16; - public static readonly STATS = 17; - public static readonly WHERE = 18; - public static readonly UNKNOWN_CMD = 19; - public static readonly LINE_COMMENT = 20; - public static readonly MULTILINE_COMMENT = 21; - public static readonly WS = 22; - public static readonly EXPLAIN_WS = 23; - public static readonly EXPLAIN_LINE_COMMENT = 24; - public static readonly EXPLAIN_MULTILINE_COMMENT = 25; - public static readonly PIPE = 26; - public static readonly STRING = 27; - public static readonly INTEGER_LITERAL = 28; - public static readonly DECIMAL_LITERAL = 29; - public static readonly BY = 30; - public static readonly AND = 31; - public static readonly ASC = 32; - public static readonly ASSIGN = 33; - public static readonly COMMA = 34; - public static readonly DESC = 35; - public static readonly DOT = 36; - public static readonly FALSE = 37; - public static readonly FIRST = 38; - public static readonly LAST = 39; - public static readonly LP = 40; - public static readonly IN = 41; - public static readonly IS = 42; - public static readonly LIKE = 43; - public static readonly NOT = 44; - public static readonly NULL = 45; - public static readonly NULLS = 46; - public static readonly OR = 47; - public static readonly PARAM = 48; - public static readonly RLIKE = 49; - public static readonly RP = 50; - public static readonly TRUE = 51; - public static readonly EQ = 52; - public static readonly CIEQ = 53; - public static readonly NEQ = 54; - public static readonly LT = 55; - public static readonly LTE = 56; - public static readonly GT = 57; - public static readonly GTE = 58; - public static readonly PLUS = 59; - public static readonly MINUS = 60; - public static readonly ASTERISK = 61; - public static readonly SLASH = 62; - public static readonly PERCENT = 63; - public static readonly OPENING_BRACKET = 64; - public static readonly CLOSING_BRACKET = 65; - public static readonly UNQUOTED_IDENTIFIER = 66; - public static readonly QUOTED_IDENTIFIER = 67; - public static readonly EXPR_LINE_COMMENT = 68; - public static readonly EXPR_MULTILINE_COMMENT = 69; - public static readonly EXPR_WS = 70; - public static readonly METADATA = 71; - public static readonly FROM_UNQUOTED_IDENTIFIER = 72; - public static readonly FROM_LINE_COMMENT = 73; - public static readonly FROM_MULTILINE_COMMENT = 74; - public static readonly FROM_WS = 75; - public static readonly UNQUOTED_ID_PATTERN = 76; - public static readonly PROJECT_LINE_COMMENT = 77; - public static readonly PROJECT_MULTILINE_COMMENT = 78; - public static readonly PROJECT_WS = 79; - public static readonly AS = 80; - public static readonly RENAME_LINE_COMMENT = 81; - public static readonly RENAME_MULTILINE_COMMENT = 82; - public static readonly RENAME_WS = 83; - public static readonly ON = 84; - public static readonly WITH = 85; - public static readonly ENRICH_POLICY_NAME = 86; - public static readonly ENRICH_LINE_COMMENT = 87; - public static readonly ENRICH_MULTILINE_COMMENT = 88; - public static readonly ENRICH_WS = 89; - public static readonly ENRICH_FIELD_LINE_COMMENT = 90; - public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 91; - public static readonly ENRICH_FIELD_WS = 92; - public static readonly MVEXPAND_LINE_COMMENT = 93; - public static readonly MVEXPAND_MULTILINE_COMMENT = 94; - public static readonly MVEXPAND_WS = 95; - public static readonly INFO = 96; - public static readonly FUNCTIONS = 97; - public static readonly SHOW_LINE_COMMENT = 98; - public static readonly SHOW_MULTILINE_COMMENT = 99; - public static readonly SHOW_WS = 100; - public static readonly COLON = 101; - public static readonly SETTING = 102; - public static readonly SETTING_LINE_COMMENT = 103; - public static readonly SETTTING_MULTILINE_COMMENT = 104; - public static readonly SETTING_WS = 105; + public static readonly RENAME = 12; + public static readonly ROW = 13; + public static readonly SHOW = 14; + public static readonly SORT = 15; + public static readonly STATS = 16; + public static readonly WHERE = 17; + public static readonly UNKNOWN_CMD = 18; + public static readonly LINE_COMMENT = 19; + public static readonly MULTILINE_COMMENT = 20; + public static readonly WS = 21; + public static readonly EXPLAIN_WS = 22; + public static readonly EXPLAIN_LINE_COMMENT = 23; + public static readonly EXPLAIN_MULTILINE_COMMENT = 24; + public static readonly PIPE = 25; + public static readonly STRING = 26; + public static readonly INTEGER_LITERAL = 27; + public static readonly DECIMAL_LITERAL = 28; + public static readonly BY = 29; + public static readonly AND = 30; + public static readonly ASC = 31; + public static readonly ASSIGN = 32; + public static readonly COMMA = 33; + public static readonly DESC = 34; + public static readonly DOT = 35; + public static readonly FALSE = 36; + public static readonly FIRST = 37; + public static readonly LAST = 38; + public static readonly LP = 39; + public static readonly IN = 40; + public static readonly IS = 41; + public static readonly LIKE = 42; + public static readonly NOT = 43; + public static readonly NULL = 44; + public static readonly NULLS = 45; + public static readonly OR = 46; + public static readonly PARAM = 47; + public static readonly RLIKE = 48; + public static readonly RP = 49; + public static readonly TRUE = 50; + public static readonly EQ = 51; + public static readonly CIEQ = 52; + public static readonly NEQ = 53; + public static readonly LT = 54; + public static readonly LTE = 55; + public static readonly GT = 56; + public static readonly GTE = 57; + public static readonly PLUS = 58; + public static readonly MINUS = 59; + public static readonly ASTERISK = 60; + public static readonly SLASH = 61; + public static readonly PERCENT = 62; + public static readonly OPENING_BRACKET = 63; + public static readonly CLOSING_BRACKET = 64; + public static readonly UNQUOTED_IDENTIFIER = 65; + public static readonly QUOTED_IDENTIFIER = 66; + public static readonly EXPR_LINE_COMMENT = 67; + public static readonly EXPR_MULTILINE_COMMENT = 68; + public static readonly EXPR_WS = 69; + public static readonly METADATA = 70; + public static readonly FROM_UNQUOTED_IDENTIFIER = 71; + public static readonly FROM_LINE_COMMENT = 72; + public static readonly FROM_MULTILINE_COMMENT = 73; + public static readonly FROM_WS = 74; + public static readonly UNQUOTED_ID_PATTERN = 75; + public static readonly PROJECT_LINE_COMMENT = 76; + public static readonly PROJECT_MULTILINE_COMMENT = 77; + public static readonly PROJECT_WS = 78; + public static readonly AS = 79; + public static readonly RENAME_LINE_COMMENT = 80; + public static readonly RENAME_MULTILINE_COMMENT = 81; + public static readonly RENAME_WS = 82; + public static readonly ON = 83; + public static readonly WITH = 84; + public static readonly ENRICH_POLICY_NAME = 85; + public static readonly ENRICH_LINE_COMMENT = 86; + public static readonly ENRICH_MULTILINE_COMMENT = 87; + public static readonly ENRICH_WS = 88; + public static readonly ENRICH_FIELD_LINE_COMMENT = 89; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 90; + public static readonly ENRICH_FIELD_WS = 91; + public static readonly MVEXPAND_LINE_COMMENT = 92; + public static readonly MVEXPAND_MULTILINE_COMMENT = 93; + public static readonly MVEXPAND_WS = 94; + public static readonly INFO = 95; + public static readonly FUNCTIONS = 96; + public static readonly SHOW_LINE_COMMENT = 97; + public static readonly SHOW_MULTILINE_COMMENT = 98; + public static readonly SHOW_WS = 99; + public static readonly COLON = 100; + public static readonly SETTING = 101; + public static readonly SETTING_LINE_COMMENT = 102; + public static readonly SETTTING_MULTILINE_COMMENT = 103; + public static readonly SETTING_WS = 104; public static readonly EXPLAIN_MODE = 1; public static readonly EXPRESSION_MODE = 2; public static readonly FROM_MODE = 3; @@ -147,47 +146,47 @@ export class esql_lexer extends Lexer { public static readonly ruleNames: string[] = [ "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "INLINESTATS", - "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", "SHOW", "SORT", - "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", - "WS", "EXPLAIN_OPENING_BRACKET", "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", - "EXPLAIN_MULTILINE_COMMENT", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", - "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", - "UNDERSCORE", "UNQUOTED_ID_BODY", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", - "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", - "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", - "RLIKE", "RP", "TRUE", "EQ", "CIEQ", "NEQ", "LT", "LTE", "GT", "GTE", - "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", - "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", - "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", - "FROM_COMMA", "FROM_ASSIGN", "METADATA", "FROM_UNQUOTED_IDENTIFIER_PART", - "FROM_UNQUOTED_IDENTIFIER", "FROM_QUOTED_IDENTIFIER", "FROM_LINE_COMMENT", - "FROM_MULTILINE_COMMENT", "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", - "UNQUOTED_ID_BODY_WITH_PATTERN", "UNQUOTED_ID_PATTERN", "PROJECT_UNQUOTED_IDENTIFIER", - "PROJECT_QUOTED_IDENTIFIER", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", - "PROJECT_WS", "RENAME_PIPE", "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", - "AS", "RENAME_QUOTED_IDENTIFIER", "RENAME_UNQUOTED_IDENTIFIER", "RENAME_LINE_COMMENT", - "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ENRICH_PIPE", "ENRICH_OPENING_BRACKET", - "ON", "WITH", "ENRICH_POLICY_NAME_BODY", "ENRICH_POLICY_NAME", "ENRICH_QUOTED_IDENTIFIER", - "ENRICH_MODE_UNQUOTED_VALUE", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", - "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", - "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_UNQUOTED_IDENTIFIER", - "ENRICH_FIELD_QUOTED_IDENTIFIER", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", - "ENRICH_FIELD_WS", "MVEXPAND_PIPE", "MVEXPAND_DOT", "MVEXPAND_QUOTED_IDENTIFIER", - "MVEXPAND_UNQUOTED_IDENTIFIER", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", - "MVEXPAND_WS", "SHOW_PIPE", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", - "SHOW_MULTILINE_COMMENT", "SHOW_WS", "SETTING_CLOSING_BRACKET", "COLON", - "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", "SETTING_WS", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", - "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", + "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "EXPLAIN_OPENING_BRACKET", + "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", + "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", "UNESCAPED_CHARS", "EXPONENT", + "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", "UNDERSCORE", "UNQUOTED_ID_BODY", + "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", + "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", + "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "EQ", "CIEQ", + "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", + "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", + "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", + "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", "FROM_COMMA", + "FROM_ASSIGN", "METADATA", "FROM_UNQUOTED_IDENTIFIER_PART", "FROM_UNQUOTED_IDENTIFIER", + "FROM_QUOTED_IDENTIFIER", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", "UNQUOTED_ID_BODY_WITH_PATTERN", + "UNQUOTED_ID_PATTERN", "PROJECT_UNQUOTED_IDENTIFIER", "PROJECT_QUOTED_IDENTIFIER", + "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "RENAME_PIPE", + "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", "AS", "RENAME_QUOTED_IDENTIFIER", + "RENAME_UNQUOTED_IDENTIFIER", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ENRICH_PIPE", "ENRICH_OPENING_BRACKET", "ON", "WITH", "ENRICH_POLICY_NAME_BODY", + "ENRICH_POLICY_NAME", "ENRICH_QUOTED_IDENTIFIER", "ENRICH_MODE_UNQUOTED_VALUE", + "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_PIPE", + "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", + "ENRICH_FIELD_UNQUOTED_IDENTIFIER", "ENRICH_FIELD_QUOTED_IDENTIFIER", + "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", + "MVEXPAND_PIPE", "MVEXPAND_DOT", "MVEXPAND_QUOTED_IDENTIFIER", "MVEXPAND_UNQUOTED_IDENTIFIER", + "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", + "SHOW_PIPE", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", + "SHOW_WS", "SETTING_CLOSING_BRACKET", "COLON", "SETTING", "SETTING_LINE_COMMENT", + "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "A", "B", "C", "D", "E", "F", + "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", + "U", "V", "W", "X", "Y", "Z", ]; private static readonly _LITERAL_NAMES: Array<string | undefined> = [ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, "'|'", undefined, - undefined, undefined, undefined, undefined, undefined, "'='", "','", undefined, - "'.'", undefined, undefined, undefined, "'('", undefined, undefined, undefined, + undefined, undefined, undefined, undefined, "'|'", undefined, undefined, + undefined, undefined, undefined, undefined, "'='", "','", undefined, "'.'", + undefined, undefined, undefined, "'('", undefined, undefined, undefined, undefined, undefined, undefined, undefined, "'?'", undefined, "')'", undefined, "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", undefined, "']'", undefined, undefined, undefined, undefined, @@ -199,8 +198,8 @@ export class esql_lexer extends Lexer { ]; private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [ undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", - "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", - "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", + "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", @@ -250,7 +249,7 @@ export class esql_lexer extends Lexer { private static readonly _serializedATNSegments: number = 3; private static readonly _serializedATNSegment0: string = - "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02k\u04F3\b\x01" + + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02j\u04EB\b\x01" + "\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\x04\x02\t" + "\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07\t" + "\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r\x04\x0E" + @@ -279,602 +278,598 @@ export class esql_lexer extends Lexer { "\t\xA5\x04\xA6\t\xA6\x04\xA7\t\xA7\x04\xA8\t\xA8\x04\xA9\t\xA9\x04\xAA" + "\t\xAA\x04\xAB\t\xAB\x04\xAC\t\xAC\x04\xAD\t\xAD\x04\xAE\t\xAE\x04\xAF" + "\t\xAF\x04\xB0\t\xB0\x04\xB1\t\xB1\x04\xB2\t\xB2\x04\xB3\t\xB3\x04\xB4" + - "\t\xB4\x04\xB5\t\xB5\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + - "\x02\x03\x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03" + - "\x03\x03\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + - "\x04\x03\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" + - "\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03" + - "\x06\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\b\x03" + - "\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03" + - "\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\n\x03\n\x03\n\x03\n\x03" + - "\n\x03\n\x03\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\f\x03" + - "\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\r\x03" + - "\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\x0E\x03\x0E\x03" + - "\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0F\x03\x0F\x03" + - "\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03" + - "\x10\x03\x10\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03" + - "\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x13\x03" + - "\x13\x03\x13\x03\x13\x03\x13\x03\x13\x03\x13\x03\x13\x03\x14\x06\x14\u0210" + - "\n\x14\r\x14\x0E\x14\u0211\x03\x14\x03\x14\x03\x15\x03\x15\x03\x15\x03" + - "\x15\x07\x15\u021A\n\x15\f\x15\x0E\x15\u021D\v\x15\x03\x15\x05\x15\u0220" + - "\n\x15\x03\x15\x05\x15\u0223\n\x15\x03\x15\x03\x15\x03\x16\x03\x16\x03" + - "\x16\x03\x16\x03\x16\x07\x16\u022C\n\x16\f\x16\x0E\x16\u022F\v\x16\x03" + - "\x16\x03\x16\x03\x16\x03\x16\x03\x16\x03\x17\x06\x17\u0237\n\x17\r\x17" + - "\x0E\x17\u0238\x03\x17\x03\x17\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18" + - "\x03\x19\x03\x19\x03\x19\x03\x19\x03\x19\x03\x1A\x03\x1A\x03\x1A\x03\x1A" + - "\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1D" + - "\x03\x1D\x03\x1D\x03\x1D\x03\x1E\x03\x1E\x03\x1F\x03\x1F\x03 \x03 \x03" + - " \x03!\x03!\x03\"\x03\"\x05\"\u0262\n\"\x03\"\x06\"\u0265\n\"\r\"\x0E" + - "\"\u0266\x03#\x03#\x03$\x03$\x03%\x03%\x03%\x05%\u0270\n%\x03&\x03&\x03" + - "\'\x03\'\x03\'\x05\'\u0277\n\'\x03(\x03(\x03(\x07(\u027C\n(\f(\x0E(\u027F" + - "\v(\x03(\x03(\x03(\x03(\x03(\x03(\x07(\u0287\n(\f(\x0E(\u028A\v(\x03(" + - "\x03(\x03(\x03(\x03(\x05(\u0291\n(\x03(\x05(\u0294\n(\x05(\u0296\n(\x03" + - ")\x06)\u0299\n)\r)\x0E)\u029A\x03*\x06*\u029E\n*\r*\x0E*\u029F\x03*\x03" + - "*\x07*\u02A4\n*\f*\x0E*\u02A7\v*\x03*\x03*\x06*\u02AB\n*\r*\x0E*\u02AC" + - "\x03*\x06*\u02B0\n*\r*\x0E*\u02B1\x03*\x03*\x07*\u02B6\n*\f*\x0E*\u02B9" + - "\v*\x05*\u02BB\n*\x03*\x03*\x03*\x03*\x06*\u02C1\n*\r*\x0E*\u02C2\x03" + - "*\x03*\x05*\u02C7\n*\x03+\x03+\x03+\x03,\x03,\x03,\x03,\x03-\x03-\x03" + - "-\x03-\x03.\x03.\x03/\x03/\x030\x030\x030\x030\x030\x031\x031\x032\x03" + - "2\x032\x032\x032\x032\x033\x033\x033\x033\x033\x033\x034\x034\x034\x03" + - "4\x034\x035\x035\x036\x036\x036\x037\x037\x037\x038\x038\x038\x038\x03" + - "8\x039\x039\x039\x039\x03:\x03:\x03:\x03:\x03:\x03;\x03;\x03;\x03;\x03" + - ";\x03;\x03<\x03<\x03<\x03=\x03=\x03>\x03>\x03>\x03>\x03>\x03>\x03?\x03" + - "?\x03@\x03@\x03@\x03@\x03@\x03A\x03A\x03A\x03B\x03B\x03B\x03C\x03C\x03" + - "C\x03D\x03D\x03E\x03E\x03E\x03F\x03F\x03G\x03G\x03G\x03H\x03H\x03I\x03" + - "I\x03J\x03J\x03K\x03K\x03L\x03L\x03M\x03M\x03M\x03M\x03M\x03N\x03N\x03" + - "N\x03N\x03N\x03O\x03O\x07O\u0347\nO\fO\x0EO\u034A\vO\x03O\x03O\x05O\u034E" + - "\nO\x03O\x06O\u0351\nO\rO\x0EO\u0352\x05O\u0355\nO\x03P\x03P\x06P\u0359" + - "\nP\rP\x0EP\u035A\x03P\x03P\x03Q\x03Q\x03Q\x03Q\x03R\x03R\x03R\x03R\x03" + - "S\x03S\x03S\x03S\x03T\x03T\x03T\x03T\x03T\x03U\x03U\x03U\x03U\x03V\x03" + - "V\x03V\x03V\x03W\x03W\x03W\x03W\x03X\x03X\x03X\x03X\x03Y\x03Y\x03Y\x03" + - "Y\x03Y\x03Y\x03Y\x03Y\x03Y\x03Z\x03Z\x03Z\x05Z\u038C\nZ\x03[\x06[\u038F" + - "\n[\r[\x0E[\u0390\x03\\\x03\\\x03\\\x03\\\x03]\x03]\x03]\x03]\x03^\x03" + - "^\x03^\x03^\x03_\x03_\x03_\x03_\x03`\x03`\x03`\x03`\x03`\x03a\x03a\x03" + - "a\x03a\x03b\x03b\x03b\x03b\x03c\x03c\x03c\x03c\x05c\u03B4\nc\x03d\x03" + - "d\x05d\u03B8\nd\x03d\x07d\u03BB\nd\fd\x0Ed\u03BE\vd\x03d\x03d\x05d\u03C2" + - "\nd\x03d\x06d\u03C5\nd\rd\x0Ed\u03C6\x05d\u03C9\nd\x03e\x03e\x03e\x03" + - "e\x03f\x03f\x03f\x03f\x03g\x03g\x03g\x03g\x03h\x03h\x03h\x03h\x03i\x03" + - "i\x03i\x03i\x03j\x03j\x03j\x03j\x03j\x03k\x03k\x03k\x03k\x03l\x03l\x03" + - "l\x03l\x03m\x03m\x03m\x03m\x03n\x03n\x03n\x03o\x03o\x03o\x03o\x03p\x03" + - "p\x03p\x03p\x03q\x03q\x03q\x03q\x03r\x03r\x03r\x03r\x03s\x03s\x03s\x03" + - "s\x03t\x03t\x03t\x03t\x03t\x03u\x03u\x03u\x03u\x03u\x03v\x03v\x03v\x03" + - "v\x03v\x03w\x03w\x03w\x03w\x03w\x03w\x03w\x03x\x03x\x03y\x03y\x05y\u0421" + - "\ny\x03y\x07y\u0424\ny\fy\x0Ey\u0427\vy\x03z\x03z\x03z\x03z\x03{\x03{" + - "\x03{\x03{\x03|\x03|\x03|\x03|\x03}\x03}\x03}\x03}\x03~\x03~\x03~\x03" + - "~\x03\x7F\x03\x7F\x03\x7F\x03\x7F\x03\x7F\x03\x7F\x03\x80\x03\x80\x03" + - "\x80\x03\x80\x03\x81\x03\x81\x03\x81\x03\x81\x03\x82\x03\x82\x03\x82\x03" + - "\x82\x03\x83\x03\x83\x03\x83\x03\x83\x03\x84\x03\x84\x03\x84\x03\x84\x03" + - "\x85\x03\x85\x03\x85\x03\x85\x03\x86\x03\x86\x03\x86\x03\x86\x03\x87\x03" + - "\x87\x03\x87\x03\x87\x03\x88\x03\x88\x03\x88\x03\x88\x03\x89\x03\x89\x03" + - "\x89\x03\x89\x03\x89\x03\x8A\x03\x8A\x03\x8A\x03\x8A\x03\x8B\x03\x8B\x03" + - "\x8B\x03\x8B\x03\x8C\x03\x8C\x03\x8C\x03\x8C\x03\x8D\x03\x8D\x03\x8D\x03" + - "\x8D\x03\x8E\x03\x8E\x03\x8E\x03\x8E\x03\x8F\x03\x8F\x03\x8F\x03\x8F\x03" + - "\x90\x03\x90\x03\x90\x03\x90\x03\x90\x03\x91\x03\x91\x03\x91\x03\x91\x03" + - "\x91\x03\x92\x03\x92\x03\x92\x03\x92\x03\x92\x03\x92\x03\x92\x03\x92\x03" + - "\x92\x03\x92\x03\x93\x03\x93\x03\x93\x03\x93\x03\x94\x03\x94\x03\x94\x03" + - "\x94\x03\x95\x03\x95\x03\x95\x03\x95\x03\x96\x03\x96\x03\x96\x03\x96\x03" + - "\x96\x03\x97\x03\x97\x03\x98\x03\x98\x03\x98\x03\x98\x03\x98\x06\x98\u04B0" + - "\n\x98\r\x98\x0E\x98\u04B1\x03\x99\x03\x99\x03\x99\x03\x99\x03\x9A\x03" + - "\x9A\x03\x9A\x03\x9A\x03\x9B\x03\x9B\x03\x9B\x03\x9B\x03\x9C\x03\x9C\x03" + - "\x9D\x03\x9D\x03\x9E\x03\x9E\x03\x9F\x03\x9F\x03\xA0\x03\xA0\x03\xA1\x03" + - "\xA1\x03\xA2\x03\xA2\x03\xA3\x03\xA3\x03\xA4\x03\xA4\x03\xA5\x03\xA5\x03" + - "\xA6\x03\xA6\x03\xA7\x03\xA7\x03\xA8\x03\xA8\x03\xA9\x03\xA9\x03\xAA\x03" + - "\xAA\x03\xAB\x03\xAB\x03\xAC\x03\xAC\x03\xAD\x03\xAD\x03\xAE\x03\xAE\x03" + - "\xAF\x03\xAF\x03\xB0\x03\xB0\x03\xB1\x03\xB1\x03\xB2\x03\xB2\x03\xB3\x03" + - "\xB3\x03\xB4\x03\xB4\x03\xB5\x03\xB5\x04\u022D\u0288\x02\x02\xB6\r\x02" + - "\x03\x0F\x02\x04\x11\x02\x05\x13\x02\x06\x15\x02\x07\x17\x02\b\x19\x02" + - "\t\x1B\x02\n\x1D\x02\v\x1F\x02\f!\x02\r#\x02\x0E%\x02\x0F\'\x02\x10)\x02" + - "\x11+\x02\x12-\x02\x13/\x02\x141\x02\x153\x02\x165\x02\x177\x02\x189\x02" + - "\x02;\x02\x02=\x02\x19?\x02\x1AA\x02\x1BC\x02\x1CE\x02\x02G\x02\x02I\x02" + - "\x02K\x02\x02M\x02\x02O\x02\x02Q\x02\x02S\x02\x02U\x02\x02W\x02\x02Y\x02" + - "\x1D[\x02\x1E]\x02\x1F_\x02 a\x02!c\x02\"e\x02#g\x02$i\x02%k\x02&m\x02" + - "\'o\x02(q\x02)s\x02*u\x02+w\x02,y\x02-{\x02.}\x02/\x7F\x020\x81\x021\x83" + - "\x022\x85\x023\x87\x024\x89\x025\x8B\x026\x8D\x027\x8F\x028\x91\x029\x93" + - "\x02:\x95\x02;\x97\x02<\x99\x02=\x9B\x02>\x9D\x02?\x9F\x02@\xA1\x02A\xA3" + - "\x02B\xA5\x02C\xA7\x02D\xA9\x02E\xAB\x02F\xAD\x02G\xAF\x02H\xB1\x02\x02" + - "\xB3\x02\x02\xB5\x02\x02\xB7\x02\x02\xB9\x02\x02\xBB\x02I\xBD\x02\x02" + - "\xBF\x02J\xC1\x02\x02\xC3\x02K\xC5\x02L\xC7\x02M\xC9\x02\x02\xCB\x02\x02" + - "\xCD\x02\x02\xCF\x02\x02\xD1\x02N\xD3\x02\x02\xD5\x02\x02\xD7\x02O\xD9" + - "\x02P\xDB\x02Q\xDD\x02\x02\xDF\x02\x02\xE1\x02\x02\xE3\x02\x02\xE5\x02" + - "R\xE7\x02\x02\xE9\x02\x02\xEB\x02S\xED\x02T\xEF\x02U\xF1\x02\x02\xF3\x02" + - "\x02\xF5\x02V\xF7\x02W\xF9\x02\x02\xFB\x02X\xFD\x02\x02\xFF\x02\x02\u0101" + - "\x02Y\u0103\x02Z\u0105\x02[\u0107\x02\x02\u0109\x02\x02\u010B\x02\x02" + - "\u010D\x02\x02\u010F\x02\x02\u0111\x02\x02\u0113\x02\x02\u0115\x02\\\u0117" + - "\x02]\u0119\x02^\u011B\x02\x02\u011D\x02\x02\u011F\x02\x02\u0121\x02\x02" + - "\u0123\x02_\u0125\x02`\u0127\x02a\u0129\x02\x02\u012B\x02b\u012D\x02c" + - "\u012F\x02d\u0131\x02e\u0133\x02f\u0135\x02\x02\u0137\x02g\u0139\x02h" + - "\u013B\x02i\u013D\x02j\u013F\x02k\u0141\x02\x02\u0143\x02\x02\u0145\x02" + - "\x02\u0147\x02\x02\u0149\x02\x02\u014B\x02\x02\u014D\x02\x02\u014F\x02" + - "\x02\u0151\x02\x02\u0153\x02\x02\u0155\x02\x02\u0157\x02\x02\u0159\x02" + - "\x02\u015B\x02\x02\u015D\x02\x02\u015F\x02\x02\u0161\x02\x02\u0163\x02" + - "\x02\u0165\x02\x02\u0167\x02\x02\u0169\x02\x02\u016B\x02\x02\u016D\x02" + - "\x02\u016F\x02\x02\u0171\x02\x02\u0173\x02\x02\r\x02\x03\x04\x05\x06\x07" + - "\b\t\n\v\f(\b\x02\v\f\x0F\x0F\"\"11]]__\x04\x02\f\f\x0F\x0F\x05\x02\v" + - "\f\x0F\x0F\"\"\x03\x022;\x04\x02C\\c|\x07\x02$$^^ppttvv\x06\x02\f\f\x0F" + - "\x0F$$^^\x04\x02GGgg\x04\x02--//\x03\x02bb\f\x02\v\f\x0F\x0F\"\"..11?" + - "?]]__bb~~\x04\x02,,11\r\x02\v\f\x0F\x0F\"\"$%..11<<>>@A^^~~\x04\x02CC" + - "cc\x04\x02DDdd\x04\x02EEee\x04\x02FFff\x04\x02HHhh\x04\x02IIii\x04\x02" + - "JJjj\x04\x02KKkk\x04\x02LLll\x04\x02MMmm\x04\x02NNnn\x04\x02OOoo\x04\x02" + - "PPpp\x04\x02QQqq\x04\x02RRrr\x04\x02SSss\x04\x02TTtt\x04\x02UUuu\x04\x02" + - "VVvv\x04\x02WWww\x04\x02XXxx\x04\x02YYyy\x04\x02ZZzz\x04\x02[[{{\x04\x02" + - "\\\\||\x02\u04F4\x02\r\x03\x02\x02\x02\x02\x0F\x03\x02\x02\x02\x02\x11" + - "\x03\x02\x02\x02\x02\x13\x03\x02\x02\x02\x02\x15\x03\x02\x02\x02\x02\x17" + - "\x03\x02\x02\x02\x02\x19\x03\x02\x02\x02\x02\x1B\x03\x02\x02\x02\x02\x1D" + - "\x03\x02\x02\x02\x02\x1F\x03\x02\x02\x02\x02!\x03\x02\x02\x02\x02#\x03" + - "\x02\x02\x02\x02%\x03\x02\x02\x02\x02\'\x03\x02\x02\x02\x02)\x03\x02\x02" + - "\x02\x02+\x03\x02\x02\x02\x02-\x03\x02\x02\x02\x02/\x03\x02\x02\x02\x02" + - "1\x03\x02\x02\x02\x023\x03\x02\x02\x02\x025\x03\x02\x02\x02\x027\x03\x02" + - "\x02\x02\x039\x03\x02\x02\x02\x03;\x03\x02\x02\x02\x03=\x03\x02\x02\x02" + - "\x03?\x03\x02\x02\x02\x03A\x03\x02\x02\x02\x04C\x03\x02\x02\x02\x04Y\x03" + - "\x02\x02\x02\x04[\x03\x02\x02\x02\x04]\x03\x02\x02\x02\x04_\x03\x02\x02" + - "\x02\x04a\x03\x02\x02\x02\x04c\x03\x02\x02\x02\x04e\x03\x02\x02\x02\x04" + - "g\x03\x02\x02\x02\x04i\x03\x02\x02\x02\x04k\x03\x02\x02\x02\x04m\x03\x02" + - "\x02\x02\x04o\x03\x02\x02\x02\x04q\x03\x02\x02\x02\x04s\x03\x02\x02\x02" + - "\x04u\x03\x02\x02\x02\x04w\x03\x02\x02\x02\x04y\x03\x02\x02\x02\x04{\x03" + - "\x02\x02\x02\x04}\x03\x02\x02\x02\x04\x7F\x03\x02\x02\x02\x04\x81\x03" + - "\x02\x02\x02\x04\x83\x03\x02\x02\x02\x04\x85\x03\x02\x02\x02\x04\x87\x03" + - "\x02\x02\x02\x04\x89\x03\x02\x02\x02\x04\x8B\x03\x02\x02\x02\x04\x8D\x03" + - "\x02\x02\x02\x04\x8F\x03\x02\x02\x02\x04\x91\x03\x02\x02\x02\x04\x93\x03" + - "\x02\x02\x02\x04\x95\x03\x02\x02\x02\x04\x97\x03\x02\x02\x02\x04\x99\x03" + - "\x02\x02\x02\x04\x9B\x03\x02\x02\x02\x04\x9D\x03\x02\x02\x02\x04\x9F\x03" + - "\x02\x02\x02\x04\xA1\x03\x02\x02\x02\x04\xA3\x03\x02\x02\x02\x04\xA5\x03" + - "\x02\x02\x02\x04\xA7\x03\x02\x02\x02\x04\xA9\x03\x02\x02\x02\x04\xAB\x03" + - "\x02\x02\x02\x04\xAD\x03\x02\x02\x02\x04\xAF\x03\x02\x02\x02\x05\xB1\x03" + - "\x02\x02\x02\x05\xB3\x03\x02\x02\x02\x05\xB5\x03\x02\x02\x02\x05\xB7\x03" + - "\x02\x02\x02\x05\xB9\x03\x02\x02\x02\x05\xBB\x03\x02\x02\x02\x05\xBF\x03" + - "\x02\x02\x02\x05\xC1\x03\x02\x02\x02\x05\xC3\x03\x02\x02\x02\x05\xC5\x03" + - "\x02\x02\x02\x05\xC7\x03\x02\x02\x02\x06\xC9\x03\x02\x02\x02\x06\xCB\x03" + - "\x02\x02\x02\x06\xCD\x03\x02\x02\x02\x06\xD1\x03\x02\x02\x02\x06\xD3\x03" + - "\x02\x02\x02\x06\xD5\x03\x02\x02\x02\x06\xD7\x03\x02\x02\x02\x06\xD9\x03" + - "\x02\x02\x02\x06\xDB\x03\x02\x02\x02\x07\xDD\x03\x02\x02\x02\x07\xDF\x03" + - "\x02\x02\x02\x07\xE1\x03\x02\x02\x02\x07\xE3\x03\x02\x02\x02\x07\xE5\x03" + - "\x02\x02\x02\x07\xE7\x03\x02\x02\x02\x07\xE9\x03\x02\x02\x02\x07\xEB\x03" + - "\x02\x02\x02\x07\xED\x03\x02\x02\x02\x07\xEF\x03\x02\x02\x02\b\xF1\x03" + - "\x02\x02\x02\b\xF3\x03\x02\x02\x02\b\xF5\x03\x02\x02\x02\b\xF7\x03\x02" + - "\x02\x02\b\xFB\x03\x02\x02\x02\b\xFD\x03\x02\x02\x02\b\xFF\x03\x02\x02" + - "\x02\b\u0101\x03\x02\x02\x02\b\u0103\x03\x02\x02\x02\b\u0105\x03\x02\x02" + - "\x02\t\u0107\x03\x02\x02\x02\t\u0109\x03\x02\x02\x02\t\u010B\x03\x02\x02" + - "\x02\t\u010D\x03\x02\x02\x02\t\u010F\x03\x02\x02\x02\t\u0111\x03\x02\x02" + - "\x02\t\u0113\x03\x02\x02\x02\t\u0115\x03\x02\x02\x02\t\u0117\x03\x02\x02" + - "\x02\t\u0119\x03\x02\x02\x02\n\u011B\x03\x02\x02\x02\n\u011D\x03\x02\x02" + - "\x02\n\u011F\x03\x02\x02\x02\n\u0121\x03\x02\x02\x02\n\u0123\x03\x02\x02" + - "\x02\n\u0125\x03\x02\x02\x02\n\u0127\x03\x02\x02\x02\v\u0129\x03\x02\x02" + - "\x02\v\u012B\x03\x02\x02\x02\v\u012D\x03\x02\x02\x02\v\u012F\x03\x02\x02" + - "\x02\v\u0131\x03\x02\x02\x02\v\u0133\x03\x02\x02\x02\f\u0135\x03\x02\x02" + - "\x02\f\u0137\x03\x02\x02\x02\f\u0139\x03\x02\x02\x02\f\u013B\x03\x02\x02" + - "\x02\f\u013D\x03\x02\x02\x02\f\u013F\x03\x02\x02\x02\r\u0175\x03\x02\x02" + - "\x02\x0F\u017F\x03\x02\x02\x02\x11\u0186\x03\x02\x02\x02\x13\u018F\x03" + - "\x02\x02\x02\x15\u0196\x03\x02\x02\x02\x17\u01A0\x03\x02\x02\x02\x19\u01A7" + - "\x03\x02\x02\x02\x1B\u01AE\x03\x02\x02\x02\x1D\u01BC\x03\x02\x02\x02\x1F" + - "\u01C3\x03\x02\x02\x02!\u01CB\x03\x02\x02\x02#\u01D7\x03\x02\x02\x02%" + - "\u01E1\x03\x02\x02\x02\'\u01EA\x03\x02\x02\x02)\u01F0\x03\x02\x02\x02" + - "+\u01F7\x03\x02\x02\x02-\u01FE\x03\x02\x02\x02/\u0206\x03\x02\x02\x02" + - "1\u020F\x03\x02\x02\x023\u0215\x03\x02\x02\x025\u0226\x03\x02\x02\x02" + - "7\u0236\x03\x02\x02\x029\u023C\x03\x02\x02\x02;\u0241\x03\x02\x02\x02" + - "=\u0246\x03\x02\x02\x02?\u024A\x03\x02\x02\x02A\u024E\x03\x02\x02\x02" + - "C\u0252\x03\x02\x02\x02E\u0256\x03\x02\x02\x02G\u0258\x03\x02\x02\x02" + - "I\u025A\x03\x02\x02\x02K\u025D\x03\x02\x02\x02M\u025F\x03\x02\x02\x02" + - "O\u0268\x03\x02\x02\x02Q\u026A\x03\x02\x02\x02S\u026F\x03\x02\x02\x02" + - "U\u0271\x03\x02\x02\x02W\u0276\x03\x02\x02\x02Y\u0295\x03\x02\x02\x02" + - "[\u0298\x03\x02\x02\x02]\u02C6\x03\x02\x02\x02_\u02C8\x03\x02\x02\x02" + - "a\u02CB\x03\x02\x02\x02c\u02CF\x03\x02\x02\x02e\u02D3\x03\x02\x02\x02" + - "g\u02D5\x03\x02\x02\x02i\u02D7\x03\x02\x02\x02k\u02DC\x03\x02\x02\x02" + - "m\u02DE\x03\x02\x02\x02o\u02E4\x03\x02\x02\x02q\u02EA\x03\x02\x02\x02" + - "s\u02EF\x03\x02\x02\x02u\u02F1\x03\x02\x02\x02w\u02F4\x03\x02\x02\x02" + - "y\u02F7\x03\x02\x02\x02{\u02FC\x03\x02\x02\x02}\u0300\x03\x02\x02\x02" + - "\x7F\u0305\x03\x02\x02\x02\x81\u030B\x03\x02\x02\x02\x83\u030E\x03\x02" + - "\x02\x02\x85\u0310\x03\x02\x02\x02\x87\u0316\x03\x02\x02\x02\x89\u0318" + - "\x03\x02\x02\x02\x8B\u031D\x03\x02\x02\x02\x8D\u0320\x03\x02\x02\x02\x8F" + - "\u0323\x03\x02\x02\x02\x91\u0326\x03\x02\x02\x02\x93\u0328\x03\x02\x02" + - "\x02\x95\u032B\x03\x02\x02\x02\x97\u032D\x03\x02\x02\x02\x99\u0330\x03" + - "\x02\x02\x02\x9B\u0332\x03\x02\x02\x02\x9D\u0334\x03\x02\x02\x02\x9F\u0336" + - "\x03\x02\x02\x02\xA1\u0338\x03\x02\x02\x02\xA3\u033A\x03\x02\x02\x02\xA5" + - "\u033F\x03\x02\x02\x02\xA7\u0354\x03\x02\x02\x02\xA9\u0356\x03\x02\x02" + - "\x02\xAB\u035E\x03\x02\x02\x02\xAD\u0362\x03\x02\x02\x02\xAF\u0366\x03" + - "\x02\x02\x02\xB1\u036A\x03\x02\x02\x02\xB3\u036F\x03\x02\x02\x02\xB5\u0373" + - "\x03\x02\x02\x02\xB7\u0377\x03\x02\x02\x02\xB9\u037B\x03\x02\x02\x02\xBB" + - "\u037F\x03\x02\x02\x02\xBD\u038B\x03\x02\x02\x02\xBF\u038E\x03\x02\x02" + - "\x02\xC1\u0392\x03\x02\x02\x02\xC3\u0396\x03\x02\x02\x02\xC5\u039A\x03" + - "\x02\x02\x02\xC7\u039E\x03\x02\x02\x02\xC9\u03A2\x03\x02\x02\x02\xCB\u03A7" + - "\x03\x02\x02\x02\xCD\u03AB\x03\x02\x02\x02\xCF\u03B3\x03\x02\x02\x02\xD1" + - "\u03C8\x03\x02\x02\x02\xD3\u03CA\x03\x02\x02\x02\xD5\u03CE\x03\x02\x02" + - "\x02\xD7\u03D2\x03\x02\x02\x02\xD9\u03D6\x03\x02\x02\x02\xDB\u03DA\x03" + - "\x02\x02\x02\xDD\u03DE\x03\x02\x02\x02\xDF\u03E3\x03\x02\x02\x02\xE1\u03E7" + - "\x03\x02\x02\x02\xE3\u03EB\x03\x02\x02\x02\xE5\u03EF\x03\x02\x02\x02\xE7" + - "\u03F2\x03\x02\x02\x02\xE9\u03F6\x03\x02\x02\x02\xEB\u03FA\x03\x02\x02" + - "\x02\xED\u03FE\x03\x02\x02\x02\xEF\u0402\x03\x02\x02\x02\xF1\u0406\x03" + - "\x02\x02\x02\xF3\u040B\x03\x02\x02\x02\xF5\u0410\x03\x02\x02\x02\xF7\u0415" + - "\x03\x02\x02\x02\xF9\u041C\x03"; + "\t\xB4\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x06\x03\x06" + + "\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x07" + + "\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\b\x03\b\x03\b\x03" + + "\b\x03\b\x03\b\x03\b\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03" + + "\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03" + + "\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\f\x03\f\x03\f\x03" + + "\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03" + + "\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E" + + "\x03\x0E\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x10" + + "\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03\x11\x03\x11\x03\x11" + + "\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x12\x03\x12\x03\x12\x03\x12" + + "\x03\x12\x03\x12\x03\x12\x03\x12\x03\x13\x06\x13\u0204\n\x13\r\x13\x0E" + + "\x13\u0205\x03\x13\x03\x13\x03\x14\x03\x14\x03\x14\x03\x14\x07\x14\u020E" + + "\n\x14\f\x14\x0E\x14\u0211\v\x14\x03\x14\x05\x14\u0214\n\x14\x03\x14\x05" + + "\x14\u0217\n\x14\x03\x14\x03\x14\x03\x15\x03\x15\x03\x15\x03\x15\x03\x15" + + "\x07\x15\u0220\n\x15\f\x15\x0E\x15\u0223\v\x15\x03\x15\x03\x15\x03\x15" + + "\x03\x15\x03\x15\x03\x16\x06\x16\u022B\n\x16\r\x16\x0E\x16\u022C\x03\x16" + + "\x03\x16\x03\x17\x03\x17\x03\x17\x03\x17\x03\x17\x03\x18\x03\x18\x03\x18" + + "\x03\x18\x03\x18\x03\x19\x03\x19\x03\x19\x03\x19\x03\x1A\x03\x1A\x03\x1A" + + "\x03\x1A\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1C\x03\x1C\x03\x1C\x03\x1C" + + "\x03\x1D\x03\x1D\x03\x1E\x03\x1E\x03\x1F\x03\x1F\x03\x1F\x03 \x03 \x03" + + "!\x03!\x05!\u0256\n!\x03!\x06!\u0259\n!\r!\x0E!\u025A\x03\"\x03\"\x03" + + "#\x03#\x03$\x03$\x03$\x05$\u0264\n$\x03%\x03%\x03&\x03&\x03&\x05&\u026B" + + "\n&\x03\'\x03\'\x03\'\x07\'\u0270\n\'\f\'\x0E\'\u0273\v\'\x03\'\x03\'" + + "\x03\'\x03\'\x03\'\x03\'\x07\'\u027B\n\'\f\'\x0E\'\u027E\v\'\x03\'\x03" + + "\'\x03\'\x03\'\x03\'\x05\'\u0285\n\'\x03\'\x05\'\u0288\n\'\x05\'\u028A" + + "\n\'\x03(\x06(\u028D\n(\r(\x0E(\u028E\x03)\x06)\u0292\n)\r)\x0E)\u0293" + + "\x03)\x03)\x07)\u0298\n)\f)\x0E)\u029B\v)\x03)\x03)\x06)\u029F\n)\r)\x0E" + + ")\u02A0\x03)\x06)\u02A4\n)\r)\x0E)\u02A5\x03)\x03)\x07)\u02AA\n)\f)\x0E" + + ")\u02AD\v)\x05)\u02AF\n)\x03)\x03)\x03)\x03)\x06)\u02B5\n)\r)\x0E)\u02B6" + + "\x03)\x03)\x05)\u02BB\n)\x03*\x03*\x03*\x03+\x03+\x03+\x03+\x03,\x03," + + "\x03,\x03,\x03-\x03-\x03.\x03.\x03/\x03/\x03/\x03/\x03/\x030\x030\x03" + + "1\x031\x031\x031\x031\x031\x032\x032\x032\x032\x032\x032\x033\x033\x03" + + "3\x033\x033\x034\x034\x035\x035\x035\x036\x036\x036\x037\x037\x037\x03" + + "7\x037\x038\x038\x038\x038\x039\x039\x039\x039\x039\x03:\x03:\x03:\x03" + + ":\x03:\x03:\x03;\x03;\x03;\x03<\x03<\x03=\x03=\x03=\x03=\x03=\x03=\x03" + + ">\x03>\x03?\x03?\x03?\x03?\x03?\x03@\x03@\x03@\x03A\x03A\x03A\x03B\x03" + + "B\x03B\x03C\x03C\x03D\x03D\x03D\x03E\x03E\x03F\x03F\x03F\x03G\x03G\x03" + + "H\x03H\x03I\x03I\x03J\x03J\x03K\x03K\x03L\x03L\x03L\x03L\x03L\x03M\x03" + + "M\x03M\x03M\x03M\x03N\x03N\x07N\u033B\nN\fN\x0EN\u033E\vN\x03N\x03N\x05" + + "N\u0342\nN\x03N\x06N\u0345\nN\rN\x0EN\u0346\x05N\u0349\nN\x03O\x03O\x06" + + "O\u034D\nO\rO\x0EO\u034E\x03O\x03O\x03P\x03P\x03P\x03P\x03Q\x03Q\x03Q" + + "\x03Q\x03R\x03R\x03R\x03R\x03S\x03S\x03S\x03S\x03S\x03T\x03T\x03T\x03" + + "T\x03U\x03U\x03U\x03U\x03V\x03V\x03V\x03V\x03W\x03W\x03W\x03W\x03X\x03" + + "X\x03X\x03X\x03X\x03X\x03X\x03X\x03X\x03Y\x03Y\x03Y\x05Y\u0380\nY\x03" + + "Z\x06Z\u0383\nZ\rZ\x0EZ\u0384\x03[\x03[\x03[\x03[\x03\\\x03\\\x03\\\x03" + + "\\\x03]\x03]\x03]\x03]\x03^\x03^\x03^\x03^\x03_\x03_\x03_\x03_\x03_\x03" + + "`\x03`\x03`\x03`\x03a\x03a\x03a\x03a\x03b\x03b\x03b\x03b\x05b\u03A8\n" + + "b\x03c\x03c\x05c\u03AC\nc\x03c\x07c\u03AF\nc\fc\x0Ec\u03B2\vc\x03c\x03" + + "c\x05c\u03B6\nc\x03c\x06c\u03B9\nc\rc\x0Ec\u03BA\x05c\u03BD\nc\x03d\x03" + + "d\x03d\x03d\x03e\x03e\x03e\x03e\x03f\x03f\x03f\x03f\x03g\x03g\x03g\x03" + + "g\x03h\x03h\x03h\x03h\x03i\x03i\x03i\x03i\x03i\x03j\x03j\x03j\x03j\x03" + + "k\x03k\x03k\x03k\x03l\x03l\x03l\x03l\x03m\x03m\x03m\x03n\x03n\x03n\x03" + + "n\x03o\x03o\x03o\x03o\x03p\x03p\x03p\x03p\x03q\x03q\x03q\x03q\x03r\x03" + + "r\x03r\x03r\x03s\x03s\x03s\x03s\x03s\x03t\x03t\x03t\x03t\x03t\x03u\x03" + + "u\x03u\x03u\x03u\x03v\x03v\x03v\x03v\x03v\x03v\x03v\x03w\x03w\x03x\x06" + + "x\u0414\nx\rx\x0Ex\u0415\x03x\x03x\x05x\u041A\nx\x03x\x06x\u041D\nx\r" + + "x\x0Ex\u041E\x03y\x03y\x03y\x03y\x03z\x03z\x03z\x03z\x03{\x03{\x03{\x03" + + "{\x03|\x03|\x03|\x03|\x03}\x03}\x03}\x03}\x03~\x03~\x03~\x03~\x03~\x03" + + "~\x03\x7F\x03\x7F\x03\x7F\x03\x7F\x03\x80\x03\x80\x03\x80\x03\x80\x03" + + "\x81\x03\x81\x03\x81\x03\x81\x03\x82\x03\x82\x03\x82\x03\x82\x03\x83\x03" + + "\x83\x03\x83\x03\x83\x03\x84\x03\x84\x03\x84\x03\x84\x03\x85\x03\x85\x03" + + "\x85\x03\x85\x03\x86\x03\x86\x03\x86\x03\x86\x03\x87\x03\x87\x03\x87\x03" + + "\x87\x03\x88\x03\x88\x03\x88\x03\x88\x03\x88\x03\x89\x03\x89\x03\x89\x03" + + "\x89\x03\x8A\x03\x8A\x03\x8A\x03\x8A\x03\x8B\x03\x8B\x03\x8B\x03\x8B\x03" + + "\x8C\x03\x8C\x03\x8C\x03\x8C\x03\x8D\x03\x8D\x03\x8D\x03\x8D\x03\x8E\x03" + + "\x8E\x03\x8E\x03\x8E\x03\x8F\x03\x8F\x03\x8F\x03\x8F\x03\x8F\x03\x90\x03" + + "\x90\x03\x90\x03\x90\x03\x90\x03\x91\x03\x91\x03\x91\x03\x91\x03\x91\x03" + + "\x91\x03\x91\x03\x91\x03\x91\x03\x91\x03\x92\x03\x92\x03\x92\x03\x92\x03" + + "\x93\x03\x93\x03\x93\x03\x93\x03\x94\x03\x94\x03\x94\x03\x94\x03\x95\x03" + + "\x95\x03\x95\x03\x95\x03\x95\x03\x96\x03\x96\x03\x97\x03\x97\x03\x97\x03" + + "\x97\x03\x97\x06\x97\u04A8\n\x97\r\x97\x0E\x97\u04A9\x03\x98\x03\x98\x03" + + "\x98\x03\x98\x03\x99\x03\x99\x03\x99\x03\x99\x03\x9A\x03\x9A\x03\x9A\x03" + + "\x9A\x03\x9B\x03\x9B\x03\x9C\x03\x9C\x03\x9D\x03\x9D\x03\x9E\x03\x9E\x03" + + "\x9F\x03\x9F\x03\xA0\x03\xA0\x03\xA1\x03\xA1\x03\xA2\x03\xA2\x03\xA3\x03" + + "\xA3\x03\xA4\x03\xA4\x03\xA5\x03\xA5\x03\xA6\x03\xA6\x03\xA7\x03\xA7\x03" + + "\xA8\x03\xA8\x03\xA9\x03\xA9\x03\xAA\x03\xAA\x03\xAB\x03\xAB\x03\xAC\x03" + + "\xAC\x03\xAD\x03\xAD\x03\xAE\x03\xAE\x03\xAF\x03\xAF\x03\xB0\x03\xB0\x03" + + "\xB1\x03\xB1\x03\xB2\x03\xB2\x03\xB3\x03\xB3\x03\xB4\x03\xB4\x04\u0221" + + "\u027C\x02\x02\xB5\r\x02\x03\x0F\x02\x04\x11\x02\x05\x13\x02\x06\x15\x02" + + "\x07\x17\x02\b\x19\x02\t\x1B\x02\n\x1D\x02\v\x1F\x02\f!\x02\r#\x02\x0E" + + "%\x02\x0F\'\x02\x10)\x02\x11+\x02\x12-\x02\x13/\x02\x141\x02\x153\x02" + + "\x165\x02\x177\x02\x029\x02\x02;\x02\x18=\x02\x19?\x02\x1AA\x02\x1BC\x02" + + "\x02E\x02\x02G\x02\x02I\x02\x02K\x02\x02M\x02\x02O\x02\x02Q\x02\x02S\x02" + + "\x02U\x02\x02W\x02\x1CY\x02\x1D[\x02\x1E]\x02\x1F_\x02 a\x02!c\x02\"e" + + "\x02#g\x02$i\x02%k\x02&m\x02\'o\x02(q\x02)s\x02*u\x02+w\x02,y\x02-{\x02" + + ".}\x02/\x7F\x020\x81\x021\x83\x022\x85\x023\x87\x024\x89\x025\x8B\x02" + + "6\x8D\x027\x8F\x028\x91\x029\x93\x02:\x95\x02;\x97\x02<\x99\x02=\x9B\x02" + + ">\x9D\x02?\x9F\x02@\xA1\x02A\xA3\x02B\xA5\x02C\xA7\x02D\xA9\x02E\xAB\x02" + + "F\xAD\x02G\xAF\x02\x02\xB1\x02\x02\xB3\x02\x02\xB5\x02\x02\xB7\x02\x02" + + "\xB9\x02H\xBB\x02\x02\xBD\x02I\xBF\x02\x02\xC1\x02J\xC3\x02K\xC5\x02L" + + "\xC7\x02\x02\xC9\x02\x02\xCB\x02\x02\xCD\x02\x02\xCF\x02M\xD1\x02\x02" + + "\xD3\x02\x02\xD5\x02N\xD7\x02O\xD9\x02P\xDB\x02\x02\xDD\x02\x02\xDF\x02" + + "\x02\xE1\x02\x02\xE3\x02Q\xE5\x02\x02\xE7\x02\x02\xE9\x02R\xEB\x02S\xED" + + "\x02T\xEF\x02\x02\xF1\x02\x02\xF3\x02U\xF5\x02V\xF7\x02\x02\xF9\x02W\xFB" + + "\x02\x02\xFD\x02\x02\xFF\x02X\u0101\x02Y\u0103\x02Z\u0105\x02\x02\u0107" + + "\x02\x02\u0109\x02\x02\u010B\x02\x02\u010D\x02\x02\u010F\x02\x02\u0111" + + "\x02\x02\u0113\x02[\u0115\x02\\\u0117\x02]\u0119\x02\x02\u011B\x02\x02" + + "\u011D\x02\x02\u011F\x02\x02\u0121\x02^\u0123\x02_\u0125\x02`\u0127\x02" + + "\x02\u0129\x02a\u012B\x02b\u012D\x02c\u012F\x02d\u0131\x02e\u0133\x02" + + "\x02\u0135\x02f\u0137\x02g\u0139\x02h\u013B\x02i\u013D\x02j\u013F\x02" + + "\x02\u0141\x02\x02\u0143\x02\x02\u0145\x02\x02\u0147\x02\x02\u0149\x02" + + "\x02\u014B\x02\x02\u014D\x02\x02\u014F\x02\x02\u0151\x02\x02\u0153\x02" + + "\x02\u0155\x02\x02\u0157\x02\x02\u0159\x02\x02\u015B\x02\x02\u015D\x02" + + "\x02\u015F\x02\x02\u0161\x02\x02\u0163\x02\x02\u0165\x02\x02\u0167\x02" + + "\x02\u0169\x02\x02\u016B\x02\x02\u016D\x02\x02\u016F\x02\x02\u0171\x02" + + "\x02\r\x02\x03\x04\x05\x06\x07\b\t\n\v\f(\b\x02\v\f\x0F\x0F\"\"11]]__" + + "\x04\x02\f\f\x0F\x0F\x05\x02\v\f\x0F\x0F\"\"\x03\x022;\x04\x02C\\c|\x07" + + "\x02$$^^ppttvv\x06\x02\f\f\x0F\x0F$$^^\x04\x02GGgg\x04\x02--//\x03\x02" + + "bb\f\x02\v\f\x0F\x0F\"\"..11??]]__bb~~\x04\x02,,11\r\x02\v\f\x0F\x0F\"" + + "\"$%..11<<>>@A^^~~\x04\x02CCcc\x04\x02DDdd\x04\x02EEee\x04\x02FFff\x04" + + "\x02HHhh\x04\x02IIii\x04\x02JJjj\x04\x02KKkk\x04\x02LLll\x04\x02MMmm\x04" + + "\x02NNnn\x04\x02OOoo\x04\x02PPpp\x04\x02QQqq\x04\x02RRrr\x04\x02SSss\x04" + + "\x02TTtt\x04\x02UUuu\x04\x02VVvv\x04\x02WWww\x04\x02XXxx\x04\x02YYyy\x04" + + "\x02ZZzz\x04\x02[[{{\x04\x02\\\\||\x02\u04ED\x02\r\x03\x02\x02\x02\x02" + + "\x0F\x03\x02\x02\x02\x02\x11\x03\x02\x02\x02\x02\x13\x03\x02\x02\x02\x02" + + "\x15\x03\x02\x02\x02\x02\x17\x03\x02\x02\x02\x02\x19\x03\x02\x02\x02\x02" + + "\x1B\x03\x02\x02\x02\x02\x1D\x03\x02\x02\x02\x02\x1F\x03\x02\x02\x02\x02" + + "!\x03\x02\x02\x02\x02#\x03\x02\x02\x02\x02%\x03\x02\x02\x02\x02\'\x03" + + "\x02\x02\x02\x02)\x03\x02\x02\x02\x02+\x03\x02\x02\x02\x02-\x03\x02\x02" + + "\x02\x02/\x03\x02\x02\x02\x021\x03\x02\x02\x02\x023\x03\x02\x02\x02\x02" + + "5\x03\x02\x02\x02\x037\x03\x02\x02\x02\x039\x03\x02\x02\x02\x03;\x03\x02" + + "\x02\x02\x03=\x03\x02\x02\x02\x03?\x03\x02\x02\x02\x04A\x03\x02\x02\x02" + + "\x04W\x03\x02\x02\x02\x04Y\x03\x02\x02\x02\x04[\x03\x02\x02\x02\x04]\x03" + + "\x02\x02\x02\x04_\x03\x02\x02\x02\x04a\x03\x02\x02\x02\x04c\x03\x02\x02" + + "\x02\x04e\x03\x02\x02\x02\x04g\x03\x02\x02\x02\x04i\x03\x02\x02\x02\x04" + + "k\x03\x02\x02\x02\x04m\x03\x02\x02\x02\x04o\x03\x02\x02\x02\x04q\x03\x02" + + "\x02\x02\x04s\x03\x02\x02\x02\x04u\x03\x02\x02\x02\x04w\x03\x02\x02\x02" + + "\x04y\x03\x02\x02\x02\x04{\x03\x02\x02\x02\x04}\x03\x02\x02\x02\x04\x7F" + + "\x03\x02\x02\x02\x04\x81\x03\x02\x02\x02\x04\x83\x03\x02\x02\x02\x04\x85" + + "\x03\x02\x02\x02\x04\x87\x03\x02\x02\x02\x04\x89\x03\x02\x02\x02\x04\x8B" + + "\x03\x02\x02\x02\x04\x8D\x03\x02\x02\x02\x04\x8F\x03\x02\x02\x02\x04\x91" + + "\x03\x02\x02\x02\x04\x93\x03\x02\x02\x02\x04\x95\x03\x02\x02\x02\x04\x97" + + "\x03\x02\x02\x02\x04\x99\x03\x02\x02\x02\x04\x9B\x03\x02\x02\x02\x04\x9D" + + "\x03\x02\x02\x02\x04\x9F\x03\x02\x02\x02\x04\xA1\x03\x02\x02\x02\x04\xA3" + + "\x03\x02\x02\x02\x04\xA5\x03\x02\x02\x02\x04\xA7\x03\x02\x02\x02\x04\xA9" + + "\x03\x02\x02\x02\x04\xAB\x03\x02\x02\x02\x04\xAD\x03\x02\x02\x02\x05\xAF" + + "\x03\x02\x02\x02\x05\xB1\x03\x02\x02\x02\x05\xB3\x03\x02\x02\x02\x05\xB5" + + "\x03\x02\x02\x02\x05\xB7\x03\x02\x02\x02\x05\xB9\x03\x02\x02\x02\x05\xBD" + + "\x03\x02\x02\x02\x05\xBF\x03\x02\x02\x02\x05\xC1\x03\x02\x02\x02\x05\xC3" + + "\x03\x02\x02\x02\x05\xC5\x03\x02\x02\x02\x06\xC7\x03\x02\x02\x02\x06\xC9" + + "\x03\x02\x02\x02\x06\xCB\x03\x02\x02\x02\x06\xCF\x03\x02\x02\x02\x06\xD1" + + "\x03\x02\x02\x02\x06\xD3\x03\x02\x02\x02\x06\xD5\x03\x02\x02\x02\x06\xD7" + + "\x03\x02\x02\x02\x06\xD9\x03\x02\x02\x02\x07\xDB\x03\x02\x02\x02\x07\xDD" + + "\x03\x02\x02\x02\x07\xDF\x03\x02\x02\x02\x07\xE1\x03\x02\x02\x02\x07\xE3" + + "\x03\x02\x02\x02\x07\xE5\x03\x02\x02\x02\x07\xE7\x03\x02\x02\x02\x07\xE9" + + "\x03\x02\x02\x02\x07\xEB\x03\x02\x02\x02\x07\xED\x03\x02\x02\x02\b\xEF" + + "\x03\x02\x02\x02\b\xF1\x03\x02\x02\x02\b\xF3\x03\x02\x02\x02\b\xF5\x03" + + "\x02\x02\x02\b\xF9\x03\x02\x02\x02\b\xFB\x03\x02\x02\x02\b\xFD\x03\x02" + + "\x02\x02\b\xFF\x03\x02\x02\x02\b\u0101\x03\x02\x02\x02\b\u0103\x03\x02" + + "\x02\x02\t\u0105\x03\x02\x02\x02\t\u0107\x03\x02\x02\x02\t\u0109\x03\x02" + + "\x02\x02\t\u010B\x03\x02\x02\x02\t\u010D\x03\x02\x02\x02\t\u010F\x03\x02" + + "\x02\x02\t\u0111\x03\x02\x02\x02\t\u0113\x03\x02\x02\x02\t\u0115\x03\x02" + + "\x02\x02\t\u0117\x03\x02\x02\x02\n\u0119\x03\x02\x02\x02\n\u011B\x03\x02" + + "\x02\x02\n\u011D\x03\x02\x02\x02\n\u011F\x03\x02\x02\x02\n\u0121\x03\x02" + + "\x02\x02\n\u0123\x03\x02\x02\x02\n\u0125\x03\x02\x02\x02\v\u0127\x03\x02" + + "\x02\x02\v\u0129\x03\x02\x02\x02\v\u012B\x03\x02\x02\x02\v\u012D\x03\x02" + + "\x02\x02\v\u012F\x03\x02\x02\x02\v\u0131\x03\x02\x02\x02\f\u0133\x03\x02" + + "\x02\x02\f\u0135\x03\x02\x02\x02\f\u0137\x03\x02\x02\x02\f\u0139\x03\x02" + + "\x02\x02\f\u013B\x03\x02\x02\x02\f\u013D\x03\x02\x02\x02\r\u0173\x03\x02" + + "\x02\x02\x0F\u017D\x03\x02\x02\x02\x11\u0184\x03\x02\x02\x02\x13\u018D" + + "\x03\x02\x02\x02\x15\u0194\x03\x02\x02\x02\x17\u019E\x03\x02\x02\x02\x19" + + "\u01A5\x03\x02\x02\x02\x1B\u01AC\x03\x02\x02\x02\x1D\u01BA\x03\x02\x02" + + "\x02\x1F\u01C1\x03\x02\x02\x02!\u01C9\x03\x02\x02\x02#\u01D5\x03\x02\x02" + + "\x02%\u01DE\x03\x02\x02\x02\'\u01E4\x03\x02\x02\x02)\u01EB\x03\x02\x02" + + "\x02+\u01F2\x03\x02\x02\x02-\u01FA\x03\x02\x02\x02/\u0203\x03\x02\x02" + + "\x021\u0209\x03\x02\x02\x023\u021A\x03\x02\x02\x025\u022A\x03\x02\x02" + + "\x027\u0230\x03\x02\x02\x029\u0235\x03\x02\x02\x02;\u023A\x03\x02\x02" + + "\x02=\u023E\x03\x02\x02\x02?\u0242\x03\x02\x02\x02A\u0246\x03\x02\x02" + + "\x02C\u024A\x03\x02\x02\x02E\u024C\x03\x02\x02\x02G\u024E\x03\x02\x02" + + "\x02I\u0251\x03\x02\x02\x02K\u0253\x03\x02\x02\x02M\u025C\x03\x02\x02" + + "\x02O\u025E\x03\x02\x02\x02Q\u0263\x03\x02\x02\x02S\u0265\x03\x02\x02" + + "\x02U\u026A\x03\x02\x02\x02W\u0289\x03\x02\x02\x02Y\u028C\x03\x02\x02" + + "\x02[\u02BA\x03\x02\x02\x02]\u02BC\x03\x02\x02\x02_\u02BF\x03\x02\x02" + + "\x02a\u02C3\x03\x02\x02\x02c\u02C7\x03\x02\x02\x02e\u02C9\x03\x02\x02" + + "\x02g\u02CB\x03\x02\x02\x02i\u02D0\x03\x02\x02\x02k\u02D2\x03\x02\x02" + + "\x02m\u02D8\x03\x02\x02\x02o\u02DE\x03\x02\x02\x02q\u02E3\x03\x02\x02" + + "\x02s\u02E5\x03\x02\x02\x02u\u02E8\x03\x02\x02\x02w\u02EB\x03\x02\x02" + + "\x02y\u02F0\x03\x02\x02\x02{\u02F4\x03\x02\x02\x02}\u02F9\x03\x02\x02" + + "\x02\x7F\u02FF\x03\x02\x02\x02\x81\u0302\x03\x02\x02\x02\x83\u0304\x03" + + "\x02\x02\x02\x85\u030A\x03\x02\x02\x02\x87\u030C\x03\x02\x02\x02\x89\u0311" + + "\x03\x02\x02\x02\x8B\u0314\x03\x02\x02\x02\x8D\u0317\x03\x02\x02\x02\x8F" + + "\u031A\x03\x02\x02\x02\x91\u031C\x03\x02\x02\x02\x93\u031F\x03\x02\x02" + + "\x02\x95\u0321\x03\x02\x02\x02\x97\u0324\x03\x02\x02\x02\x99\u0326\x03" + + "\x02\x02\x02\x9B\u0328\x03\x02\x02\x02\x9D\u032A\x03\x02\x02\x02\x9F\u032C" + + "\x03\x02\x02\x02\xA1\u032E\x03\x02\x02\x02\xA3\u0333\x03\x02\x02\x02\xA5" + + "\u0348\x03\x02\x02\x02\xA7\u034A\x03\x02\x02\x02\xA9\u0352\x03\x02\x02" + + "\x02\xAB\u0356\x03\x02\x02\x02\xAD\u035A\x03\x02\x02\x02\xAF\u035E\x03" + + "\x02\x02\x02\xB1\u0363\x03\x02\x02\x02\xB3\u0367\x03\x02\x02\x02\xB5\u036B" + + "\x03\x02\x02\x02\xB7\u036F\x03\x02\x02\x02\xB9\u0373\x03\x02\x02\x02\xBB" + + "\u037F\x03\x02\x02\x02\xBD\u0382\x03\x02\x02\x02\xBF\u0386\x03\x02\x02" + + "\x02\xC1\u038A\x03\x02\x02\x02\xC3\u038E\x03\x02\x02\x02\xC5\u0392\x03" + + "\x02\x02\x02\xC7\u0396\x03\x02\x02\x02\xC9\u039B\x03\x02\x02\x02\xCB\u039F" + + "\x03\x02\x02\x02\xCD\u03A7\x03\x02\x02\x02\xCF\u03BC\x03\x02\x02\x02\xD1" + + "\u03BE\x03\x02\x02\x02\xD3\u03C2\x03\x02\x02\x02\xD5\u03C6\x03\x02\x02" + + "\x02\xD7\u03CA\x03\x02\x02\x02\xD9\u03CE\x03\x02\x02\x02\xDB\u03D2\x03" + + "\x02\x02\x02\xDD\u03D7\x03\x02\x02\x02\xDF\u03DB\x03\x02\x02\x02\xE1\u03DF" + + "\x03\x02\x02\x02\xE3\u03E3\x03\x02\x02\x02\xE5\u03E6\x03\x02\x02\x02\xE7" + + "\u03EA\x03\x02\x02\x02\xE9\u03EE\x03\x02\x02\x02\xEB\u03F2\x03\x02\x02" + + "\x02\xED\u03F6\x03\x02\x02\x02\xEF\u03FA\x03\x02\x02\x02\xF1\u03FF\x03" + + "\x02\x02\x02\xF3\u0404\x03\x02\x02\x02\xF5\u0409\x03\x02\x02\x02\xF7\u0410" + + "\x03\x02\x02\x02\xF9\u0419\x03\x02\x02\x02\xFB\u0420\x03\x02\x02\x02\xFD" + + "\u0424\x03\x02\x02\x02\xFF\u0428\x03\x02\x02\x02\u0101\u042C"; private static readonly _serializedATNSegment1: string = - "\x02\x02\x02\xFB\u0420\x03\x02\x02\x02\xFD\u0428\x03\x02\x02\x02\xFF\u042C" + - "\x03\x02\x02\x02\u0101\u0430\x03\x02\x02\x02\u0103\u0434\x03\x02\x02\x02" + - "\u0105\u0438\x03\x02\x02\x02\u0107\u043C\x03\x02\x02\x02\u0109\u0442\x03" + - "\x02\x02\x02\u010B\u0446\x03\x02\x02\x02\u010D\u044A\x03\x02\x02\x02\u010F" + - "\u044E\x03\x02\x02\x02\u0111\u0452\x03\x02\x02\x02\u0113\u0456\x03\x02" + - "\x02\x02\u0115\u045A\x03\x02\x02\x02\u0117\u045E\x03\x02\x02\x02\u0119" + - "\u0462\x03\x02\x02\x02\u011B\u0466\x03\x02\x02\x02\u011D\u046B\x03\x02" + - "\x02\x02\u011F\u046F\x03\x02\x02\x02\u0121\u0473\x03\x02\x02\x02\u0123" + - "\u0477\x03\x02\x02\x02\u0125\u047B\x03\x02\x02\x02\u0127\u047F\x03\x02" + - "\x02\x02\u0129\u0483\x03\x02\x02\x02\u012B\u0488\x03\x02\x02\x02\u012D" + - "\u048D\x03\x02\x02\x02\u012F\u0497\x03\x02\x02\x02\u0131\u049B\x03\x02" + - "\x02\x02\u0133\u049F\x03\x02\x02\x02\u0135\u04A3\x03\x02\x02\x02\u0137" + - "\u04A8\x03\x02\x02\x02\u0139\u04AF\x03\x02\x02\x02\u013B\u04B3\x03\x02" + - "\x02\x02\u013D\u04B7\x03\x02\x02\x02\u013F\u04BB\x03\x02\x02\x02\u0141" + - "\u04BF\x03\x02\x02\x02\u0143\u04C1\x03\x02\x02\x02\u0145\u04C3\x03\x02" + - "\x02\x02\u0147\u04C5\x03\x02\x02\x02\u0149\u04C7\x03\x02\x02\x02\u014B" + - "\u04C9\x03\x02\x02\x02\u014D\u04CB\x03\x02\x02\x02\u014F\u04CD\x03\x02" + - "\x02\x02\u0151\u04CF\x03\x02\x02\x02\u0153\u04D1\x03\x02\x02\x02\u0155" + - "\u04D3\x03\x02\x02\x02\u0157\u04D5\x03\x02\x02\x02\u0159\u04D7\x03\x02" + - "\x02\x02\u015B\u04D9\x03\x02\x02\x02\u015D\u04DB\x03\x02\x02\x02\u015F" + - "\u04DD\x03\x02\x02\x02\u0161\u04DF\x03\x02\x02\x02\u0163\u04E1\x03\x02" + - "\x02\x02\u0165\u04E3\x03\x02\x02\x02\u0167\u04E5\x03\x02\x02\x02\u0169" + - "\u04E7\x03\x02\x02\x02\u016B\u04E9\x03\x02\x02\x02\u016D\u04EB\x03\x02" + - "\x02\x02\u016F\u04ED\x03\x02\x02\x02\u0171\u04EF\x03\x02\x02\x02\u0173" + - "\u04F1\x03\x02\x02\x02\u0175\u0176\x05\u0147\x9F\x02\u0176\u0177\x05\u0151" + - "\xA4\x02\u0177\u0178\x05\u0165\xAE\x02\u0178\u0179\x05\u0165\xAE\x02\u0179" + - "\u017A\x05\u0149\xA0\x02\u017A\u017B\x05\u0145\x9E\x02\u017B\u017C\x05" + - "\u0167\xAF\x02\u017C\u017D\x03\x02\x02\x02\u017D\u017E\b\x02\x02\x02\u017E" + - "\x0E\x03\x02\x02\x02\u017F\u0180\x05\u0147\x9F\x02\u0180\u0181\x05\u0163" + - "\xAD\x02\u0181\u0182\x05\u015D\xAA\x02\u0182\u0183\x05\u015F\xAB\x02\u0183" + - "\u0184\x03\x02\x02\x02\u0184\u0185\b\x03\x03\x02\u0185\x10\x03\x02\x02" + - "\x02\u0186\u0187\x05\u0149\xA0\x02\u0187\u0188\x05\u015B\xA9\x02\u0188" + - "\u0189\x05\u0163\xAD\x02\u0189\u018A\x05\u0151\xA4\x02\u018A\u018B\x05" + - "\u0145\x9E\x02\u018B\u018C\x05\u014F\xA3\x02\u018C\u018D\x03\x02\x02\x02" + - "\u018D\u018E\b\x04\x04\x02\u018E\x12\x03\x02\x02\x02\u018F\u0190\x05\u0149" + - "\xA0\x02\u0190\u0191\x05\u016B\xB1\x02\u0191\u0192\x05\u0141\x9C\x02\u0192" + - "\u0193\x05\u0157\xA7\x02\u0193\u0194\x03\x02\x02\x02\u0194\u0195\b\x05" + - "\x02\x02\u0195\x14\x03\x02\x02\x02\u0196\u0197\x05\u0149\xA0\x02\u0197" + - "\u0198\x05\u016F\xB3\x02\u0198\u0199\x05\u015F\xAB\x02\u0199\u019A\x05" + - "\u0157\xA7\x02\u019A\u019B\x05\u0141\x9C\x02\u019B\u019C\x05\u0151\xA4" + - "\x02\u019C\u019D\x05\u015B\xA9\x02\u019D\u019E\x03\x02\x02\x02\u019E\u019F" + - "\b\x06\x05\x02\u019F\x16\x03\x02\x02\x02\u01A0\u01A1\x05\u014B\xA1\x02" + - "\u01A1\u01A2\x05\u0163\xAD\x02\u01A2\u01A3\x05\u015D\xAA\x02\u01A3\u01A4" + - "\x05\u0159\xA8\x02\u01A4\u01A5\x03\x02\x02\x02\u01A5\u01A6\b\x07\x06\x02" + - "\u01A6\x18\x03\x02\x02\x02\u01A7\u01A8\x05\u014D\xA2\x02\u01A8\u01A9\x05" + - "\u0163\xAD\x02\u01A9\u01AA\x05\u015D\xAA\x02\u01AA\u01AB\x05\u0155\xA6" + - "\x02\u01AB\u01AC\x03\x02\x02\x02\u01AC\u01AD\b\b\x02\x02\u01AD\x1A\x03" + - "\x02\x02\x02\u01AE\u01AF\x05\u0151\xA4\x02\u01AF\u01B0\x05\u015B\xA9\x02" + - "\u01B0\u01B1\x05\u0157\xA7\x02\u01B1\u01B2\x05\u0151\xA4\x02\u01B2\u01B3" + - "\x05\u015B\xA9\x02\u01B3\u01B4\x05\u0149\xA0\x02\u01B4\u01B5\x05\u0165" + - "\xAE\x02\u01B5\u01B6\x05\u0167\xAF\x02\u01B6\u01B7\x05\u0141\x9C\x02\u01B7" + - "\u01B8\x05\u0167\xAF\x02\u01B8\u01B9\x05\u0165\xAE\x02\u01B9\u01BA\x03" + - "\x02\x02\x02\u01BA\u01BB\b\t\x02\x02\u01BB\x1C\x03\x02\x02\x02\u01BC\u01BD" + - "\x05\u0155\xA6\x02\u01BD\u01BE\x05\u0149\xA0\x02\u01BE\u01BF\x05\u0149" + - "\xA0\x02\u01BF\u01C0\x05\u015F\xAB\x02\u01C0\u01C1\x03\x02\x02\x02\u01C1" + - "\u01C2\b\n\x03\x02\u01C2\x1E\x03\x02\x02\x02\u01C3\u01C4\x05\u0157\xA7" + - "\x02\u01C4\u01C5\x05\u0151\xA4\x02\u01C5\u01C6\x05\u0159\xA8\x02\u01C6" + - "\u01C7\x05\u0151\xA4\x02\u01C7\u01C8\x05\u0167\xAF\x02\u01C8\u01C9\x03" + - "\x02\x02\x02\u01C9\u01CA\b\v\x02\x02\u01CA \x03\x02\x02\x02\u01CB\u01CC" + - "\x05\u0159\xA8\x02\u01CC\u01CD\x05\u016B\xB1\x02\u01CD\u01CE\x05U&\x02" + - "\u01CE\u01CF\x05\u0149\xA0\x02\u01CF\u01D0\x05\u016F\xB3\x02\u01D0\u01D1" + - "\x05\u015F\xAB\x02\u01D1\u01D2\x05\u0141\x9C\x02\u01D2\u01D3\x05\u015B" + - "\xA9\x02\u01D3\u01D4\x05\u0147\x9F\x02\u01D4\u01D5\x03\x02\x02\x02\u01D5" + - "\u01D6\b\f\x07\x02\u01D6\"\x03\x02\x02\x02\u01D7\u01D8\x05\u015F\xAB\x02" + - "\u01D8\u01D9\x05\u0163\xAD\x02\u01D9\u01DA\x05\u015D\xAA\x02\u01DA\u01DB" + - "\x05\u0153\xA5\x02\u01DB\u01DC\x05\u0149\xA0\x02\u01DC\u01DD\x05\u0145" + - "\x9E\x02\u01DD\u01DE\x05\u0167\xAF\x02\u01DE\u01DF\x03\x02\x02\x02\u01DF" + - "\u01E0\b\r\x03\x02\u01E0$\x03\x02\x02\x02\u01E1\u01E2\x05\u0163\xAD\x02" + - "\u01E2\u01E3\x05\u0149\xA0\x02\u01E3\u01E4\x05\u015B\xA9\x02\u01E4\u01E5" + - "\x05\u0141\x9C\x02\u01E5\u01E6\x05\u0159\xA8\x02\u01E6\u01E7\x05\u0149" + - "\xA0\x02\u01E7\u01E8\x03\x02\x02\x02\u01E8\u01E9\b\x0E\b\x02\u01E9&\x03" + - "\x02\x02\x02\u01EA\u01EB\x05\u0163\xAD\x02\u01EB\u01EC\x05\u015D\xAA\x02" + - "\u01EC\u01ED\x05\u016D\xB2\x02\u01ED\u01EE\x03\x02\x02\x02\u01EE\u01EF" + - "\b\x0F\x02\x02\u01EF(\x03\x02\x02\x02\u01F0\u01F1\x05\u0165\xAE\x02\u01F1" + - "\u01F2\x05\u014F\xA3\x02\u01F2\u01F3\x05\u015D\xAA\x02\u01F3\u01F4\x05" + - "\u016D\xB2\x02\u01F4\u01F5\x03\x02\x02\x02\u01F5\u01F6\b\x10\t\x02\u01F6" + - "*\x03\x02\x02\x02\u01F7\u01F8\x05\u0165\xAE\x02\u01F8\u01F9\x05\u015D" + - "\xAA\x02\u01F9\u01FA\x05\u0163\xAD\x02\u01FA\u01FB\x05\u0167\xAF\x02\u01FB" + - "\u01FC\x03\x02\x02\x02\u01FC\u01FD\b\x11\x02\x02\u01FD,\x03\x02\x02\x02" + - "\u01FE\u01FF\x05\u0165\xAE\x02\u01FF\u0200\x05\u0167\xAF\x02\u0200\u0201" + - "\x05\u0141\x9C\x02\u0201\u0202\x05\u0167\xAF\x02\u0202\u0203\x05\u0165" + - "\xAE\x02\u0203\u0204\x03\x02\x02\x02\u0204\u0205\b\x12\x02\x02\u0205." + - "\x03\x02\x02\x02\u0206\u0207\x05\u016D\xB2\x02\u0207\u0208\x05\u014F\xA3" + - "\x02\u0208\u0209\x05\u0149\xA0\x02\u0209\u020A\x05\u0163\xAD\x02\u020A" + - "\u020B\x05\u0149\xA0\x02\u020B\u020C\x03\x02\x02\x02\u020C\u020D\b\x13" + - "\x02\x02\u020D0\x03\x02\x02\x02\u020E\u0210\n\x02\x02\x02\u020F\u020E" + - "\x03\x02\x02\x02\u0210\u0211\x03\x02\x02\x02\u0211\u020F\x03\x02\x02\x02" + - "\u0211\u0212\x03\x02\x02\x02\u0212\u0213\x03\x02\x02\x02\u0213\u0214\b" + - "\x14\x02\x02\u02142\x03\x02\x02\x02\u0215\u0216\x071\x02\x02\u0216\u0217" + - "\x071\x02\x02\u0217\u021B\x03\x02\x02\x02\u0218\u021A\n\x03\x02\x02\u0219" + - "\u0218\x03\x02\x02\x02\u021A\u021D\x03\x02\x02\x02\u021B\u0219\x03\x02" + - "\x02\x02\u021B\u021C\x03\x02\x02\x02\u021C\u021F\x03\x02\x02\x02\u021D" + - "\u021B\x03\x02\x02\x02\u021E\u0220\x07\x0F\x02\x02\u021F\u021E\x03\x02" + - "\x02\x02\u021F\u0220\x03\x02\x02\x02\u0220\u0222\x03\x02\x02\x02\u0221" + - "\u0223\x07\f\x02\x02\u0222\u0221\x03\x02\x02\x02\u0222\u0223\x03\x02\x02" + - "\x02\u0223\u0224\x03\x02\x02\x02\u0224\u0225\b\x15\n\x02\u02254\x03\x02" + - "\x02\x02\u0226\u0227\x071\x02\x02\u0227\u0228\x07,\x02\x02\u0228\u022D" + - "\x03\x02\x02\x02\u0229\u022C\x055\x16\x02\u022A\u022C\v\x02\x02\x02\u022B" + - "\u0229\x03\x02\x02\x02\u022B\u022A\x03\x02\x02\x02\u022C\u022F\x03\x02" + - "\x02\x02\u022D\u022E\x03\x02\x02\x02\u022D\u022B\x03\x02\x02\x02\u022E" + - "\u0230\x03\x02\x02\x02\u022F\u022D\x03\x02\x02\x02\u0230\u0231\x07,\x02" + - "\x02\u0231\u0232\x071\x02\x02\u0232\u0233\x03\x02\x02\x02\u0233\u0234" + - "\b\x16\n\x02\u02346\x03\x02\x02\x02\u0235\u0237\t\x04\x02\x02\u0236\u0235" + - "\x03\x02\x02\x02\u0237\u0238\x03\x02\x02\x02\u0238\u0236\x03\x02\x02\x02" + - "\u0238\u0239\x03\x02\x02\x02\u0239\u023A\x03\x02\x02\x02\u023A\u023B\b" + - "\x17\n\x02\u023B8\x03\x02\x02\x02\u023C\u023D\x05\xA3M\x02\u023D\u023E" + - "\x03\x02\x02\x02\u023E\u023F\b\x18\v\x02\u023F\u0240\b\x18\f\x02\u0240" + - ":\x03\x02\x02\x02\u0241\u0242\x05C\x1D\x02\u0242\u0243\x03\x02\x02\x02" + - "\u0243\u0244\b\x19\r\x02\u0244\u0245\b\x19\x0E\x02\u0245<\x03\x02\x02" + - "\x02\u0246\u0247\x057\x17\x02\u0247\u0248\x03\x02\x02\x02\u0248\u0249" + - "\b\x1A\n\x02\u0249>\x03\x02\x02\x02\u024A\u024B\x053\x15\x02\u024B\u024C" + - "\x03\x02\x02\x02\u024C\u024D\b\x1B\n\x02\u024D@\x03\x02\x02\x02\u024E" + - "\u024F\x055\x16\x02\u024F\u0250\x03\x02\x02\x02\u0250\u0251\b\x1C\n\x02" + - "\u0251B\x03\x02\x02\x02\u0252\u0253\x07~\x02\x02\u0253\u0254\x03\x02\x02" + - "\x02\u0254\u0255\b\x1D\x0E\x02\u0255D\x03\x02\x02\x02\u0256\u0257\t\x05" + - "\x02\x02\u0257F\x03\x02\x02\x02\u0258\u0259\t\x06\x02\x02\u0259H\x03\x02" + - "\x02\x02\u025A\u025B\x07^\x02\x02\u025B\u025C\t\x07\x02\x02\u025CJ\x03" + - "\x02\x02\x02\u025D\u025E\n\b\x02\x02\u025EL\x03\x02\x02\x02\u025F\u0261" + - "\t\t\x02\x02\u0260\u0262\t\n\x02\x02\u0261\u0260\x03\x02\x02\x02\u0261" + - "\u0262\x03\x02\x02\x02\u0262\u0264\x03\x02\x02\x02\u0263\u0265\x05E\x1E" + - "\x02\u0264\u0263\x03\x02\x02\x02\u0265\u0266\x03\x02\x02\x02\u0266\u0264" + - "\x03\x02\x02\x02\u0266\u0267\x03\x02\x02\x02\u0267N\x03\x02\x02\x02\u0268" + - "\u0269\x07B\x02\x02\u0269P\x03\x02\x02\x02\u026A\u026B\x07b\x02\x02\u026B" + - "R\x03\x02\x02\x02\u026C\u0270\n\v\x02\x02\u026D\u026E\x07b\x02\x02\u026E" + - "\u0270\x07b\x02\x02\u026F\u026C\x03\x02\x02\x02\u026F\u026D\x03\x02\x02" + - "\x02\u0270T\x03\x02\x02\x02\u0271\u0272\x07a\x02\x02\u0272V\x03\x02\x02" + - "\x02\u0273\u0277\x05G\x1F\x02\u0274\u0277\x05E\x1E\x02\u0275\u0277\x05" + - "U&\x02\u0276\u0273\x03\x02\x02\x02\u0276\u0274\x03\x02\x02\x02\u0276\u0275" + - "\x03\x02\x02\x02\u0277X\x03\x02\x02\x02\u0278\u027D\x07$\x02\x02\u0279" + - "\u027C\x05I \x02\u027A\u027C\x05K!\x02\u027B\u0279\x03\x02\x02\x02\u027B" + - "\u027A\x03\x02\x02\x02\u027C\u027F\x03\x02\x02\x02\u027D\u027B\x03\x02" + - "\x02\x02\u027D\u027E\x03\x02\x02\x02\u027E\u0280\x03\x02\x02\x02\u027F" + - "\u027D\x03\x02\x02\x02\u0280\u0296\x07$\x02\x02\u0281\u0282\x07$\x02\x02" + - "\u0282\u0283\x07$\x02\x02\u0283\u0284\x07$\x02\x02\u0284\u0288\x03\x02" + - "\x02\x02\u0285\u0287\n\x03\x02\x02\u0286\u0285\x03\x02\x02\x02\u0287\u028A" + - "\x03\x02\x02\x02\u0288\u0289\x03\x02\x02\x02\u0288\u0286\x03\x02\x02\x02" + - "\u0289\u028B\x03\x02\x02\x02\u028A\u0288\x03\x02\x02\x02\u028B\u028C\x07" + - "$\x02\x02\u028C\u028D\x07$\x02\x02\u028D\u028E\x07$\x02\x02\u028E\u0290" + - "\x03\x02\x02\x02\u028F\u0291\x07$\x02\x02\u0290\u028F\x03\x02\x02\x02" + - "\u0290\u0291\x03\x02\x02\x02\u0291\u0293\x03\x02\x02\x02\u0292\u0294\x07" + - "$\x02\x02\u0293\u0292\x03\x02\x02\x02\u0293\u0294\x03\x02\x02\x02\u0294" + - "\u0296\x03\x02\x02\x02\u0295\u0278\x03\x02\x02\x02\u0295\u0281\x03\x02" + - "\x02\x02\u0296Z\x03\x02\x02\x02\u0297\u0299\x05E\x1E\x02\u0298\u0297\x03" + - "\x02\x02\x02\u0299\u029A\x03\x02\x02\x02\u029A\u0298\x03\x02\x02\x02\u029A" + - "\u029B\x03\x02\x02\x02\u029B\\\x03\x02\x02\x02\u029C\u029E\x05E\x1E\x02" + - "\u029D\u029C\x03\x02\x02\x02\u029E\u029F\x03\x02\x02\x02\u029F\u029D\x03" + - "\x02\x02\x02\u029F\u02A0\x03\x02\x02\x02\u02A0\u02A1\x03\x02\x02\x02\u02A1" + - "\u02A5\x05k1\x02\u02A2\u02A4\x05E\x1E\x02\u02A3\u02A2\x03\x02\x02\x02" + - "\u02A4\u02A7\x03\x02\x02\x02\u02A5\u02A3\x03\x02\x02\x02\u02A5\u02A6\x03" + - "\x02\x02\x02\u02A6\u02C7\x03\x02\x02\x02\u02A7\u02A5\x03\x02\x02\x02\u02A8" + - "\u02AA\x05k1\x02\u02A9\u02AB\x05E\x1E\x02\u02AA\u02A9\x03\x02\x02\x02" + - "\u02AB\u02AC\x03\x02\x02\x02\u02AC\u02AA\x03\x02\x02\x02\u02AC\u02AD\x03" + - "\x02\x02\x02\u02AD\u02C7\x03\x02\x02\x02\u02AE\u02B0\x05E\x1E\x02\u02AF" + - "\u02AE\x03\x02\x02\x02\u02B0\u02B1\x03\x02\x02\x02\u02B1\u02AF\x03\x02" + - "\x02\x02\u02B1\u02B2\x03\x02\x02\x02\u02B2\u02BA\x03\x02\x02\x02\u02B3" + - "\u02B7\x05k1\x02\u02B4\u02B6\x05E\x1E\x02\u02B5\u02B4\x03\x02\x02\x02" + - "\u02B6\u02B9\x03\x02\x02\x02\u02B7\u02B5\x03\x02\x02\x02\u02B7\u02B8\x03" + - "\x02\x02\x02\u02B8\u02BB\x03\x02\x02\x02\u02B9\u02B7\x03\x02\x02\x02\u02BA" + - "\u02B3\x03\x02\x02\x02\u02BA\u02BB\x03\x02\x02\x02\u02BB\u02BC\x03\x02" + - "\x02\x02\u02BC\u02BD\x05M\"\x02\u02BD\u02C7\x03\x02\x02\x02\u02BE\u02C0" + - "\x05k1\x02\u02BF\u02C1\x05E\x1E\x02\u02C0\u02BF\x03\x02\x02\x02\u02C1" + - "\u02C2\x03\x02\x02\x02\u02C2\u02C0\x03\x02\x02\x02\u02C2\u02C3\x03\x02" + - "\x02\x02\u02C3\u02C4\x03\x02\x02\x02\u02C4\u02C5\x05M\"\x02\u02C5\u02C7" + - "\x03\x02\x02\x02\u02C6\u029D\x03\x02\x02\x02\u02C6\u02A8\x03\x02\x02\x02" + - "\u02C6\u02AF\x03\x02\x02\x02\u02C6\u02BE\x03\x02\x02\x02\u02C7^\x03\x02" + - "\x02\x02\u02C8\u02C9\x05\u0143\x9D\x02\u02C9\u02CA\x05\u0171\xB4\x02\u02CA" + - "`\x03\x02\x02\x02\u02CB\u02CC\x05\u0141\x9C\x02\u02CC\u02CD\x05\u015B" + - "\xA9\x02\u02CD\u02CE\x05\u0147\x9F\x02\u02CEb\x03\x02\x02\x02\u02CF\u02D0" + - "\x05\u0141\x9C\x02\u02D0\u02D1\x05\u0165\xAE\x02\u02D1\u02D2\x05\u0145" + - "\x9E\x02\u02D2d\x03\x02\x02\x02\u02D3\u02D4\x07?\x02\x02\u02D4f\x03\x02" + - "\x02\x02\u02D5\u02D6\x07.\x02\x02\u02D6h\x03\x02\x02\x02\u02D7\u02D8\x05" + - "\u0147\x9F\x02\u02D8\u02D9\x05\u0149\xA0\x02\u02D9\u02DA\x05\u0165\xAE" + - "\x02\u02DA\u02DB\x05\u0145\x9E\x02\u02DBj\x03\x02\x02\x02\u02DC\u02DD" + - "\x070\x02\x02\u02DDl\x03\x02\x02\x02\u02DE\u02DF\x05\u014B\xA1\x02\u02DF" + - "\u02E0\x05\u0141\x9C\x02\u02E0\u02E1\x05\u0157\xA7\x02\u02E1\u02E2\x05" + - "\u0165\xAE\x02\u02E2\u02E3\x05\u0149\xA0\x02\u02E3n\x03\x02\x02\x02\u02E4" + - "\u02E5\x05\u014B\xA1\x02\u02E5\u02E6\x05\u0151\xA4\x02\u02E6\u02E7\x05" + - "\u0163\xAD\x02\u02E7\u02E8\x05\u0165\xAE\x02\u02E8\u02E9\x05\u0167\xAF" + - "\x02\u02E9p\x03\x02\x02\x02\u02EA\u02EB\x05\u0157\xA7\x02\u02EB\u02EC" + - "\x05\u0141\x9C\x02\u02EC\u02ED\x05\u0165\xAE\x02\u02ED\u02EE\x05\u0167" + - "\xAF\x02\u02EEr\x03\x02\x02\x02\u02EF\u02F0\x07*\x02\x02\u02F0t\x03\x02" + - "\x02\x02\u02F1\u02F2\x05\u0151\xA4\x02\u02F2\u02F3\x05\u015B\xA9\x02\u02F3" + - "v\x03\x02\x02\x02\u02F4\u02F5\x05\u0151\xA4\x02\u02F5\u02F6\x05\u0165" + - "\xAE\x02\u02F6x\x03\x02\x02\x02\u02F7\u02F8\x05\u0157\xA7\x02\u02F8\u02F9" + - "\x05\u0151\xA4\x02\u02F9\u02FA\x05\u0155\xA6\x02\u02FA\u02FB\x05\u0149" + - "\xA0\x02\u02FBz\x03\x02\x02\x02\u02FC\u02FD\x05\u015B\xA9\x02\u02FD\u02FE" + - "\x05\u015D\xAA\x02\u02FE\u02FF\x05\u0167\xAF\x02\u02FF|\x03\x02\x02\x02" + - "\u0300\u0301\x05\u015B\xA9\x02\u0301\u0302\x05\u0169\xB0\x02\u0302\u0303" + - "\x05\u0157\xA7\x02\u0303\u0304\x05\u0157\xA7\x02\u0304~\x03\x02\x02\x02" + - "\u0305\u0306\x05\u015B\xA9\x02\u0306\u0307\x05\u0169\xB0\x02\u0307\u0308" + - "\x05\u0157\xA7\x02\u0308\u0309\x05\u0157\xA7\x02\u0309\u030A\x05\u0165" + - "\xAE\x02\u030A\x80\x03\x02\x02\x02\u030B\u030C\x05\u015D\xAA\x02\u030C" + - "\u030D\x05\u0163\xAD\x02\u030D\x82\x03\x02\x02\x02\u030E\u030F\x07A\x02" + - "\x02\u030F\x84\x03\x02\x02\x02\u0310\u0311\x05\u0163\xAD\x02\u0311\u0312" + - "\x05\u0157\xA7\x02\u0312\u0313\x05\u0151\xA4\x02\u0313\u0314\x05\u0155" + - "\xA6\x02\u0314\u0315\x05\u0149\xA0\x02\u0315\x86\x03\x02\x02\x02\u0316" + - "\u0317\x07+\x02\x02\u0317\x88\x03\x02\x02\x02\u0318\u0319\x05\u0167\xAF" + - "\x02\u0319\u031A\x05\u0163\xAD\x02\u031A\u031B\x05\u0169\xB0\x02\u031B" + - "\u031C\x05\u0149\xA0\x02\u031C\x8A\x03\x02\x02\x02\u031D\u031E\x07?\x02" + - "\x02\u031E\u031F\x07?\x02\x02\u031F\x8C\x03\x02\x02\x02\u0320\u0321\x07" + - "?\x02\x02\u0321\u0322\x07\x80\x02\x02\u0322\x8E\x03\x02\x02\x02\u0323" + - "\u0324\x07#\x02\x02\u0324\u0325\x07?\x02\x02\u0325\x90\x03\x02\x02\x02" + - "\u0326\u0327\x07>\x02\x02\u0327\x92\x03\x02\x02\x02\u0328\u0329\x07>\x02" + - "\x02\u0329\u032A\x07?\x02\x02\u032A\x94\x03\x02\x02\x02\u032B\u032C\x07" + - "@\x02\x02\u032C\x96\x03\x02\x02\x02\u032D\u032E\x07@\x02\x02\u032E\u032F" + - "\x07?\x02\x02\u032F\x98\x03\x02\x02\x02\u0330\u0331\x07-\x02\x02\u0331" + - "\x9A\x03\x02\x02\x02\u0332\u0333\x07/\x02\x02\u0333\x9C\x03\x02\x02\x02" + - "\u0334\u0335\x07,\x02\x02\u0335\x9E\x03\x02\x02\x02\u0336\u0337\x071\x02" + - "\x02\u0337\xA0\x03\x02\x02\x02\u0338\u0339\x07\'\x02\x02\u0339\xA2\x03" + - "\x02\x02\x02\u033A\u033B\x07]\x02\x02\u033B\u033C\x03\x02\x02\x02\u033C" + - "\u033D\bM\x02\x02\u033D\u033E\bM\x02\x02\u033E\xA4\x03\x02\x02\x02\u033F" + - "\u0340\x07_\x02\x02\u0340\u0341\x03\x02\x02\x02\u0341\u0342\bN\x0E\x02" + - "\u0342\u0343\bN\x0E\x02\u0343\xA6\x03\x02\x02\x02\u0344\u0348\x05G\x1F" + - "\x02\u0345\u0347\x05W\'\x02\u0346\u0345\x03\x02\x02\x02\u0347\u034A\x03" + - "\x02\x02\x02\u0348\u0346\x03\x02\x02\x02\u0348\u0349\x03\x02\x02\x02\u0349" + - "\u0355\x03\x02\x02\x02\u034A\u0348\x03\x02\x02\x02\u034B\u034E\x05U&\x02" + - "\u034C\u034E\x05O#\x02\u034D\u034B\x03\x02\x02\x02\u034D\u034C\x03\x02" + - "\x02\x02\u034E\u0350\x03\x02\x02\x02\u034F\u0351\x05W\'\x02\u0350\u034F" + - "\x03\x02\x02\x02\u0351\u0352\x03\x02\x02\x02\u0352\u0350\x03\x02\x02\x02" + - "\u0352\u0353\x03\x02\x02\x02\u0353\u0355\x03\x02\x02\x02\u0354\u0344\x03" + - "\x02\x02\x02\u0354\u034D\x03\x02\x02\x02\u0355\xA8\x03\x02\x02\x02\u0356" + - "\u0358\x05Q$\x02\u0357\u0359\x05S%\x02\u0358\u0357\x03\x02\x02\x02\u0359" + - "\u035A\x03\x02\x02\x02\u035A\u0358\x03\x02\x02\x02\u035A\u035B\x03\x02" + - "\x02\x02\u035B\u035C\x03\x02\x02\x02\u035C\u035D\x05Q$\x02\u035D\xAA\x03" + - "\x02\x02\x02\u035E\u035F\x053\x15\x02\u035F\u0360\x03\x02\x02\x02\u0360" + - "\u0361\bQ\n\x02\u0361\xAC\x03\x02\x02\x02\u0362\u0363\x055\x16\x02\u0363" + - "\u0364\x03\x02\x02\x02\u0364\u0365\bR\n\x02\u0365\xAE\x03\x02\x02\x02" + - "\u0366\u0367\x057\x17\x02\u0367\u0368\x03\x02\x02\x02\u0368\u0369\bS\n" + - "\x02\u0369\xB0\x03\x02\x02\x02\u036A\u036B\x05C\x1D\x02\u036B\u036C\x03" + - "\x02\x02\x02\u036C\u036D\bT\r\x02\u036D\u036E\bT\x0E\x02\u036E\xB2\x03" + - "\x02\x02\x02\u036F\u0370\x05\xA3M\x02\u0370\u0371\x03\x02\x02\x02\u0371" + - "\u0372\bU\v\x02\u0372\xB4\x03\x02\x02\x02\u0373\u0374\x05\xA5N\x02\u0374" + - "\u0375\x03\x02\x02\x02\u0375\u0376\bV\x0F\x02\u0376\xB6\x03\x02\x02\x02" + - "\u0377\u0378\x05g/\x02\u0378\u0379\x03\x02\x02\x02\u0379\u037A\bW\x10" + - "\x02\u037A\xB8\x03\x02\x02\x02\u037B\u037C\x05e.\x02\u037C\u037D\x03\x02" + - "\x02\x02\u037D\u037E\bX\x11\x02\u037E\xBA\x03\x02\x02\x02\u037F\u0380" + - "\x05\u0159\xA8\x02\u0380\u0381\x05\u0149\xA0\x02\u0381\u0382\x05\u0167" + - "\xAF\x02\u0382\u0383\x05\u0141\x9C\x02\u0383\u0384\x05\u0147\x9F\x02\u0384" + - "\u0385\x05\u0141\x9C\x02\u0385\u0386\x05\u0167\xAF\x02\u0386\u0387\x05" + - "\u0141\x9C\x02\u0387\xBC\x03\x02\x02\x02\u0388\u038C\n\f\x02\x02\u0389" + - "\u038A\x071\x02\x02\u038A\u038C\n\r\x02\x02\u038B\u0388\x03\x02\x02\x02" + - "\u038B\u0389\x03\x02\x02\x02\u038C\xBE\x03\x02\x02\x02\u038D\u038F\x05" + - "\xBDZ\x02\u038E\u038D\x03\x02\x02\x02\u038F\u0390\x03\x02\x02\x02\u0390" + - "\u038E\x03\x02\x02\x02\u0390\u0391\x03\x02\x02\x02\u0391\xC0\x03\x02\x02" + - "\x02\u0392\u0393\x05\xA9P\x02\u0393\u0394\x03\x02\x02\x02\u0394\u0395" + - "\b\\\x12\x02\u0395\xC2\x03\x02\x02\x02\u0396\u0397\x053\x15\x02\u0397" + - "\u0398\x03\x02\x02\x02\u0398\u0399\b]\n\x02\u0399\xC4\x03\x02\x02\x02" + - "\u039A\u039B\x055\x16\x02\u039B\u039C\x03\x02\x02\x02\u039C\u039D\b^\n" + - "\x02\u039D\xC6\x03\x02\x02\x02\u039E\u039F\x057\x17\x02\u039F\u03A0\x03" + - "\x02\x02\x02\u03A0\u03A1\b_\n\x02\u03A1\xC8\x03\x02\x02\x02\u03A2\u03A3" + - "\x05C\x1D\x02\u03A3\u03A4\x03\x02\x02\x02\u03A4\u03A5\b`\r\x02\u03A5\u03A6" + - "\b`\x0E\x02\u03A6\xCA\x03\x02\x02\x02\u03A7\u03A8\x05k1\x02\u03A8\u03A9" + - "\x03\x02\x02\x02\u03A9\u03AA\ba\x13\x02\u03AA\xCC\x03\x02\x02\x02\u03AB" + - "\u03AC\x05g/\x02\u03AC\u03AD\x03\x02\x02\x02\u03AD\u03AE\bb\x10\x02\u03AE" + - "\xCE\x03\x02\x02\x02\u03AF\u03B4\x05G\x1F\x02\u03B0\u03B4\x05E\x1E\x02" + - "\u03B1\u03B4\x05U&\x02\u03B2\u03B4\x05\x9DJ\x02\u03B3\u03AF\x03\x02\x02" + - "\x02\u03B3\u03B0\x03\x02\x02\x02\u03B3\u03B1\x03\x02\x02\x02\u03B3\u03B2" + - "\x03\x02\x02\x02\u03B4\xD0\x03\x02\x02\x02\u03B5\u03B8\x05G\x1F\x02\u03B6" + - "\u03B8\x05\x9DJ\x02\u03B7\u03B5\x03\x02\x02\x02\u03B7\u03B6\x03\x02\x02" + - "\x02\u03B8\u03BC\x03\x02\x02\x02\u03B9\u03BB\x05\xCFc\x02\u03BA\u03B9" + - "\x03\x02\x02\x02\u03BB\u03BE\x03\x02\x02\x02\u03BC\u03BA\x03\x02\x02\x02" + - "\u03BC\u03BD\x03\x02\x02\x02\u03BD\u03C9\x03\x02\x02\x02\u03BE\u03BC\x03" + - "\x02\x02\x02\u03BF\u03C2\x05U&\x02\u03C0\u03C2\x05O#\x02\u03C1\u03BF\x03" + - "\x02\x02\x02\u03C1\u03C0\x03\x02\x02\x02\u03C2\u03C4\x03\x02\x02\x02\u03C3" + - "\u03C5\x05\xCFc\x02\u03C4\u03C3\x03\x02\x02\x02\u03C5\u03C6\x03\x02\x02" + - "\x02\u03C6\u03C4\x03\x02\x02\x02\u03C6\u03C7\x03\x02\x02\x02\u03C7\u03C9" + - "\x03\x02\x02\x02\u03C8\u03B7\x03\x02\x02\x02\u03C8\u03C1\x03\x02\x02\x02" + - "\u03C9\xD2\x03\x02\x02\x02\u03CA\u03CB\x05\xD1d\x02\u03CB\u03CC\x03\x02" + - "\x02\x02\u03CC\u03CD\be\x14\x02\u03CD\xD4\x03\x02\x02\x02\u03CE\u03CF" + - "\x05\xA9P\x02\u03CF\u03D0\x03\x02\x02\x02\u03D0\u03D1\bf\x12\x02\u03D1" + - "\xD6\x03\x02\x02\x02\u03D2\u03D3\x053\x15\x02\u03D3\u03D4\x03\x02\x02" + - "\x02\u03D4\u03D5\bg\n\x02\u03D5\xD8\x03\x02\x02\x02\u03D6\u03D7\x055\x16" + - "\x02\u03D7\u03D8\x03\x02\x02\x02\u03D8\u03D9\bh\n\x02\u03D9\xDA\x03\x02" + - "\x02\x02\u03DA\u03DB\x057\x17\x02\u03DB\u03DC\x03\x02\x02\x02\u03DC\u03DD" + - "\bi\n\x02\u03DD\xDC\x03\x02\x02\x02\u03DE\u03DF\x05C\x1D\x02\u03DF\u03E0" + - "\x03\x02\x02\x02\u03E0\u03E1\bj\r\x02\u03E1\u03E2\bj\x0E\x02\u03E2\xDE" + - "\x03\x02\x02\x02\u03E3\u03E4\x05e.\x02\u03E4\u03E5\x03\x02\x02\x02\u03E5" + - "\u03E6\bk\x11\x02\u03E6\xE0\x03\x02\x02\x02\u03E7\u03E8\x05g/\x02\u03E8" + - "\u03E9\x03\x02\x02\x02\u03E9\u03EA\bl\x10\x02\u03EA\xE2\x03\x02\x02\x02" + - "\u03EB\u03EC\x05k1\x02\u03EC\u03ED\x03\x02\x02\x02\u03ED\u03EE\bm\x13" + - "\x02\u03EE\xE4\x03\x02\x02\x02\u03EF\u03F0\x05\u0141\x9C\x02\u03F0\u03F1" + - "\x05\u0165\xAE\x02\u03F1\xE6\x03\x02\x02\x02\u03F2\u03F3\x05\xA9P\x02" + - "\u03F3\u03F4\x03\x02\x02\x02\u03F4\u03F5\bo\x12\x02\u03F5\xE8\x03\x02" + - "\x02\x02\u03F6\u03F7\x05\xD1d\x02\u03F7\u03F8\x03\x02\x02\x02\u03F8\u03F9" + - "\bp\x14\x02\u03F9\xEA\x03\x02\x02\x02\u03FA\u03FB\x053\x15\x02\u03FB\u03FC" + - "\x03\x02\x02\x02\u03FC\u03FD\bq\n\x02\u03FD\xEC\x03\x02\x02\x02\u03FE" + - "\u03FF\x055\x16\x02\u03FF\u0400\x03\x02\x02\x02\u0400\u0401\br\n\x02\u0401" + - "\xEE\x03\x02\x02\x02\u0402\u0403\x057\x17\x02\u0403\u0404\x03\x02\x02" + - "\x02\u0404\u0405\bs\n\x02\u0405\xF0\x03\x02\x02\x02\u0406\u0407\x05C\x1D" + - "\x02\u0407\u0408\x03\x02\x02\x02\u0408\u0409\bt\r\x02\u0409\u040A\bt\x0E" + - "\x02\u040A\xF2\x03\x02\x02\x02\u040B\u040C\x05\xA3M\x02\u040C\u040D\x03" + - "\x02\x02\x02\u040D\u040E\bu\v\x02\u040E\u040F\bu\x15\x02\u040F\xF4\x03" + - "\x02\x02\x02\u0410\u0411\x05\u015D\xAA\x02\u0411\u0412\x05\u015B\xA9\x02" + - "\u0412\u0413\x03\x02\x02\x02\u0413\u0414\bv\x16\x02\u0414\xF6\x03\x02" + - "\x02\x02\u0415\u0416\x05\u016D\xB2\x02\u0416\u0417\x05\u0151\xA4\x02\u0417" + - "\u0418\x05\u0167\xAF\x02\u0418\u0419\x05\u014F\xA3\x02\u0419\u041A\x03" + - "\x02\x02\x02\u041A\u041B\bw\x16\x02\u041B\xF8\x03\x02\x02\x02\u041C\u041D" + - "\n\x0E\x02\x02\u041D\xFA\x03\x02\x02\x02\u041E\u0421\x05G\x1F\x02\u041F" + - "\u0421\x05E\x1E\x02\u0420\u041E\x03\x02\x02\x02\u0420\u041F\x03\x02\x02" + - "\x02\u0421\u0425\x03\x02\x02\x02\u0422\u0424\x05\xF9x\x02\u0423\u0422" + - "\x03\x02\x02\x02\u0424\u0427\x03\x02\x02\x02\u0425\u0423\x03\x02\x02\x02" + - "\u0425\u0426\x03\x02\x02\x02\u0426\xFC\x03\x02\x02\x02\u0427\u0425\x03" + - "\x02\x02\x02\u0428\u0429\x05\xA9P\x02\u0429\u042A\x03\x02\x02\x02\u042A" + - "\u042B\bz\x12\x02\u042B\xFE\x03\x02\x02\x02\u042C\u042D\x05\xFBy\x02\u042D" + - "\u042E\x03\x02\x02\x02\u042E\u042F\b{\x17\x02\u042F\u0100\x03\x02\x02" + - "\x02\u0430\u0431\x053\x15\x02\u0431\u0432\x03\x02\x02\x02\u0432\u0433" + - "\b|\n\x02\u0433\u0102\x03\x02\x02\x02\u0434\u0435\x055\x16\x02\u0435\u0436" + - "\x03\x02\x02\x02\u0436\u0437\b}\n\x02\u0437\u0104\x03\x02\x02\x02\u0438" + - "\u0439\x057\x17\x02\u0439\u043A\x03\x02\x02\x02\u043A\u043B\b~\n\x02\u043B" + - "\u0106\x03\x02\x02\x02\u043C\u043D\x05C\x1D\x02\u043D\u043E\x03\x02\x02" + - "\x02\u043E\u043F\b\x7F\r\x02\u043F\u0440\b\x7F\x0E\x02\u0440\u0441\b\x7F" + - "\x0E\x02\u0441\u0108\x03\x02\x02\x02\u0442\u0443\x05e.\x02\u0443\u0444" + - "\x03\x02\x02\x02\u0444\u0445\b\x80\x11\x02\u0445\u010A\x03\x02\x02\x02" + - "\u0446\u0447\x05g/\x02\u0447\u0448\x03\x02\x02\x02\u0448\u0449\b\x81\x10" + - "\x02\u0449\u010C\x03\x02\x02\x02\u044A\u044B\x05k1"; + "\x03\x02\x02\x02\u0103\u0430\x03\x02\x02\x02\u0105\u0434\x03\x02\x02\x02" + + "\u0107\u043A\x03\x02\x02\x02\u0109\u043E\x03\x02\x02\x02\u010B\u0442\x03" + + "\x02\x02\x02\u010D\u0446\x03\x02\x02\x02\u010F\u044A\x03\x02\x02\x02\u0111" + + "\u044E\x03\x02\x02\x02\u0113\u0452\x03\x02\x02\x02\u0115\u0456\x03\x02" + + "\x02\x02\u0117\u045A\x03\x02\x02\x02\u0119\u045E\x03\x02\x02\x02\u011B" + + "\u0463\x03\x02\x02\x02\u011D\u0467\x03\x02\x02\x02\u011F\u046B\x03\x02" + + "\x02\x02\u0121\u046F\x03\x02\x02\x02\u0123\u0473\x03\x02\x02\x02\u0125" + + "\u0477\x03\x02\x02\x02\u0127\u047B\x03\x02\x02\x02\u0129\u0480\x03\x02" + + "\x02\x02\u012B\u0485\x03\x02\x02\x02\u012D\u048F\x03\x02\x02\x02\u012F" + + "\u0493\x03\x02\x02\x02\u0131\u0497\x03\x02\x02\x02\u0133\u049B\x03\x02" + + "\x02\x02\u0135\u04A0\x03\x02\x02\x02\u0137\u04A7\x03\x02\x02\x02\u0139" + + "\u04AB\x03\x02\x02\x02\u013B\u04AF\x03\x02\x02\x02\u013D\u04B3\x03\x02" + + "\x02\x02\u013F\u04B7\x03\x02\x02\x02\u0141\u04B9\x03\x02\x02\x02\u0143" + + "\u04BB\x03\x02\x02\x02\u0145\u04BD\x03\x02\x02\x02\u0147\u04BF\x03\x02" + + "\x02\x02\u0149\u04C1\x03\x02\x02\x02\u014B\u04C3\x03\x02\x02\x02\u014D" + + "\u04C5\x03\x02\x02\x02\u014F\u04C7\x03\x02\x02\x02\u0151\u04C9\x03\x02" + + "\x02\x02\u0153\u04CB\x03\x02\x02\x02\u0155\u04CD\x03\x02\x02\x02\u0157" + + "\u04CF\x03\x02\x02\x02\u0159\u04D1\x03\x02\x02\x02\u015B\u04D3\x03\x02" + + "\x02\x02\u015D\u04D5\x03\x02\x02\x02\u015F\u04D7\x03\x02\x02\x02\u0161" + + "\u04D9\x03\x02\x02\x02\u0163\u04DB\x03\x02\x02\x02\u0165\u04DD\x03\x02" + + "\x02\x02\u0167\u04DF\x03\x02\x02\x02\u0169\u04E1\x03\x02\x02\x02\u016B" + + "\u04E3\x03\x02\x02\x02\u016D\u04E5\x03\x02\x02\x02\u016F\u04E7\x03\x02" + + "\x02\x02\u0171\u04E9\x03\x02\x02\x02\u0173\u0174\x05\u0145\x9E\x02\u0174" + + "\u0175\x05\u014F\xA3\x02\u0175\u0176\x05\u0163\xAD\x02\u0176\u0177\x05" + + "\u0163\xAD\x02\u0177\u0178\x05\u0147\x9F\x02\u0178\u0179\x05\u0143\x9D" + + "\x02\u0179\u017A\x05\u0165\xAE\x02\u017A\u017B\x03\x02\x02\x02\u017B\u017C" + + "\b\x02\x02\x02\u017C\x0E\x03\x02\x02\x02\u017D\u017E\x05\u0145\x9E\x02" + + "\u017E\u017F\x05\u0161\xAC\x02\u017F\u0180\x05\u015B\xA9\x02\u0180\u0181" + + "\x05\u015D\xAA\x02\u0181\u0182\x03\x02\x02\x02\u0182\u0183\b\x03\x03\x02" + + "\u0183\x10\x03\x02\x02\x02\u0184\u0185\x05\u0147\x9F\x02\u0185\u0186\x05" + + "\u0159\xA8\x02\u0186\u0187\x05\u0161\xAC\x02\u0187\u0188\x05\u014F\xA3" + + "\x02\u0188\u0189\x05\u0143\x9D\x02\u0189\u018A\x05\u014D\xA2\x02\u018A" + + "\u018B\x03\x02\x02\x02\u018B\u018C\b\x04\x04\x02\u018C\x12\x03\x02\x02" + + "\x02\u018D\u018E\x05\u0147\x9F\x02\u018E\u018F\x05\u0169\xB0\x02\u018F" + + "\u0190\x05\u013F\x9B\x02\u0190\u0191\x05\u0155\xA6\x02\u0191\u0192\x03" + + "\x02\x02\x02\u0192\u0193\b\x05\x02\x02\u0193\x14\x03\x02\x02\x02\u0194" + + "\u0195\x05\u0147\x9F\x02\u0195\u0196\x05\u016D\xB2\x02\u0196\u0197\x05" + + "\u015D\xAA\x02\u0197\u0198\x05\u0155\xA6\x02\u0198\u0199\x05\u013F\x9B" + + "\x02\u0199\u019A\x05\u014F\xA3\x02\u019A\u019B\x05\u0159\xA8\x02\u019B" + + "\u019C\x03\x02\x02\x02\u019C\u019D\b\x06\x05\x02\u019D\x16\x03\x02\x02" + + "\x02\u019E\u019F\x05\u0149\xA0\x02\u019F\u01A0\x05\u0161\xAC\x02\u01A0" + + "\u01A1\x05\u015B\xA9\x02\u01A1\u01A2\x05\u0157\xA7\x02\u01A2\u01A3\x03" + + "\x02\x02\x02\u01A3\u01A4\b\x07\x06\x02\u01A4\x18\x03\x02\x02\x02\u01A5" + + "\u01A6\x05\u014B\xA1\x02\u01A6\u01A7\x05\u0161\xAC\x02\u01A7\u01A8\x05" + + "\u015B\xA9\x02\u01A8\u01A9\x05\u0153\xA5\x02\u01A9\u01AA\x03\x02\x02\x02" + + "\u01AA\u01AB\b\b\x02\x02\u01AB\x1A\x03\x02\x02\x02\u01AC\u01AD\x05\u014F" + + "\xA3\x02\u01AD\u01AE\x05\u0159\xA8\x02\u01AE\u01AF\x05\u0155\xA6\x02\u01AF" + + "\u01B0\x05\u014F\xA3\x02\u01B0\u01B1\x05\u0159\xA8\x02\u01B1\u01B2\x05" + + "\u0147\x9F\x02\u01B2\u01B3\x05\u0163\xAD\x02\u01B3\u01B4\x05\u0165\xAE" + + "\x02\u01B4\u01B5\x05\u013F\x9B\x02\u01B5\u01B6\x05\u0165\xAE\x02\u01B6" + + "\u01B7\x05\u0163\xAD\x02\u01B7\u01B8\x03\x02\x02\x02\u01B8\u01B9\b\t\x02" + + "\x02\u01B9\x1C\x03\x02\x02\x02\u01BA\u01BB\x05\u0153\xA5\x02\u01BB\u01BC" + + "\x05\u0147\x9F\x02\u01BC\u01BD\x05\u0147\x9F\x02\u01BD\u01BE\x05\u015D" + + "\xAA\x02\u01BE\u01BF\x03\x02\x02\x02\u01BF\u01C0\b\n\x03\x02\u01C0\x1E" + + "\x03\x02\x02\x02\u01C1\u01C2\x05\u0155\xA6\x02\u01C2\u01C3\x05\u014F\xA3" + + "\x02\u01C3\u01C4\x05\u0157\xA7\x02\u01C4\u01C5\x05\u014F\xA3\x02\u01C5" + + "\u01C6\x05\u0165\xAE\x02\u01C6\u01C7\x03\x02\x02\x02\u01C7\u01C8\b\v\x02" + + "\x02\u01C8 \x03\x02\x02\x02\u01C9\u01CA\x05\u0157\xA7\x02\u01CA\u01CB" + + "\x05\u0169\xB0\x02\u01CB\u01CC\x05S%\x02\u01CC\u01CD\x05\u0147\x9F\x02" + + "\u01CD\u01CE\x05\u016D\xB2\x02\u01CE\u01CF\x05\u015D\xAA\x02\u01CF\u01D0" + + "\x05\u013F\x9B\x02\u01D0\u01D1\x05\u0159\xA8\x02\u01D1\u01D2\x05\u0145" + + "\x9E\x02\u01D2\u01D3\x03\x02\x02\x02\u01D3\u01D4\b\f\x07\x02\u01D4\"\x03" + + "\x02\x02\x02\u01D5\u01D6\x05\u0161\xAC\x02\u01D6\u01D7\x05\u0147\x9F\x02" + + "\u01D7\u01D8\x05\u0159\xA8\x02\u01D8\u01D9\x05\u013F\x9B\x02\u01D9\u01DA" + + "\x05\u0157\xA7\x02\u01DA\u01DB\x05\u0147\x9F\x02\u01DB\u01DC\x03\x02\x02" + + "\x02\u01DC\u01DD\b\r\b\x02\u01DD$\x03\x02\x02\x02\u01DE\u01DF\x05\u0161" + + "\xAC\x02\u01DF\u01E0\x05\u015B\xA9\x02\u01E0\u01E1\x05\u016B\xB1\x02\u01E1" + + "\u01E2\x03\x02\x02\x02\u01E2\u01E3\b\x0E\x02\x02\u01E3&\x03\x02\x02\x02" + + "\u01E4\u01E5\x05\u0163\xAD\x02\u01E5\u01E6\x05\u014D\xA2\x02\u01E6\u01E7" + + "\x05\u015B\xA9\x02\u01E7\u01E8\x05\u016B\xB1\x02\u01E8\u01E9\x03\x02\x02" + + "\x02\u01E9\u01EA\b\x0F\t\x02\u01EA(\x03\x02\x02\x02\u01EB\u01EC\x05\u0163" + + "\xAD\x02\u01EC\u01ED\x05\u015B\xA9\x02\u01ED\u01EE\x05\u0161\xAC\x02\u01EE" + + "\u01EF\x05\u0165\xAE\x02\u01EF\u01F0\x03\x02\x02\x02\u01F0\u01F1\b\x10" + + "\x02\x02\u01F1*\x03\x02\x02\x02\u01F2\u01F3\x05\u0163\xAD\x02\u01F3\u01F4" + + "\x05\u0165\xAE\x02\u01F4\u01F5\x05\u013F\x9B\x02\u01F5\u01F6\x05\u0165" + + "\xAE\x02\u01F6\u01F7\x05\u0163\xAD\x02\u01F7\u01F8\x03\x02\x02\x02\u01F8" + + "\u01F9\b\x11\x02\x02\u01F9,\x03\x02\x02\x02\u01FA\u01FB\x05\u016B\xB1" + + "\x02\u01FB\u01FC\x05\u014D\xA2\x02\u01FC\u01FD\x05\u0147\x9F\x02\u01FD" + + "\u01FE\x05\u0161\xAC\x02\u01FE\u01FF\x05\u0147\x9F\x02\u01FF\u0200\x03" + + "\x02\x02\x02\u0200\u0201\b\x12\x02\x02\u0201.\x03\x02\x02\x02\u0202\u0204" + + "\n\x02\x02\x02\u0203\u0202\x03\x02\x02\x02\u0204\u0205\x03\x02\x02\x02" + + "\u0205\u0203\x03\x02\x02\x02\u0205\u0206\x03\x02\x02\x02\u0206\u0207\x03" + + "\x02\x02\x02\u0207\u0208\b\x13\x02\x02\u02080\x03\x02\x02\x02\u0209\u020A" + + "\x071\x02\x02\u020A\u020B\x071\x02\x02\u020B\u020F\x03\x02\x02\x02\u020C" + + "\u020E\n\x03\x02\x02\u020D\u020C\x03\x02\x02\x02\u020E\u0211\x03\x02\x02" + + "\x02\u020F\u020D\x03\x02\x02\x02\u020F\u0210\x03\x02\x02\x02\u0210\u0213" + + "\x03\x02\x02\x02\u0211\u020F\x03\x02\x02\x02\u0212\u0214\x07\x0F\x02\x02" + + "\u0213\u0212\x03\x02\x02\x02\u0213\u0214\x03\x02\x02\x02\u0214\u0216\x03" + + "\x02\x02\x02\u0215\u0217\x07\f\x02\x02\u0216\u0215\x03\x02\x02\x02\u0216" + + "\u0217\x03\x02\x02\x02\u0217\u0218\x03\x02\x02\x02\u0218\u0219\b\x14\n" + + "\x02\u02192\x03\x02\x02\x02\u021A\u021B\x071\x02\x02\u021B\u021C\x07," + + "\x02\x02\u021C\u0221\x03\x02\x02\x02\u021D\u0220\x053\x15\x02\u021E\u0220" + + "\v\x02\x02\x02\u021F\u021D\x03\x02\x02\x02\u021F\u021E\x03\x02\x02\x02" + + "\u0220\u0223\x03\x02\x02\x02\u0221\u0222\x03\x02\x02\x02\u0221\u021F\x03" + + "\x02\x02\x02\u0222\u0224\x03\x02\x02\x02\u0223\u0221\x03\x02\x02\x02\u0224" + + "\u0225\x07,\x02\x02\u0225\u0226\x071\x02\x02\u0226\u0227\x03\x02\x02\x02" + + "\u0227\u0228\b\x15\n\x02\u02284\x03\x02\x02\x02\u0229\u022B\t\x04\x02" + + "\x02\u022A\u0229\x03\x02\x02\x02\u022B\u022C\x03\x02\x02\x02\u022C\u022A" + + "\x03\x02\x02\x02\u022C\u022D\x03\x02\x02\x02\u022D\u022E\x03\x02\x02\x02" + + "\u022E\u022F\b\x16\n\x02\u022F6\x03\x02\x02\x02\u0230\u0231\x05\xA1L\x02" + + "\u0231\u0232\x03\x02\x02\x02\u0232\u0233\b\x17\v\x02\u0233\u0234\b\x17" + + "\f\x02\u02348\x03\x02\x02\x02\u0235\u0236\x05A\x1C\x02\u0236\u0237\x03" + + "\x02\x02\x02\u0237\u0238\b\x18\r\x02\u0238\u0239\b\x18\x0E\x02\u0239:" + + "\x03\x02\x02\x02\u023A\u023B\x055\x16\x02\u023B\u023C\x03\x02\x02\x02" + + "\u023C\u023D\b\x19\n\x02\u023D<\x03\x02\x02\x02\u023E\u023F\x051\x14\x02" + + "\u023F\u0240\x03\x02\x02\x02\u0240\u0241\b\x1A\n\x02\u0241>\x03\x02\x02" + + "\x02\u0242\u0243\x053\x15\x02\u0243\u0244\x03\x02\x02\x02\u0244\u0245" + + "\b\x1B\n\x02\u0245@\x03\x02\x02\x02\u0246\u0247\x07~\x02\x02\u0247\u0248" + + "\x03\x02\x02\x02\u0248\u0249\b\x1C\x0E\x02\u0249B\x03\x02\x02\x02\u024A" + + "\u024B\t\x05\x02\x02\u024BD\x03\x02\x02\x02\u024C\u024D\t\x06\x02\x02" + + "\u024DF\x03\x02\x02\x02\u024E\u024F\x07^\x02\x02\u024F\u0250\t\x07\x02" + + "\x02\u0250H\x03\x02\x02\x02\u0251\u0252\n\b\x02\x02\u0252J\x03\x02\x02" + + "\x02\u0253\u0255\t\t\x02\x02\u0254\u0256\t\n\x02\x02\u0255\u0254\x03\x02" + + "\x02\x02\u0255\u0256\x03\x02\x02\x02\u0256\u0258\x03\x02\x02\x02\u0257" + + "\u0259\x05C\x1D\x02\u0258\u0257\x03\x02\x02\x02\u0259\u025A\x03\x02\x02" + + "\x02\u025A\u0258\x03\x02\x02\x02\u025A\u025B\x03\x02\x02\x02\u025BL\x03" + + "\x02\x02\x02\u025C\u025D\x07B\x02\x02\u025DN\x03\x02\x02\x02\u025E\u025F" + + "\x07b\x02\x02\u025FP\x03\x02\x02\x02\u0260\u0264\n\v\x02\x02\u0261\u0262" + + "\x07b\x02\x02\u0262\u0264\x07b\x02\x02\u0263\u0260\x03\x02\x02\x02\u0263" + + "\u0261\x03\x02\x02\x02\u0264R\x03\x02\x02\x02\u0265\u0266\x07a\x02\x02" + + "\u0266T\x03\x02\x02\x02\u0267\u026B\x05E\x1E\x02\u0268\u026B\x05C\x1D" + + "\x02\u0269\u026B\x05S%\x02\u026A\u0267\x03\x02\x02\x02\u026A\u0268\x03" + + "\x02\x02\x02\u026A\u0269\x03\x02\x02\x02\u026BV\x03\x02\x02\x02\u026C" + + "\u0271\x07$\x02\x02\u026D\u0270\x05G\x1F\x02\u026E\u0270\x05I \x02\u026F" + + "\u026D\x03\x02\x02\x02\u026F\u026E\x03\x02\x02\x02\u0270\u0273\x03\x02" + + "\x02\x02\u0271\u026F\x03\x02\x02\x02\u0271\u0272\x03\x02\x02\x02\u0272" + + "\u0274\x03\x02\x02\x02\u0273\u0271\x03\x02\x02\x02\u0274\u028A\x07$\x02" + + "\x02\u0275\u0276\x07$\x02\x02\u0276\u0277\x07$\x02\x02\u0277\u0278\x07" + + "$\x02\x02\u0278\u027C\x03\x02\x02\x02\u0279\u027B\n\x03\x02\x02\u027A" + + "\u0279\x03\x02\x02\x02\u027B\u027E\x03\x02\x02\x02\u027C\u027D\x03\x02" + + "\x02\x02\u027C\u027A\x03\x02\x02\x02\u027D\u027F\x03\x02\x02\x02\u027E" + + "\u027C\x03\x02\x02\x02\u027F\u0280\x07$\x02\x02\u0280\u0281\x07$\x02\x02" + + "\u0281\u0282\x07$\x02\x02\u0282\u0284\x03\x02\x02\x02\u0283\u0285\x07" + + "$\x02\x02\u0284\u0283\x03\x02\x02\x02\u0284\u0285\x03\x02\x02\x02\u0285" + + "\u0287\x03\x02\x02\x02\u0286\u0288\x07$\x02\x02\u0287\u0286\x03\x02\x02" + + "\x02\u0287\u0288\x03\x02\x02\x02\u0288\u028A\x03\x02\x02\x02\u0289\u026C" + + "\x03\x02\x02\x02\u0289\u0275\x03\x02\x02\x02\u028AX\x03\x02\x02\x02\u028B" + + "\u028D\x05C\x1D\x02\u028C\u028B\x03\x02\x02\x02\u028D\u028E\x03\x02\x02" + + "\x02\u028E\u028C\x03\x02\x02\x02\u028E\u028F\x03\x02\x02\x02\u028FZ\x03" + + "\x02\x02\x02\u0290\u0292\x05C\x1D\x02\u0291\u0290\x03\x02\x02\x02\u0292" + + "\u0293\x03\x02\x02\x02\u0293\u0291\x03\x02\x02\x02\u0293\u0294\x03\x02" + + "\x02\x02\u0294\u0295\x03\x02\x02\x02\u0295\u0299\x05i0\x02\u0296\u0298" + + "\x05C\x1D\x02\u0297\u0296\x03\x02\x02\x02\u0298\u029B\x03\x02\x02\x02" + + "\u0299\u0297\x03\x02\x02\x02\u0299\u029A\x03\x02\x02\x02\u029A\u02BB\x03" + + "\x02\x02\x02\u029B\u0299\x03\x02\x02\x02\u029C\u029E\x05i0\x02\u029D\u029F" + + "\x05C\x1D\x02\u029E\u029D\x03\x02\x02\x02\u029F\u02A0\x03\x02\x02\x02" + + "\u02A0\u029E\x03\x02\x02\x02\u02A0\u02A1\x03\x02\x02\x02\u02A1\u02BB\x03" + + "\x02\x02\x02\u02A2\u02A4\x05C\x1D\x02\u02A3\u02A2\x03\x02\x02\x02\u02A4" + + "\u02A5\x03\x02\x02\x02\u02A5\u02A3\x03\x02\x02\x02\u02A5\u02A6\x03\x02" + + "\x02\x02\u02A6\u02AE\x03\x02\x02\x02\u02A7\u02AB\x05i0\x02\u02A8\u02AA" + + "\x05C\x1D\x02\u02A9\u02A8\x03\x02\x02\x02\u02AA\u02AD\x03\x02\x02\x02" + + "\u02AB\u02A9\x03\x02\x02\x02\u02AB\u02AC\x03\x02\x02\x02\u02AC\u02AF\x03" + + "\x02\x02\x02\u02AD\u02AB\x03\x02\x02\x02\u02AE\u02A7\x03\x02\x02\x02\u02AE" + + "\u02AF\x03\x02\x02\x02\u02AF\u02B0\x03\x02\x02\x02\u02B0\u02B1\x05K!\x02" + + "\u02B1\u02BB\x03\x02\x02\x02\u02B2\u02B4\x05i0\x02\u02B3\u02B5\x05C\x1D" + + "\x02\u02B4\u02B3\x03\x02\x02\x02\u02B5\u02B6\x03\x02\x02\x02\u02B6\u02B4" + + "\x03\x02\x02\x02\u02B6\u02B7\x03\x02\x02\x02\u02B7\u02B8\x03\x02\x02\x02" + + "\u02B8\u02B9\x05K!\x02\u02B9\u02BB\x03\x02\x02\x02\u02BA\u0291\x03\x02" + + "\x02\x02\u02BA\u029C\x03\x02\x02\x02\u02BA\u02A3\x03\x02\x02\x02\u02BA" + + "\u02B2\x03\x02\x02\x02\u02BB\\\x03\x02\x02\x02\u02BC\u02BD\x05\u0141\x9C" + + "\x02\u02BD\u02BE\x05\u016F\xB3\x02\u02BE^\x03\x02\x02\x02\u02BF\u02C0" + + "\x05\u013F\x9B\x02\u02C0\u02C1\x05\u0159\xA8\x02\u02C1\u02C2\x05\u0145" + + "\x9E\x02\u02C2`\x03\x02\x02\x02\u02C3\u02C4\x05\u013F\x9B\x02\u02C4\u02C5" + + "\x05\u0163\xAD\x02\u02C5\u02C6\x05\u0143\x9D\x02\u02C6b\x03\x02\x02\x02" + + "\u02C7\u02C8\x07?\x02\x02\u02C8d\x03\x02\x02\x02\u02C9\u02CA\x07.\x02" + + "\x02\u02CAf\x03\x02\x02\x02\u02CB\u02CC\x05\u0145\x9E\x02\u02CC\u02CD" + + "\x05\u0147\x9F\x02\u02CD\u02CE\x05\u0163\xAD\x02\u02CE\u02CF\x05\u0143" + + "\x9D\x02\u02CFh\x03\x02\x02\x02\u02D0\u02D1\x070\x02\x02\u02D1j\x03\x02" + + "\x02\x02\u02D2\u02D3\x05\u0149\xA0\x02\u02D3\u02D4\x05\u013F\x9B\x02\u02D4" + + "\u02D5\x05\u0155\xA6\x02\u02D5\u02D6\x05\u0163\xAD\x02\u02D6\u02D7\x05" + + "\u0147\x9F\x02\u02D7l\x03\x02\x02\x02\u02D8\u02D9\x05\u0149\xA0\x02\u02D9" + + "\u02DA\x05\u014F\xA3\x02\u02DA\u02DB\x05\u0161\xAC\x02\u02DB\u02DC\x05" + + "\u0163\xAD\x02\u02DC\u02DD\x05\u0165\xAE\x02\u02DDn\x03\x02\x02\x02\u02DE" + + "\u02DF\x05\u0155\xA6\x02\u02DF\u02E0\x05\u013F\x9B\x02\u02E0\u02E1\x05" + + "\u0163\xAD\x02\u02E1\u02E2\x05\u0165\xAE\x02\u02E2p\x03\x02\x02\x02\u02E3" + + "\u02E4\x07*\x02\x02\u02E4r\x03\x02\x02\x02\u02E5\u02E6\x05\u014F\xA3\x02" + + "\u02E6\u02E7\x05\u0159\xA8\x02\u02E7t\x03\x02\x02\x02\u02E8\u02E9\x05" + + "\u014F\xA3\x02\u02E9\u02EA\x05\u0163\xAD\x02\u02EAv\x03\x02\x02\x02\u02EB" + + "\u02EC\x05\u0155\xA6\x02\u02EC\u02ED\x05\u014F\xA3\x02\u02ED\u02EE\x05" + + "\u0153\xA5\x02\u02EE\u02EF\x05\u0147\x9F\x02\u02EFx\x03\x02\x02\x02\u02F0" + + "\u02F1\x05\u0159\xA8\x02\u02F1\u02F2\x05\u015B\xA9\x02\u02F2\u02F3\x05" + + "\u0165\xAE\x02\u02F3z\x03\x02\x02\x02\u02F4\u02F5\x05\u0159\xA8\x02\u02F5" + + "\u02F6\x05\u0167\xAF\x02\u02F6\u02F7\x05\u0155\xA6\x02\u02F7\u02F8\x05" + + "\u0155\xA6\x02\u02F8|\x03\x02\x02\x02\u02F9\u02FA\x05\u0159\xA8\x02\u02FA" + + "\u02FB\x05\u0167\xAF\x02\u02FB\u02FC\x05\u0155\xA6\x02\u02FC\u02FD\x05" + + "\u0155\xA6\x02\u02FD\u02FE\x05\u0163\xAD\x02\u02FE~\x03\x02\x02\x02\u02FF" + + "\u0300\x05\u015B\xA9\x02\u0300\u0301\x05\u0161\xAC\x02\u0301\x80\x03\x02" + + "\x02\x02\u0302\u0303\x07A\x02\x02\u0303\x82\x03\x02\x02\x02\u0304\u0305" + + "\x05\u0161\xAC\x02\u0305\u0306\x05\u0155\xA6\x02\u0306\u0307\x05\u014F" + + "\xA3\x02\u0307\u0308\x05\u0153\xA5\x02\u0308\u0309\x05\u0147\x9F\x02\u0309" + + "\x84\x03\x02\x02\x02\u030A\u030B\x07+\x02\x02\u030B\x86\x03\x02\x02\x02" + + "\u030C\u030D\x05\u0165\xAE\x02\u030D\u030E\x05\u0161\xAC\x02\u030E\u030F" + + "\x05\u0167\xAF\x02\u030F\u0310\x05\u0147\x9F\x02\u0310\x88\x03\x02\x02" + + "\x02\u0311\u0312\x07?\x02\x02\u0312\u0313\x07?\x02\x02\u0313\x8A\x03\x02" + + "\x02\x02\u0314\u0315\x07?\x02\x02\u0315\u0316\x07\x80\x02\x02\u0316\x8C" + + "\x03\x02\x02\x02\u0317\u0318\x07#\x02\x02\u0318\u0319\x07?\x02\x02\u0319" + + "\x8E\x03\x02\x02\x02\u031A\u031B\x07>\x02\x02\u031B\x90\x03\x02\x02\x02" + + "\u031C\u031D\x07>\x02\x02\u031D\u031E\x07?\x02\x02\u031E\x92\x03\x02\x02" + + "\x02\u031F\u0320\x07@\x02\x02\u0320\x94\x03\x02\x02\x02\u0321\u0322\x07" + + "@\x02\x02\u0322\u0323\x07?\x02\x02\u0323\x96\x03\x02\x02\x02\u0324\u0325" + + "\x07-\x02\x02\u0325\x98\x03\x02\x02\x02\u0326\u0327\x07/\x02\x02\u0327" + + "\x9A\x03\x02\x02\x02\u0328\u0329\x07,\x02\x02\u0329\x9C\x03\x02\x02\x02" + + "\u032A\u032B\x071\x02\x02\u032B\x9E\x03\x02\x02\x02\u032C\u032D\x07\'" + + "\x02\x02\u032D\xA0\x03\x02\x02\x02\u032E\u032F\x07]\x02\x02\u032F\u0330" + + "\x03\x02\x02\x02\u0330\u0331\bL\x02\x02\u0331\u0332\bL\x02\x02\u0332\xA2" + + "\x03\x02\x02\x02\u0333\u0334\x07_\x02\x02\u0334\u0335\x03\x02\x02\x02" + + "\u0335\u0336\bM\x0E\x02\u0336\u0337\bM\x0E\x02\u0337\xA4\x03\x02\x02\x02" + + "\u0338\u033C\x05E\x1E\x02\u0339\u033B\x05U&\x02\u033A\u0339\x03\x02\x02" + + "\x02\u033B\u033E\x03\x02\x02\x02\u033C\u033A\x03\x02\x02\x02\u033C\u033D" + + "\x03\x02\x02\x02\u033D\u0349\x03\x02\x02\x02\u033E\u033C\x03\x02\x02\x02" + + "\u033F\u0342\x05S%\x02\u0340\u0342\x05M\"\x02\u0341\u033F\x03\x02\x02" + + "\x02\u0341\u0340\x03\x02\x02\x02\u0342\u0344\x03\x02\x02\x02\u0343\u0345" + + "\x05U&\x02\u0344\u0343\x03\x02\x02\x02\u0345\u0346\x03\x02\x02\x02\u0346" + + "\u0344\x03\x02\x02\x02\u0346\u0347\x03\x02\x02\x02\u0347\u0349\x03\x02" + + "\x02\x02\u0348\u0338\x03\x02\x02\x02\u0348\u0341\x03\x02\x02\x02\u0349" + + "\xA6\x03\x02\x02\x02\u034A\u034C\x05O#\x02\u034B\u034D\x05Q$\x02\u034C" + + "\u034B\x03\x02\x02\x02\u034D\u034E\x03\x02\x02\x02\u034E\u034C\x03\x02" + + "\x02\x02\u034E\u034F\x03\x02\x02\x02\u034F\u0350\x03\x02\x02\x02\u0350" + + "\u0351\x05O#\x02\u0351\xA8\x03\x02\x02\x02\u0352\u0353\x051\x14\x02\u0353" + + "\u0354\x03\x02\x02\x02\u0354\u0355\bP\n\x02\u0355\xAA\x03\x02\x02\x02" + + "\u0356\u0357\x053\x15\x02\u0357\u0358\x03\x02\x02\x02\u0358\u0359\bQ\n" + + "\x02\u0359\xAC\x03\x02\x02\x02\u035A\u035B\x055\x16\x02\u035B\u035C\x03" + + "\x02\x02\x02\u035C\u035D\bR\n\x02\u035D\xAE\x03\x02\x02\x02\u035E\u035F" + + "\x05A\x1C\x02\u035F\u0360\x03\x02\x02\x02\u0360\u0361\bS\r\x02\u0361\u0362" + + "\bS\x0E\x02\u0362\xB0\x03\x02\x02\x02\u0363\u0364\x05\xA1L\x02\u0364\u0365" + + "\x03\x02\x02\x02\u0365\u0366\bT\v\x02\u0366\xB2\x03\x02\x02\x02\u0367" + + "\u0368\x05\xA3M\x02\u0368\u0369\x03\x02\x02\x02\u0369\u036A\bU\x0F\x02" + + "\u036A\xB4\x03\x02\x02\x02\u036B\u036C\x05e.\x02\u036C\u036D\x03\x02\x02" + + "\x02\u036D\u036E\bV\x10\x02\u036E\xB6\x03\x02\x02\x02\u036F\u0370\x05" + + "c-\x02\u0370\u0371\x03\x02\x02\x02\u0371\u0372\bW\x11\x02\u0372\xB8\x03" + + "\x02\x02\x02\u0373\u0374\x05\u0157\xA7\x02\u0374\u0375\x05\u0147\x9F\x02" + + "\u0375\u0376\x05\u0165\xAE\x02\u0376\u0377\x05\u013F\x9B\x02\u0377\u0378" + + "\x05\u0145\x9E\x02\u0378\u0379\x05\u013F\x9B\x02\u0379\u037A\x05\u0165" + + "\xAE\x02\u037A\u037B\x05\u013F\x9B\x02\u037B\xBA\x03\x02\x02\x02\u037C" + + "\u0380\n\f\x02\x02\u037D\u037E\x071\x02\x02\u037E\u0380\n\r\x02\x02\u037F" + + "\u037C\x03\x02\x02\x02\u037F\u037D\x03\x02\x02\x02\u0380\xBC\x03\x02\x02" + + "\x02\u0381\u0383\x05\xBBY\x02\u0382\u0381\x03\x02\x02\x02\u0383\u0384" + + "\x03\x02\x02\x02\u0384\u0382\x03\x02\x02\x02\u0384\u0385\x03\x02\x02\x02" + + "\u0385\xBE\x03\x02\x02\x02\u0386\u0387\x05\xA7O\x02\u0387\u0388\x03\x02" + + "\x02\x02\u0388\u0389\b[\x12\x02\u0389\xC0\x03\x02\x02\x02\u038A\u038B" + + "\x051\x14\x02\u038B\u038C\x03\x02\x02\x02\u038C\u038D\b\\\n\x02\u038D" + + "\xC2\x03\x02\x02\x02\u038E\u038F\x053\x15\x02\u038F\u0390\x03\x02\x02" + + "\x02\u0390\u0391\b]\n\x02\u0391\xC4\x03\x02\x02\x02\u0392\u0393\x055\x16" + + "\x02\u0393\u0394\x03\x02\x02\x02\u0394\u0395\b^\n\x02\u0395\xC6\x03\x02" + + "\x02\x02\u0396\u0397\x05A\x1C\x02\u0397\u0398\x03\x02\x02\x02\u0398\u0399" + + "\b_\r\x02\u0399\u039A\b_\x0E\x02\u039A\xC8\x03\x02\x02\x02\u039B\u039C" + + "\x05i0\x02\u039C\u039D\x03\x02\x02\x02\u039D\u039E\b`\x13\x02\u039E\xCA" + + "\x03\x02\x02\x02\u039F\u03A0\x05e.\x02\u03A0\u03A1\x03\x02\x02\x02\u03A1" + + "\u03A2\ba\x10\x02\u03A2\xCC\x03\x02\x02\x02\u03A3\u03A8\x05E\x1E\x02\u03A4" + + "\u03A8\x05C\x1D\x02\u03A5\u03A8\x05S%\x02\u03A6\u03A8\x05\x9BI\x02\u03A7" + + "\u03A3\x03\x02\x02\x02\u03A7\u03A4\x03\x02\x02\x02\u03A7\u03A5\x03\x02" + + "\x02\x02\u03A7\u03A6\x03\x02\x02\x02\u03A8\xCE\x03\x02\x02\x02\u03A9\u03AC" + + "\x05E\x1E\x02\u03AA\u03AC\x05\x9BI\x02\u03AB\u03A9\x03\x02\x02\x02\u03AB" + + "\u03AA\x03\x02\x02\x02\u03AC\u03B0\x03\x02\x02\x02\u03AD\u03AF\x05\xCD" + + "b\x02\u03AE\u03AD\x03\x02\x02\x02\u03AF\u03B2\x03\x02\x02\x02\u03B0\u03AE" + + "\x03\x02\x02\x02\u03B0\u03B1\x03\x02\x02\x02\u03B1\u03BD\x03\x02\x02\x02" + + "\u03B2\u03B0\x03\x02\x02\x02\u03B3\u03B6\x05S%\x02\u03B4\u03B6\x05M\"" + + "\x02\u03B5\u03B3\x03\x02\x02\x02\u03B5\u03B4\x03\x02\x02\x02\u03B6\u03B8" + + "\x03\x02\x02\x02\u03B7\u03B9\x05\xCDb\x02\u03B8\u03B7\x03\x02\x02\x02" + + "\u03B9\u03BA\x03\x02\x02\x02\u03BA\u03B8\x03\x02\x02\x02\u03BA\u03BB\x03" + + "\x02\x02\x02\u03BB\u03BD\x03\x02\x02\x02\u03BC\u03AB\x03\x02\x02\x02\u03BC" + + "\u03B5\x03\x02\x02\x02\u03BD\xD0\x03\x02\x02\x02\u03BE\u03BF\x05\xCFc" + + "\x02\u03BF\u03C0\x03\x02\x02\x02\u03C0\u03C1\bd\x14\x02\u03C1\xD2\x03" + + "\x02\x02\x02\u03C2\u03C3\x05\xA7O\x02\u03C3\u03C4\x03\x02\x02\x02\u03C4" + + "\u03C5\be\x12\x02\u03C5\xD4\x03\x02\x02\x02\u03C6\u03C7\x051\x14\x02\u03C7" + + "\u03C8\x03\x02\x02\x02\u03C8\u03C9\bf\n\x02\u03C9\xD6\x03\x02\x02\x02" + + "\u03CA\u03CB\x053\x15\x02\u03CB\u03CC\x03\x02\x02\x02\u03CC\u03CD\bg\n" + + "\x02\u03CD\xD8\x03\x02\x02\x02\u03CE\u03CF\x055\x16\x02\u03CF\u03D0\x03" + + "\x02\x02\x02\u03D0\u03D1\bh\n\x02\u03D1\xDA\x03\x02\x02\x02\u03D2\u03D3" + + "\x05A\x1C\x02\u03D3\u03D4\x03\x02\x02\x02\u03D4\u03D5\bi\r\x02\u03D5\u03D6" + + "\bi\x0E\x02\u03D6\xDC\x03\x02\x02\x02\u03D7\u03D8\x05c-\x02\u03D8\u03D9" + + "\x03\x02\x02\x02\u03D9\u03DA\bj\x11\x02\u03DA\xDE\x03\x02\x02\x02\u03DB" + + "\u03DC\x05e.\x02\u03DC\u03DD\x03\x02\x02\x02\u03DD\u03DE\bk\x10\x02\u03DE" + + "\xE0\x03\x02\x02\x02\u03DF\u03E0\x05i0\x02\u03E0\u03E1\x03\x02\x02\x02" + + "\u03E1\u03E2\bl\x13\x02\u03E2\xE2\x03\x02\x02\x02\u03E3\u03E4\x05\u013F" + + "\x9B\x02\u03E4\u03E5\x05\u0163\xAD\x02\u03E5\xE4\x03\x02\x02\x02\u03E6" + + "\u03E7\x05\xA7O\x02\u03E7\u03E8\x03\x02\x02\x02\u03E8\u03E9\bn\x12\x02" + + "\u03E9\xE6\x03\x02\x02\x02\u03EA\u03EB\x05\xCFc\x02\u03EB\u03EC\x03\x02" + + "\x02\x02\u03EC\u03ED\bo\x14\x02\u03ED\xE8\x03\x02\x02\x02\u03EE\u03EF" + + "\x051\x14\x02\u03EF\u03F0\x03\x02\x02\x02\u03F0\u03F1\bp\n\x02\u03F1\xEA" + + "\x03\x02\x02\x02\u03F2\u03F3\x053\x15\x02\u03F3\u03F4\x03\x02\x02\x02" + + "\u03F4\u03F5\bq\n\x02\u03F5\xEC\x03\x02\x02\x02\u03F6\u03F7\x055\x16\x02" + + "\u03F7\u03F8\x03\x02\x02\x02\u03F8\u03F9\br\n\x02\u03F9\xEE\x03\x02\x02" + + "\x02\u03FA\u03FB\x05A\x1C\x02\u03FB\u03FC\x03\x02\x02\x02\u03FC\u03FD" + + "\bs\r\x02\u03FD\u03FE\bs\x0E\x02\u03FE\xF0\x03\x02\x02\x02\u03FF\u0400" + + "\x05\xA1L\x02\u0400\u0401\x03\x02\x02\x02\u0401\u0402\bt\v\x02\u0402\u0403" + + "\bt\x15\x02\u0403\xF2\x03\x02\x02\x02\u0404\u0405\x05\u015B\xA9\x02\u0405" + + "\u0406\x05\u0159\xA8\x02\u0406\u0407\x03\x02\x02\x02\u0407\u0408\bu\x16" + + "\x02\u0408\xF4\x03\x02\x02\x02\u0409\u040A\x05\u016B\xB1\x02\u040A\u040B" + + "\x05\u014F\xA3\x02\u040B\u040C\x05\u0165\xAE\x02\u040C\u040D\x05\u014D" + + "\xA2\x02\u040D\u040E\x03\x02\x02\x02\u040E\u040F\bv\x16\x02\u040F\xF6" + + "\x03\x02\x02\x02\u0410\u0411\n\x0E\x02\x02\u0411\xF8\x03\x02\x02\x02\u0412" + + "\u0414\x05\xF7w\x02\u0413\u0412\x03\x02\x02\x02\u0414\u0415\x03\x02\x02" + + "\x02\u0415\u0413\x03\x02\x02\x02\u0415\u0416\x03\x02\x02\x02\u0416\u0417" + + "\x03\x02\x02\x02\u0417\u0418\x05\u0135\x96\x02\u0418\u041A\x03\x02\x02" + + "\x02\u0419\u0413\x03\x02\x02\x02\u0419\u041A\x03\x02\x02\x02\u041A\u041C" + + "\x03\x02\x02\x02\u041B\u041D\x05\xF7w\x02\u041C\u041B\x03\x02\x02\x02" + + "\u041D\u041E\x03\x02\x02\x02\u041E\u041C\x03\x02\x02\x02\u041E\u041F\x03" + + "\x02\x02\x02\u041F\xFA\x03\x02\x02\x02\u0420\u0421\x05\xA7O\x02\u0421" + + "\u0422\x03\x02\x02\x02\u0422\u0423\by\x12\x02\u0423\xFC\x03\x02\x02\x02" + + "\u0424\u0425\x05\xF9x\x02\u0425\u0426\x03\x02\x02\x02\u0426\u0427\bz\x17" + + "\x02\u0427\xFE\x03\x02\x02\x02\u0428\u0429\x051\x14\x02\u0429\u042A\x03" + + "\x02\x02\x02\u042A\u042B\b{\n\x02\u042B\u0100\x03\x02\x02\x02\u042C\u042D" + + "\x053\x15\x02\u042D\u042E\x03\x02\x02\x02\u042E\u042F\b|\n\x02\u042F\u0102" + + "\x03\x02\x02\x02\u0430\u0431\x055\x16\x02\u0431\u0432\x03\x02\x02\x02" + + "\u0432\u0433\b}\n\x02\u0433\u0104\x03\x02\x02\x02\u0434\u0435\x05A\x1C" + + "\x02\u0435\u0436\x03\x02\x02\x02\u0436\u0437\b~\r\x02\u0437\u0438\b~\x0E" + + "\x02\u0438\u0439\b~\x0E\x02\u0439\u0106\x03\x02\x02\x02\u043A\u043B\x05" + + "c-\x02\u043B\u043C\x03\x02\x02\x02\u043C\u043D\b\x7F\x11\x02\u043D\u0108" + + "\x03\x02\x02\x02\u043E\u043F\x05e.\x02\u043F\u0440\x03\x02\x02\x02\u0440" + + "\u0441\b\x80\x10\x02\u0441\u010A\x03\x02\x02\x02\u0442\u0443\x05i0\x02" + + "\u0443\u0444\x03\x02\x02\x02\u0444\u0445\b\x81\x13\x02\u0445\u010C\x03" + + "\x02\x02\x02\u0446\u0447\x05\xF5v\x02\u0447\u0448\x03\x02\x02\x02\u0448" + + "\u0449\b\x82\x18\x02\u0449\u010E\x03\x02\x02\x02\u044A\u044B\x05\xCFc" + + "\x02\u044B\u044C\x03\x02\x02\x02\u044C\u044D\b\x83"; private static readonly _serializedATNSegment2: string = - "\x02\u044B\u044C\x03\x02\x02\x02\u044C\u044D\b\x82\x13\x02\u044D\u010E" + - "\x03\x02\x02\x02\u044E\u044F\x05\xF7w\x02\u044F\u0450\x03\x02\x02\x02" + - "\u0450\u0451\b\x83\x18\x02\u0451\u0110\x03\x02\x02\x02\u0452\u0453\x05" + - "\xD1d\x02\u0453\u0454\x03\x02\x02\x02\u0454\u0455\b\x84\x14\x02\u0455" + - "\u0112\x03\x02\x02\x02\u0456\u0457\x05\xA9P\x02\u0457\u0458\x03\x02\x02" + - "\x02\u0458\u0459\b\x85\x12\x02\u0459\u0114\x03\x02\x02\x02\u045A\u045B" + - "\x053\x15\x02\u045B\u045C\x03\x02\x02\x02\u045C\u045D\b\x86\n\x02\u045D" + - "\u0116\x03\x02\x02\x02\u045E\u045F\x055\x16\x02\u045F\u0460\x03\x02\x02" + - "\x02\u0460\u0461\b\x87\n\x02\u0461\u0118\x03\x02\x02\x02\u0462\u0463\x05" + - "7\x17\x02\u0463\u0464\x03\x02\x02\x02\u0464\u0465\b\x88\n\x02\u0465\u011A" + - "\x03\x02\x02\x02\u0466\u0467\x05C\x1D\x02\u0467\u0468\x03\x02\x02\x02" + - "\u0468\u0469\b\x89\r\x02\u0469\u046A\b\x89\x0E\x02\u046A\u011C\x03\x02" + - "\x02\x02\u046B\u046C\x05k1\x02\u046C\u046D\x03\x02\x02\x02\u046D\u046E" + - "\b\x8A\x13\x02\u046E\u011E\x03\x02\x02\x02\u046F\u0470\x05\xA9P\x02\u0470" + - "\u0471\x03\x02\x02\x02\u0471\u0472\b\x8B\x12\x02\u0472\u0120\x03\x02\x02" + - "\x02\u0473\u0474\x05\xA7O\x02\u0474\u0475\x03\x02\x02\x02\u0475\u0476" + - "\b\x8C\x19\x02\u0476\u0122\x03\x02\x02\x02\u0477\u0478\x053\x15\x02\u0478" + - "\u0479\x03\x02\x02\x02\u0479\u047A\b\x8D\n\x02\u047A\u0124\x03\x02\x02" + - "\x02\u047B\u047C\x055\x16\x02\u047C\u047D\x03\x02\x02\x02\u047D\u047E" + - "\b\x8E\n\x02\u047E\u0126\x03\x02\x02\x02\u047F\u0480\x057\x17\x02\u0480" + - "\u0481\x03\x02\x02\x02\u0481\u0482\b\x8F\n\x02\u0482\u0128\x03\x02\x02" + - "\x02\u0483\u0484\x05C\x1D\x02\u0484\u0485\x03\x02\x02\x02\u0485\u0486" + - "\b\x90\r\x02\u0486\u0487\b\x90\x0E\x02\u0487\u012A\x03\x02\x02\x02\u0488" + - "\u0489\x05\u0151\xA4\x02\u0489\u048A\x05\u015B\xA9\x02\u048A\u048B\x05" + - "\u014B\xA1\x02\u048B\u048C\x05\u015D\xAA\x02\u048C\u012C\x03\x02\x02\x02" + - "\u048D\u048E\x05\u014B\xA1\x02\u048E\u048F\x05\u0169\xB0\x02\u048F\u0490" + - "\x05\u015B\xA9\x02\u0490\u0491\x05\u0145\x9E\x02\u0491\u0492\x05\u0167" + - "\xAF\x02\u0492\u0493\x05\u0151\xA4\x02\u0493\u0494\x05\u015D\xAA\x02\u0494" + - "\u0495\x05\u015B\xA9\x02\u0495\u0496\x05\u0165\xAE\x02\u0496\u012E\x03" + - "\x02\x02\x02\u0497\u0498\x053\x15\x02\u0498\u0499\x03\x02\x02\x02\u0499" + - "\u049A\b\x93\n\x02\u049A\u0130\x03\x02\x02\x02\u049B\u049C\x055\x16\x02" + - "\u049C\u049D\x03\x02\x02\x02\u049D\u049E\b\x94\n\x02\u049E\u0132\x03\x02" + - "\x02\x02\u049F\u04A0\x057\x17\x02\u04A0\u04A1\x03\x02\x02\x02\u04A1\u04A2" + - "\b\x95\n\x02\u04A2\u0134\x03\x02\x02\x02\u04A3\u04A4\x05\xA5N\x02\u04A4" + - "\u04A5\x03\x02\x02\x02\u04A5\u04A6\b\x96\x0F\x02\u04A6\u04A7\b\x96\x0E" + - "\x02\u04A7\u0136\x03\x02\x02\x02\u04A8\u04A9\x07<\x02\x02\u04A9\u0138" + - "\x03\x02\x02\x02\u04AA\u04B0\x05O#\x02\u04AB\u04B0\x05E\x1E\x02\u04AC" + - "\u04B0\x05k1\x02\u04AD\u04B0\x05G\x1F\x02\u04AE\u04B0\x05U&\x02\u04AF" + - "\u04AA\x03\x02\x02\x02\u04AF\u04AB\x03\x02\x02\x02\u04AF\u04AC\x03\x02" + - "\x02\x02\u04AF\u04AD\x03\x02\x02\x02\u04AF\u04AE\x03\x02\x02\x02\u04B0" + - "\u04B1\x03\x02\x02\x02\u04B1\u04AF\x03\x02\x02\x02\u04B1\u04B2\x03\x02" + - "\x02\x02\u04B2\u013A\x03\x02\x02\x02\u04B3\u04B4\x053\x15\x02\u04B4\u04B5" + - "\x03\x02\x02\x02\u04B5\u04B6\b\x99\n\x02\u04B6\u013C\x03\x02\x02\x02\u04B7" + - "\u04B8\x055\x16\x02\u04B8\u04B9\x03\x02\x02\x02\u04B9\u04BA\b\x9A\n\x02" + - "\u04BA\u013E\x03\x02\x02\x02\u04BB\u04BC\x057\x17\x02\u04BC\u04BD\x03" + - "\x02\x02\x02\u04BD\u04BE\b\x9B\n\x02\u04BE\u0140\x03\x02\x02\x02\u04BF" + - "\u04C0\t\x0F\x02\x02\u04C0\u0142\x03\x02\x02\x02\u04C1\u04C2\t\x10\x02" + - "\x02\u04C2\u0144\x03\x02\x02\x02\u04C3\u04C4\t\x11\x02\x02\u04C4\u0146" + - "\x03\x02\x02\x02\u04C5\u04C6\t\x12\x02\x02\u04C6\u0148\x03\x02\x02\x02" + - "\u04C7\u04C8\t\t\x02\x02\u04C8\u014A\x03\x02\x02\x02\u04C9\u04CA\t\x13" + - "\x02\x02\u04CA\u014C\x03\x02\x02\x02\u04CB\u04CC\t\x14\x02\x02\u04CC\u014E" + - "\x03\x02\x02\x02\u04CD\u04CE\t\x15\x02\x02\u04CE\u0150\x03\x02\x02\x02" + - "\u04CF\u04D0\t\x16\x02\x02\u04D0\u0152\x03\x02\x02\x02\u04D1\u04D2\t\x17" + - "\x02\x02\u04D2\u0154\x03\x02\x02\x02\u04D3\u04D4\t\x18\x02\x02\u04D4\u0156" + - "\x03\x02\x02\x02\u04D5\u04D6\t\x19\x02\x02\u04D6\u0158\x03\x02\x02\x02" + - "\u04D7\u04D8\t\x1A\x02\x02\u04D8\u015A\x03\x02\x02\x02\u04D9\u04DA\t\x1B" + - "\x02\x02\u04DA\u015C\x03\x02\x02\x02\u04DB\u04DC\t\x1C\x02\x02\u04DC\u015E" + - "\x03\x02\x02\x02\u04DD\u04DE\t\x1D\x02\x02\u04DE\u0160\x03\x02\x02\x02" + - "\u04DF\u04E0\t\x1E\x02\x02\u04E0\u0162\x03\x02\x02\x02\u04E1\u04E2\t\x1F" + - "\x02\x02\u04E2\u0164\x03\x02\x02\x02\u04E3\u04E4\t \x02\x02\u04E4\u0166" + - "\x03\x02\x02\x02\u04E5\u04E6\t!\x02\x02\u04E6\u0168\x03\x02\x02\x02\u04E7" + - "\u04E8\t\"\x02\x02\u04E8\u016A\x03\x02\x02\x02\u04E9\u04EA\t#\x02\x02" + - "\u04EA\u016C\x03\x02\x02\x02\u04EB\u04EC\t$\x02\x02\u04EC\u016E\x03\x02" + - "\x02\x02\u04ED\u04EE\t%\x02\x02\u04EE\u0170\x03\x02\x02\x02\u04EF\u04F0" + - "\t&\x02\x02\u04F0\u0172\x03\x02\x02\x02\u04F1\u04F2\t\'\x02\x02\u04F2" + - "\u0174\x03\x02\x02\x028\x02\x03\x04\x05\x06\x07\b\t\n\v\f\u0211\u021B" + - "\u021F\u0222\u022B\u022D\u0238\u0261\u0266\u026F\u0276\u027B\u027D\u0288" + - "\u0290\u0293\u0295\u029A\u029F\u02A5\u02AC\u02B1\u02B7\u02BA\u02C2\u02C6" + - "\u0348\u034D\u0352\u0354\u035A\u038B\u0390\u03B3\u03B7\u03BC\u03C1\u03C6" + - "\u03C8\u0420\u0425\u04AF\u04B1\x1A\x07\x04\x02\x07\x06\x02\x07\b\x02\x07" + - "\x03\x02\x07\x05\x02\x07\n\x02\x07\x07\x02\x07\v\x02\x02\x03\x02\tB\x02" + - "\x07\x02\x02\t\x1C\x02\x06\x02\x02\tC\x02\t$\x02\t#\x02\tE\x02\t&\x02" + - "\tN\x02\x07\f\x02\x07\t\x02\tX\x02\tW\x02\tD\x02"; + "\x14\x02\u044D\u0110\x03\x02\x02\x02\u044E\u044F\x05\xA7O\x02\u044F\u0450" + + "\x03\x02\x02\x02\u0450\u0451\b\x84\x12\x02\u0451\u0112\x03\x02\x02\x02" + + "\u0452\u0453\x051\x14\x02\u0453\u0454\x03\x02\x02\x02\u0454\u0455\b\x85" + + "\n\x02\u0455\u0114\x03\x02\x02\x02\u0456\u0457\x053\x15\x02\u0457\u0458" + + "\x03\x02\x02\x02\u0458\u0459\b\x86\n\x02\u0459\u0116\x03\x02\x02\x02\u045A" + + "\u045B\x055\x16\x02\u045B\u045C\x03\x02\x02\x02\u045C\u045D\b\x87\n\x02" + + "\u045D\u0118\x03\x02\x02\x02\u045E\u045F\x05A\x1C\x02\u045F\u0460\x03" + + "\x02\x02\x02\u0460\u0461\b\x88\r\x02\u0461\u0462\b\x88\x0E\x02\u0462\u011A" + + "\x03\x02\x02\x02\u0463\u0464\x05i0\x02\u0464\u0465\x03\x02\x02\x02\u0465" + + "\u0466\b\x89\x13\x02\u0466\u011C\x03\x02\x02\x02\u0467\u0468\x05\xA7O" + + "\x02\u0468\u0469\x03\x02\x02\x02\u0469\u046A\b\x8A\x12\x02\u046A\u011E" + + "\x03\x02\x02\x02\u046B\u046C\x05\xA5N\x02\u046C\u046D\x03\x02\x02\x02" + + "\u046D\u046E\b\x8B\x19\x02\u046E\u0120\x03\x02\x02\x02\u046F\u0470\x05" + + "1\x14\x02\u0470\u0471\x03\x02\x02\x02\u0471\u0472\b\x8C\n\x02\u0472\u0122" + + "\x03\x02\x02\x02\u0473\u0474\x053\x15\x02\u0474\u0475\x03\x02\x02\x02" + + "\u0475\u0476\b\x8D\n\x02\u0476\u0124\x03\x02\x02\x02\u0477\u0478\x055" + + "\x16\x02\u0478\u0479\x03\x02\x02\x02\u0479\u047A\b\x8E\n\x02\u047A\u0126" + + "\x03\x02\x02\x02\u047B\u047C\x05A\x1C\x02\u047C\u047D\x03\x02\x02\x02" + + "\u047D\u047E\b\x8F\r\x02\u047E\u047F\b\x8F\x0E\x02\u047F\u0128\x03\x02" + + "\x02\x02\u0480\u0481\x05\u014F\xA3\x02\u0481\u0482\x05\u0159\xA8\x02\u0482" + + "\u0483\x05\u0149\xA0\x02\u0483\u0484\x05\u015B\xA9\x02\u0484\u012A\x03" + + "\x02\x02\x02\u0485\u0486\x05\u0149\xA0\x02\u0486\u0487\x05\u0167\xAF\x02" + + "\u0487\u0488\x05\u0159\xA8\x02\u0488\u0489\x05\u0143\x9D\x02\u0489\u048A" + + "\x05\u0165\xAE\x02\u048A\u048B\x05\u014F\xA3\x02\u048B\u048C\x05\u015B" + + "\xA9\x02\u048C\u048D\x05\u0159\xA8\x02\u048D\u048E\x05\u0163\xAD\x02\u048E" + + "\u012C\x03\x02\x02\x02\u048F\u0490\x051\x14\x02\u0490\u0491\x03\x02\x02" + + "\x02\u0491\u0492\b\x92\n\x02\u0492\u012E\x03\x02\x02\x02\u0493\u0494\x05" + + "3\x15\x02\u0494\u0495\x03\x02\x02\x02\u0495\u0496\b\x93\n\x02\u0496\u0130" + + "\x03\x02\x02\x02\u0497\u0498\x055\x16\x02\u0498\u0499\x03\x02\x02\x02" + + "\u0499\u049A\b\x94\n\x02\u049A\u0132\x03\x02\x02\x02\u049B\u049C\x05\xA3" + + "M\x02\u049C\u049D\x03\x02\x02\x02\u049D\u049E\b\x95\x0F\x02\u049E\u049F" + + "\b\x95\x0E\x02\u049F\u0134\x03\x02\x02\x02\u04A0\u04A1\x07<\x02\x02\u04A1" + + "\u0136\x03\x02\x02\x02\u04A2\u04A8\x05M\"\x02\u04A3\u04A8\x05C\x1D\x02" + + "\u04A4\u04A8\x05i0\x02\u04A5\u04A8\x05E\x1E\x02\u04A6\u04A8\x05S%\x02" + + "\u04A7\u04A2\x03\x02\x02\x02\u04A7\u04A3\x03\x02\x02\x02\u04A7\u04A4\x03" + + "\x02\x02\x02\u04A7\u04A5\x03\x02\x02\x02\u04A7\u04A6\x03\x02\x02\x02\u04A8" + + "\u04A9\x03\x02\x02\x02\u04A9\u04A7\x03\x02\x02\x02\u04A9\u04AA\x03\x02" + + "\x02\x02\u04AA\u0138\x03\x02\x02\x02\u04AB\u04AC\x051\x14\x02\u04AC\u04AD" + + "\x03\x02\x02\x02\u04AD\u04AE\b\x98\n\x02\u04AE\u013A\x03\x02\x02\x02\u04AF" + + "\u04B0\x053\x15\x02\u04B0\u04B1\x03\x02\x02\x02\u04B1\u04B2\b\x99\n\x02" + + "\u04B2\u013C\x03\x02\x02\x02\u04B3\u04B4\x055\x16\x02\u04B4\u04B5\x03" + + "\x02\x02\x02\u04B5\u04B6\b\x9A\n\x02\u04B6\u013E\x03\x02\x02\x02\u04B7" + + "\u04B8\t\x0F\x02\x02\u04B8\u0140\x03\x02\x02\x02\u04B9\u04BA\t\x10\x02" + + "\x02\u04BA\u0142\x03\x02\x02\x02\u04BB\u04BC\t\x11\x02\x02\u04BC\u0144" + + "\x03\x02\x02\x02\u04BD\u04BE\t\x12\x02\x02\u04BE\u0146\x03\x02\x02\x02" + + "\u04BF\u04C0\t\t\x02\x02\u04C0\u0148\x03\x02\x02\x02\u04C1\u04C2\t\x13" + + "\x02\x02\u04C2\u014A\x03\x02\x02\x02\u04C3\u04C4\t\x14\x02\x02\u04C4\u014C" + + "\x03\x02\x02\x02\u04C5\u04C6\t\x15\x02\x02\u04C6\u014E\x03\x02\x02\x02" + + "\u04C7\u04C8\t\x16\x02\x02\u04C8\u0150\x03\x02\x02\x02\u04C9\u04CA\t\x17" + + "\x02\x02\u04CA\u0152\x03\x02\x02\x02\u04CB\u04CC\t\x18\x02\x02\u04CC\u0154" + + "\x03\x02\x02\x02\u04CD\u04CE\t\x19\x02\x02\u04CE\u0156\x03\x02\x02\x02" + + "\u04CF\u04D0\t\x1A\x02\x02\u04D0\u0158\x03\x02\x02\x02\u04D1\u04D2\t\x1B" + + "\x02\x02\u04D2\u015A\x03\x02\x02\x02\u04D3\u04D4\t\x1C\x02\x02\u04D4\u015C" + + "\x03\x02\x02\x02\u04D5\u04D6\t\x1D\x02\x02\u04D6\u015E\x03\x02\x02\x02" + + "\u04D7\u04D8\t\x1E\x02\x02\u04D8\u0160\x03\x02\x02\x02\u04D9\u04DA\t\x1F" + + "\x02\x02\u04DA\u0162\x03\x02\x02\x02\u04DB\u04DC\t \x02\x02\u04DC\u0164" + + "\x03\x02\x02\x02\u04DD\u04DE\t!\x02\x02\u04DE\u0166\x03\x02\x02\x02\u04DF" + + "\u04E0\t\"\x02\x02\u04E0\u0168\x03\x02\x02\x02\u04E1\u04E2\t#\x02\x02" + + "\u04E2\u016A\x03\x02\x02\x02\u04E3\u04E4\t$\x02\x02\u04E4\u016C\x03\x02" + + "\x02\x02\u04E5\u04E6\t%\x02\x02\u04E6\u016E\x03\x02\x02\x02\u04E7\u04E8" + + "\t&\x02\x02\u04E8\u0170\x03\x02\x02\x02\u04E9\u04EA\t\'\x02\x02\u04EA" + + "\u0172\x03\x02\x02\x029\x02\x03\x04\x05\x06\x07\b\t\n\v\f\u0205\u020F" + + "\u0213\u0216\u021F\u0221\u022C\u0255\u025A\u0263\u026A\u026F\u0271\u027C" + + "\u0284\u0287\u0289\u028E\u0293\u0299\u02A0\u02A5\u02AB\u02AE\u02B6\u02BA" + + "\u033C\u0341\u0346\u0348\u034E\u037F\u0384\u03A7\u03AB\u03B0\u03B5\u03BA" + + "\u03BC\u0415\u0419\u041E\u04A7\u04A9\x1A\x07\x04\x02\x07\x06\x02\x07\b" + + "\x02\x07\x03\x02\x07\x05\x02\x07\n\x02\x07\x07\x02\x07\v\x02\x02\x03\x02" + + "\tA\x02\x07\x02\x02\t\x1B\x02\x06\x02\x02\tB\x02\t#\x02\t\"\x02\tD\x02" + + "\t%\x02\tM\x02\x07\f\x02\x07\t\x02\tW\x02\tV\x02\tC\x02"; public static readonly _serializedATN: string = Utils.join( [ esql_lexer._serializedATNSegment0, diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 b/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 index 57e7097eb03f8..06b955f84cd90 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 @@ -102,7 +102,16 @@ fromCommand ; metadata - : OPENING_BRACKET METADATA fromIdentifier (COMMA fromIdentifier)* CLOSING_BRACKET + : metadataOption + | deprecated_metadata + ; + +metadataOption + : METADATA fromIdentifier (COMMA fromIdentifier)* + ; + +deprecated_metadata + : OPENING_BRACKET metadataOption CLOSING_BRACKET ; @@ -168,7 +177,6 @@ orderExpression keepCommand : KEEP qualifiedNamePattern (COMMA qualifiedNamePattern)* - | PROJECT qualifiedNamePattern (COMMA qualifiedNamePattern)* ; dropCommand @@ -242,13 +250,9 @@ showCommand ; enrichCommand - : ENRICH setting* policyName=ENRICH_POLICY_NAME (ON matchField=qualifiedNamePattern)? (WITH enrichWithClause (COMMA enrichWithClause)*)? + : ENRICH policyName=ENRICH_POLICY_NAME (ON matchField=qualifiedNamePattern)? (WITH enrichWithClause (COMMA enrichWithClause)*)? ; enrichWithClause : (newName=qualifiedNamePattern ASSIGN)? enrichField=qualifiedNamePattern ; - -setting - : OPENING_BRACKET name=SETTING COLON value=SETTING CLOSING_BRACKET - ; \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.interp b/packages/kbn-monaco/src/esql/antlr/esql_parser.interp index ed3cd7a8d9227..3f76dcbcff6a0 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.interp +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.interp @@ -24,7 +24,6 @@ null null null null -null '|' null null @@ -119,7 +118,6 @@ INLINESTATS KEEP LIMIT MV_EXPAND -PROJECT RENAME ROW SHOW @@ -231,6 +229,8 @@ fields field fromCommand metadata +metadataOption +deprecated_metadata evalCommand statsCommand inlinestatsCommand @@ -263,8 +263,7 @@ subqueryExpression showCommand enrichCommand enrichWithClause -setting atn: -[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 3, 107, 525, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 110, 10, 3, 12, 3, 14, 3, 113, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 119, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 134, 10, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 146, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 153, 10, 7, 12, 7, 14, 7, 156, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 163, 10, 7, 3, 7, 3, 7, 5, 7, 167, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 175, 10, 7, 12, 7, 14, 7, 178, 11, 7, 3, 8, 3, 8, 5, 8, 182, 10, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 189, 10, 8, 3, 8, 3, 8, 3, 8, 5, 8, 194, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 201, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 207, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 215, 10, 10, 12, 10, 14, 10, 218, 11, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 227, 10, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 235, 10, 12, 12, 12, 14, 12, 238, 11, 12, 5, 12, 240, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 7, 14, 250, 10, 14, 12, 14, 14, 14, 253, 11, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 260, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 266, 10, 16, 12, 16, 14, 16, 269, 11, 16, 3, 16, 5, 16, 272, 10, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 7, 17, 279, 10, 17, 12, 17, 14, 17, 282, 11, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 291, 10, 19, 3, 19, 3, 19, 5, 19, 295, 10, 19, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 301, 10, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 7, 22, 308, 10, 22, 12, 22, 14, 22, 311, 11, 22, 3, 23, 3, 23, 3, 23, 7, 23, 316, 10, 23, 12, 23, 14, 23, 319, 11, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, 338, 10, 26, 12, 26, 14, 26, 341, 11, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, 349, 10, 26, 12, 26, 14, 26, 352, 11, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, 360, 10, 26, 12, 26, 14, 26, 363, 11, 26, 3, 26, 3, 26, 5, 26, 367, 10, 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 376, 10, 28, 12, 28, 14, 28, 379, 11, 28, 3, 29, 3, 29, 5, 29, 383, 10, 29, 3, 29, 3, 29, 5, 29, 387, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 393, 10, 30, 12, 30, 14, 30, 396, 11, 30, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 402, 10, 30, 12, 30, 14, 30, 405, 11, 30, 5, 30, 407, 10, 30, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 413, 10, 31, 12, 31, 14, 31, 416, 11, 31, 3, 32, 3, 32, 3, 32, 3, 32, 7, 32, 422, 10, 32, 12, 32, 14, 32, 425, 11, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 5, 34, 435, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 7, 37, 447, 10, 37, 12, 37, 14, 37, 450, 11, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 5, 40, 460, 10, 40, 3, 41, 5, 41, 463, 10, 41, 3, 41, 3, 41, 3, 42, 5, 42, 468, 10, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 5, 47, 487, 10, 47, 3, 48, 3, 48, 7, 48, 491, 10, 48, 12, 48, 14, 48, 494, 11, 48, 3, 48, 3, 48, 3, 48, 5, 48, 499, 10, 48, 3, 48, 3, 48, 3, 48, 3, 48, 7, 48, 505, 10, 48, 12, 48, 14, 48, 508, 11, 48, 5, 48, 510, 10, 48, 3, 49, 3, 49, 3, 49, 5, 49, 515, 10, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 2, 2, 5, 4, 12, 18, 51, 2, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 2, 60, 2, 62, 2, 64, 2, 66, 2, 68, 2, 70, 2, 72, 2, 74, 2, 76, 2, 78, 2, 80, 2, 82, 2, 84, 2, 86, 2, 88, 2, 90, 2, 92, 2, 94, 2, 96, 2, 98, 2, 2, 11, 3, 2, 61, 62, 3, 2, 63, 65, 4, 2, 69, 69, 74, 74, 3, 2, 68, 69, 4, 2, 69, 69, 78, 78, 4, 2, 34, 34, 37, 37, 3, 2, 40, 41, 4, 2, 39, 39, 53, 53, 3, 2, 54, 60, 2, 554, 2, 100, 3, 2, 2, 2, 4, 103, 3, 2, 2, 2, 6, 118, 3, 2, 2, 2, 8, 133, 3, 2, 2, 2, 10, 135, 3, 2, 2, 2, 12, 166, 3, 2, 2, 2, 14, 193, 3, 2, 2, 2, 16, 200, 3, 2, 2, 2, 18, 206, 3, 2, 2, 2, 20, 226, 3, 2, 2, 2, 22, 228, 3, 2, 2, 2, 24, 243, 3, 2, 2, 2, 26, 246, 3, 2, 2, 2, 28, 259, 3, 2, 2, 2, 30, 261, 3, 2, 2, 2, 32, 273, 3, 2, 2, 2, 34, 285, 3, 2, 2, 2, 36, 288, 3, 2, 2, 2, 38, 296, 3, 2, 2, 2, 40, 302, 3, 2, 2, 2, 42, 304, 3, 2, 2, 2, 44, 312, 3, 2, 2, 2, 46, 320, 3, 2, 2, 2, 48, 322, 3, 2, 2, 2, 50, 366, 3, 2, 2, 2, 52, 368, 3, 2, 2, 2, 54, 371, 3, 2, 2, 2, 56, 380, 3, 2, 2, 2, 58, 406, 3, 2, 2, 2, 60, 408, 3, 2, 2, 2, 62, 417, 3, 2, 2, 2, 64, 426, 3, 2, 2, 2, 66, 430, 3, 2, 2, 2, 68, 436, 3, 2, 2, 2, 70, 440, 3, 2, 2, 2, 72, 443, 3, 2, 2, 2, 74, 451, 3, 2, 2, 2, 76, 455, 3, 2, 2, 2, 78, 459, 3, 2, 2, 2, 80, 462, 3, 2, 2, 2, 82, 467, 3, 2, 2, 2, 84, 471, 3, 2, 2, 2, 86, 473, 3, 2, 2, 2, 88, 475, 3, 2, 2, 2, 90, 478, 3, 2, 2, 2, 92, 486, 3, 2, 2, 2, 94, 488, 3, 2, 2, 2, 96, 514, 3, 2, 2, 2, 98, 518, 3, 2, 2, 2, 100, 101, 5, 4, 3, 2, 101, 102, 7, 2, 2, 3, 102, 3, 3, 2, 2, 2, 103, 104, 8, 3, 1, 2, 104, 105, 5, 6, 4, 2, 105, 111, 3, 2, 2, 2, 106, 107, 12, 3, 2, 2, 107, 108, 7, 28, 2, 2, 108, 110, 5, 8, 5, 2, 109, 106, 3, 2, 2, 2, 110, 113, 3, 2, 2, 2, 111, 109, 3, 2, 2, 2, 111, 112, 3, 2, 2, 2, 112, 5, 3, 2, 2, 2, 113, 111, 3, 2, 2, 2, 114, 119, 5, 88, 45, 2, 115, 119, 5, 30, 16, 2, 116, 119, 5, 24, 13, 2, 117, 119, 5, 92, 47, 2, 118, 114, 3, 2, 2, 2, 118, 115, 3, 2, 2, 2, 118, 116, 3, 2, 2, 2, 118, 117, 3, 2, 2, 2, 119, 7, 3, 2, 2, 2, 120, 134, 5, 34, 18, 2, 121, 134, 5, 38, 20, 2, 122, 134, 5, 52, 27, 2, 123, 134, 5, 58, 30, 2, 124, 134, 5, 54, 28, 2, 125, 134, 5, 36, 19, 2, 126, 134, 5, 10, 6, 2, 127, 134, 5, 60, 31, 2, 128, 134, 5, 62, 32, 2, 129, 134, 5, 66, 34, 2, 130, 134, 5, 68, 35, 2, 131, 134, 5, 94, 48, 2, 132, 134, 5, 70, 36, 2, 133, 120, 3, 2, 2, 2, 133, 121, 3, 2, 2, 2, 133, 122, 3, 2, 2, 2, 133, 123, 3, 2, 2, 2, 133, 124, 3, 2, 2, 2, 133, 125, 3, 2, 2, 2, 133, 126, 3, 2, 2, 2, 133, 127, 3, 2, 2, 2, 133, 128, 3, 2, 2, 2, 133, 129, 3, 2, 2, 2, 133, 130, 3, 2, 2, 2, 133, 131, 3, 2, 2, 2, 133, 132, 3, 2, 2, 2, 134, 9, 3, 2, 2, 2, 135, 136, 7, 20, 2, 2, 136, 137, 5, 12, 7, 2, 137, 11, 3, 2, 2, 2, 138, 139, 8, 7, 1, 2, 139, 140, 7, 46, 2, 2, 140, 167, 5, 12, 7, 9, 141, 167, 5, 16, 9, 2, 142, 167, 5, 14, 8, 2, 143, 145, 5, 16, 9, 2, 144, 146, 7, 46, 2, 2, 145, 144, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, 147, 3, 2, 2, 2, 147, 148, 7, 43, 2, 2, 148, 149, 7, 42, 2, 2, 149, 154, 5, 16, 9, 2, 150, 151, 7, 36, 2, 2, 151, 153, 5, 16, 9, 2, 152, 150, 3, 2, 2, 2, 153, 156, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 154, 155, 3, 2, 2, 2, 155, 157, 3, 2, 2, 2, 156, 154, 3, 2, 2, 2, 157, 158, 7, 52, 2, 2, 158, 167, 3, 2, 2, 2, 159, 160, 5, 16, 9, 2, 160, 162, 7, 44, 2, 2, 161, 163, 7, 46, 2, 2, 162, 161, 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 164, 3, 2, 2, 2, 164, 165, 7, 47, 2, 2, 165, 167, 3, 2, 2, 2, 166, 138, 3, 2, 2, 2, 166, 141, 3, 2, 2, 2, 166, 142, 3, 2, 2, 2, 166, 143, 3, 2, 2, 2, 166, 159, 3, 2, 2, 2, 167, 176, 3, 2, 2, 2, 168, 169, 12, 6, 2, 2, 169, 170, 7, 33, 2, 2, 170, 175, 5, 12, 7, 7, 171, 172, 12, 5, 2, 2, 172, 173, 7, 49, 2, 2, 173, 175, 5, 12, 7, 6, 174, 168, 3, 2, 2, 2, 174, 171, 3, 2, 2, 2, 175, 178, 3, 2, 2, 2, 176, 174, 3, 2, 2, 2, 176, 177, 3, 2, 2, 2, 177, 13, 3, 2, 2, 2, 178, 176, 3, 2, 2, 2, 179, 181, 5, 16, 9, 2, 180, 182, 7, 46, 2, 2, 181, 180, 3, 2, 2, 2, 181, 182, 3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 184, 7, 45, 2, 2, 184, 185, 5, 84, 43, 2, 185, 194, 3, 2, 2, 2, 186, 188, 5, 16, 9, 2, 187, 189, 7, 46, 2, 2, 188, 187, 3, 2, 2, 2, 188, 189, 3, 2, 2, 2, 189, 190, 3, 2, 2, 2, 190, 191, 7, 51, 2, 2, 191, 192, 5, 84, 43, 2, 192, 194, 3, 2, 2, 2, 193, 179, 3, 2, 2, 2, 193, 186, 3, 2, 2, 2, 194, 15, 3, 2, 2, 2, 195, 201, 5, 18, 10, 2, 196, 197, 5, 18, 10, 2, 197, 198, 5, 86, 44, 2, 198, 199, 5, 18, 10, 2, 199, 201, 3, 2, 2, 2, 200, 195, 3, 2, 2, 2, 200, 196, 3, 2, 2, 2, 201, 17, 3, 2, 2, 2, 202, 203, 8, 10, 1, 2, 203, 207, 5, 20, 11, 2, 204, 205, 9, 2, 2, 2, 205, 207, 5, 18, 10, 5, 206, 202, 3, 2, 2, 2, 206, 204, 3, 2, 2, 2, 207, 216, 3, 2, 2, 2, 208, 209, 12, 4, 2, 2, 209, 210, 9, 3, 2, 2, 210, 215, 5, 18, 10, 5, 211, 212, 12, 3, 2, 2, 212, 213, 9, 2, 2, 2, 213, 215, 5, 18, 10, 4, 214, 208, 3, 2, 2, 2, 214, 211, 3, 2, 2, 2, 215, 218, 3, 2, 2, 2, 216, 214, 3, 2, 2, 2, 216, 217, 3, 2, 2, 2, 217, 19, 3, 2, 2, 2, 218, 216, 3, 2, 2, 2, 219, 227, 5, 50, 26, 2, 220, 227, 5, 42, 22, 2, 221, 227, 5, 22, 12, 2, 222, 223, 7, 42, 2, 2, 223, 224, 5, 12, 7, 2, 224, 225, 7, 52, 2, 2, 225, 227, 3, 2, 2, 2, 226, 219, 3, 2, 2, 2, 226, 220, 3, 2, 2, 2, 226, 221, 3, 2, 2, 2, 226, 222, 3, 2, 2, 2, 227, 21, 3, 2, 2, 2, 228, 229, 5, 46, 24, 2, 229, 239, 7, 42, 2, 2, 230, 240, 7, 63, 2, 2, 231, 236, 5, 12, 7, 2, 232, 233, 7, 36, 2, 2, 233, 235, 5, 12, 7, 2, 234, 232, 3, 2, 2, 2, 235, 238, 3, 2, 2, 2, 236, 234, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 240, 3, 2, 2, 2, 238, 236, 3, 2, 2, 2, 239, 230, 3, 2, 2, 2, 239, 231, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 241, 3, 2, 2, 2, 241, 242, 7, 52, 2, 2, 242, 23, 3, 2, 2, 2, 243, 244, 7, 16, 2, 2, 244, 245, 5, 26, 14, 2, 245, 25, 3, 2, 2, 2, 246, 251, 5, 28, 15, 2, 247, 248, 7, 36, 2, 2, 248, 250, 5, 28, 15, 2, 249, 247, 3, 2, 2, 2, 250, 253, 3, 2, 2, 2, 251, 249, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 27, 3, 2, 2, 2, 253, 251, 3, 2, 2, 2, 254, 260, 5, 12, 7, 2, 255, 256, 5, 42, 22, 2, 256, 257, 7, 35, 2, 2, 257, 258, 5, 12, 7, 2, 258, 260, 3, 2, 2, 2, 259, 254, 3, 2, 2, 2, 259, 255, 3, 2, 2, 2, 260, 29, 3, 2, 2, 2, 261, 262, 7, 8, 2, 2, 262, 267, 5, 40, 21, 2, 263, 264, 7, 36, 2, 2, 264, 266, 5, 40, 21, 2, 265, 263, 3, 2, 2, 2, 266, 269, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 267, 268, 3, 2, 2, 2, 268, 271, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 270, 272, 5, 32, 17, 2, 271, 270, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 31, 3, 2, 2, 2, 273, 274, 7, 66, 2, 2, 274, 275, 7, 73, 2, 2, 275, 280, 5, 40, 21, 2, 276, 277, 7, 36, 2, 2, 277, 279, 5, 40, 21, 2, 278, 276, 3, 2, 2, 2, 279, 282, 3, 2, 2, 2, 280, 278, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 283, 3, 2, 2, 2, 282, 280, 3, 2, 2, 2, 283, 284, 7, 67, 2, 2, 284, 33, 3, 2, 2, 2, 285, 286, 7, 6, 2, 2, 286, 287, 5, 26, 14, 2, 287, 35, 3, 2, 2, 2, 288, 290, 7, 19, 2, 2, 289, 291, 5, 26, 14, 2, 290, 289, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 294, 3, 2, 2, 2, 292, 293, 7, 32, 2, 2, 293, 295, 5, 26, 14, 2, 294, 292, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, 37, 3, 2, 2, 2, 296, 297, 7, 10, 2, 2, 297, 300, 5, 26, 14, 2, 298, 299, 7, 32, 2, 2, 299, 301, 5, 26, 14, 2, 300, 298, 3, 2, 2, 2, 300, 301, 3, 2, 2, 2, 301, 39, 3, 2, 2, 2, 302, 303, 9, 4, 2, 2, 303, 41, 3, 2, 2, 2, 304, 309, 5, 46, 24, 2, 305, 306, 7, 38, 2, 2, 306, 308, 5, 46, 24, 2, 307, 305, 3, 2, 2, 2, 308, 311, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 309, 310, 3, 2, 2, 2, 310, 43, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 312, 317, 5, 48, 25, 2, 313, 314, 7, 38, 2, 2, 314, 316, 5, 48, 25, 2, 315, 313, 3, 2, 2, 2, 316, 319, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 45, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 320, 321, 9, 5, 2, 2, 321, 47, 3, 2, 2, 2, 322, 323, 9, 6, 2, 2, 323, 49, 3, 2, 2, 2, 324, 367, 7, 47, 2, 2, 325, 326, 5, 82, 42, 2, 326, 327, 7, 68, 2, 2, 327, 367, 3, 2, 2, 2, 328, 367, 5, 80, 41, 2, 329, 367, 5, 82, 42, 2, 330, 367, 5, 76, 39, 2, 331, 367, 7, 50, 2, 2, 332, 367, 5, 84, 43, 2, 333, 334, 7, 66, 2, 2, 334, 339, 5, 78, 40, 2, 335, 336, 7, 36, 2, 2, 336, 338, 5, 78, 40, 2, 337, 335, 3, 2, 2, 2, 338, 341, 3, 2, 2, 2, 339, 337, 3, 2, 2, 2, 339, 340, 3, 2, 2, 2, 340, 342, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 342, 343, 7, 67, 2, 2, 343, 367, 3, 2, 2, 2, 344, 345, 7, 66, 2, 2, 345, 350, 5, 76, 39, 2, 346, 347, 7, 36, 2, 2, 347, 349, 5, 76, 39, 2, 348, 346, 3, 2, 2, 2, 349, 352, 3, 2, 2, 2, 350, 348, 3, 2, 2, 2, 350, 351, 3, 2, 2, 2, 351, 353, 3, 2, 2, 2, 352, 350, 3, 2, 2, 2, 353, 354, 7, 67, 2, 2, 354, 367, 3, 2, 2, 2, 355, 356, 7, 66, 2, 2, 356, 361, 5, 84, 43, 2, 357, 358, 7, 36, 2, 2, 358, 360, 5, 84, 43, 2, 359, 357, 3, 2, 2, 2, 360, 363, 3, 2, 2, 2, 361, 359, 3, 2, 2, 2, 361, 362, 3, 2, 2, 2, 362, 364, 3, 2, 2, 2, 363, 361, 3, 2, 2, 2, 364, 365, 7, 67, 2, 2, 365, 367, 3, 2, 2, 2, 366, 324, 3, 2, 2, 2, 366, 325, 3, 2, 2, 2, 366, 328, 3, 2, 2, 2, 366, 329, 3, 2, 2, 2, 366, 330, 3, 2, 2, 2, 366, 331, 3, 2, 2, 2, 366, 332, 3, 2, 2, 2, 366, 333, 3, 2, 2, 2, 366, 344, 3, 2, 2, 2, 366, 355, 3, 2, 2, 2, 367, 51, 3, 2, 2, 2, 368, 369, 7, 12, 2, 2, 369, 370, 7, 30, 2, 2, 370, 53, 3, 2, 2, 2, 371, 372, 7, 18, 2, 2, 372, 377, 5, 56, 29, 2, 373, 374, 7, 36, 2, 2, 374, 376, 5, 56, 29, 2, 375, 373, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 55, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 382, 5, 12, 7, 2, 381, 383, 9, 7, 2, 2, 382, 381, 3, 2, 2, 2, 382, 383, 3, 2, 2, 2, 383, 386, 3, 2, 2, 2, 384, 385, 7, 48, 2, 2, 385, 387, 9, 8, 2, 2, 386, 384, 3, 2, 2, 2, 386, 387, 3, 2, 2, 2, 387, 57, 3, 2, 2, 2, 388, 389, 7, 11, 2, 2, 389, 394, 5, 44, 23, 2, 390, 391, 7, 36, 2, 2, 391, 393, 5, 44, 23, 2, 392, 390, 3, 2, 2, 2, 393, 396, 3, 2, 2, 2, 394, 392, 3, 2, 2, 2, 394, 395, 3, 2, 2, 2, 395, 407, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 397, 398, 7, 14, 2, 2, 398, 403, 5, 44, 23, 2, 399, 400, 7, 36, 2, 2, 400, 402, 5, 44, 23, 2, 401, 399, 3, 2, 2, 2, 402, 405, 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 403, 404, 3, 2, 2, 2, 404, 407, 3, 2, 2, 2, 405, 403, 3, 2, 2, 2, 406, 388, 3, 2, 2, 2, 406, 397, 3, 2, 2, 2, 407, 59, 3, 2, 2, 2, 408, 409, 7, 4, 2, 2, 409, 414, 5, 44, 23, 2, 410, 411, 7, 36, 2, 2, 411, 413, 5, 44, 23, 2, 412, 410, 3, 2, 2, 2, 413, 416, 3, 2, 2, 2, 414, 412, 3, 2, 2, 2, 414, 415, 3, 2, 2, 2, 415, 61, 3, 2, 2, 2, 416, 414, 3, 2, 2, 2, 417, 418, 7, 15, 2, 2, 418, 423, 5, 64, 33, 2, 419, 420, 7, 36, 2, 2, 420, 422, 5, 64, 33, 2, 421, 419, 3, 2, 2, 2, 422, 425, 3, 2, 2, 2, 423, 421, 3, 2, 2, 2, 423, 424, 3, 2, 2, 2, 424, 63, 3, 2, 2, 2, 425, 423, 3, 2, 2, 2, 426, 427, 5, 44, 23, 2, 427, 428, 7, 82, 2, 2, 428, 429, 5, 44, 23, 2, 429, 65, 3, 2, 2, 2, 430, 431, 7, 3, 2, 2, 431, 432, 5, 20, 11, 2, 432, 434, 5, 84, 43, 2, 433, 435, 5, 72, 37, 2, 434, 433, 3, 2, 2, 2, 434, 435, 3, 2, 2, 2, 435, 67, 3, 2, 2, 2, 436, 437, 7, 9, 2, 2, 437, 438, 5, 20, 11, 2, 438, 439, 5, 84, 43, 2, 439, 69, 3, 2, 2, 2, 440, 441, 7, 13, 2, 2, 441, 442, 5, 42, 22, 2, 442, 71, 3, 2, 2, 2, 443, 448, 5, 74, 38, 2, 444, 445, 7, 36, 2, 2, 445, 447, 5, 74, 38, 2, 446, 444, 3, 2, 2, 2, 447, 450, 3, 2, 2, 2, 448, 446, 3, 2, 2, 2, 448, 449, 3, 2, 2, 2, 449, 73, 3, 2, 2, 2, 450, 448, 3, 2, 2, 2, 451, 452, 5, 46, 24, 2, 452, 453, 7, 35, 2, 2, 453, 454, 5, 50, 26, 2, 454, 75, 3, 2, 2, 2, 455, 456, 9, 9, 2, 2, 456, 77, 3, 2, 2, 2, 457, 460, 5, 80, 41, 2, 458, 460, 5, 82, 42, 2, 459, 457, 3, 2, 2, 2, 459, 458, 3, 2, 2, 2, 460, 79, 3, 2, 2, 2, 461, 463, 9, 2, 2, 2, 462, 461, 3, 2, 2, 2, 462, 463, 3, 2, 2, 2, 463, 464, 3, 2, 2, 2, 464, 465, 7, 31, 2, 2, 465, 81, 3, 2, 2, 2, 466, 468, 9, 2, 2, 2, 467, 466, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 469, 3, 2, 2, 2, 469, 470, 7, 30, 2, 2, 470, 83, 3, 2, 2, 2, 471, 472, 7, 29, 2, 2, 472, 85, 3, 2, 2, 2, 473, 474, 9, 10, 2, 2, 474, 87, 3, 2, 2, 2, 475, 476, 7, 7, 2, 2, 476, 477, 5, 90, 46, 2, 477, 89, 3, 2, 2, 2, 478, 479, 7, 66, 2, 2, 479, 480, 5, 4, 3, 2, 480, 481, 7, 67, 2, 2, 481, 91, 3, 2, 2, 2, 482, 483, 7, 17, 2, 2, 483, 487, 7, 98, 2, 2, 484, 485, 7, 17, 2, 2, 485, 487, 7, 99, 2, 2, 486, 482, 3, 2, 2, 2, 486, 484, 3, 2, 2, 2, 487, 93, 3, 2, 2, 2, 488, 492, 7, 5, 2, 2, 489, 491, 5, 98, 50, 2, 490, 489, 3, 2, 2, 2, 491, 494, 3, 2, 2, 2, 492, 490, 3, 2, 2, 2, 492, 493, 3, 2, 2, 2, 493, 495, 3, 2, 2, 2, 494, 492, 3, 2, 2, 2, 495, 498, 7, 88, 2, 2, 496, 497, 7, 86, 2, 2, 497, 499, 5, 44, 23, 2, 498, 496, 3, 2, 2, 2, 498, 499, 3, 2, 2, 2, 499, 509, 3, 2, 2, 2, 500, 501, 7, 87, 2, 2, 501, 506, 5, 96, 49, 2, 502, 503, 7, 36, 2, 2, 503, 505, 5, 96, 49, 2, 504, 502, 3, 2, 2, 2, 505, 508, 3, 2, 2, 2, 506, 504, 3, 2, 2, 2, 506, 507, 3, 2, 2, 2, 507, 510, 3, 2, 2, 2, 508, 506, 3, 2, 2, 2, 509, 500, 3, 2, 2, 2, 509, 510, 3, 2, 2, 2, 510, 95, 3, 2, 2, 2, 511, 512, 5, 44, 23, 2, 512, 513, 7, 35, 2, 2, 513, 515, 3, 2, 2, 2, 514, 511, 3, 2, 2, 2, 514, 515, 3, 2, 2, 2, 515, 516, 3, 2, 2, 2, 516, 517, 5, 44, 23, 2, 517, 97, 3, 2, 2, 2, 518, 519, 7, 66, 2, 2, 519, 520, 7, 104, 2, 2, 520, 521, 7, 103, 2, 2, 521, 522, 7, 104, 2, 2, 522, 523, 7, 67, 2, 2, 523, 99, 3, 2, 2, 2, 54, 111, 118, 133, 145, 154, 162, 166, 174, 176, 181, 188, 193, 200, 206, 214, 216, 226, 236, 239, 251, 259, 267, 271, 280, 290, 294, 300, 309, 317, 339, 350, 361, 366, 377, 382, 386, 394, 403, 406, 414, 423, 434, 448, 459, 462, 467, 486, 492, 498, 506, 509, 514] \ No newline at end of file +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 3, 106, 509, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 112, 10, 3, 12, 3, 14, 3, 115, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 121, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 136, 10, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 148, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 155, 10, 7, 12, 7, 14, 7, 158, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 165, 10, 7, 3, 7, 3, 7, 5, 7, 169, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 177, 10, 7, 12, 7, 14, 7, 180, 11, 7, 3, 8, 3, 8, 5, 8, 184, 10, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 191, 10, 8, 3, 8, 3, 8, 3, 8, 5, 8, 196, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 203, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 209, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 217, 10, 10, 12, 10, 14, 10, 220, 11, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 229, 10, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 237, 10, 12, 12, 12, 14, 12, 240, 11, 12, 5, 12, 242, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 7, 14, 252, 10, 14, 12, 14, 14, 14, 255, 11, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 262, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 268, 10, 16, 12, 16, 14, 16, 271, 11, 16, 3, 16, 5, 16, 274, 10, 16, 3, 17, 3, 17, 5, 17, 278, 10, 17, 3, 18, 3, 18, 3, 18, 3, 18, 7, 18, 284, 10, 18, 12, 18, 14, 18, 287, 11, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 5, 21, 298, 10, 21, 3, 21, 3, 21, 5, 21, 302, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 308, 10, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 7, 24, 315, 10, 24, 12, 24, 14, 24, 318, 11, 24, 3, 25, 3, 25, 3, 25, 7, 25, 323, 10, 25, 12, 25, 14, 25, 326, 11, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 345, 10, 28, 12, 28, 14, 28, 348, 11, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 356, 10, 28, 12, 28, 14, 28, 359, 11, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 367, 10, 28, 12, 28, 14, 28, 370, 11, 28, 3, 28, 3, 28, 5, 28, 374, 10, 28, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 383, 10, 30, 12, 30, 14, 30, 386, 11, 30, 3, 31, 3, 31, 5, 31, 390, 10, 31, 3, 31, 3, 31, 5, 31, 394, 10, 31, 3, 32, 3, 32, 3, 32, 3, 32, 7, 32, 400, 10, 32, 12, 32, 14, 32, 403, 11, 32, 3, 33, 3, 33, 3, 33, 3, 33, 7, 33, 409, 10, 33, 12, 33, 14, 33, 412, 11, 33, 3, 34, 3, 34, 3, 34, 3, 34, 7, 34, 418, 10, 34, 12, 34, 14, 34, 421, 11, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 431, 10, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 7, 39, 443, 10, 39, 12, 39, 14, 39, 446, 11, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 5, 42, 456, 10, 42, 3, 43, 5, 43, 459, 10, 43, 3, 43, 3, 43, 3, 44, 5, 44, 464, 10, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 5, 49, 483, 10, 49, 3, 50, 3, 50, 3, 50, 3, 50, 5, 50, 489, 10, 50, 3, 50, 3, 50, 3, 50, 3, 50, 7, 50, 495, 10, 50, 12, 50, 14, 50, 498, 11, 50, 5, 50, 500, 10, 50, 3, 51, 3, 51, 3, 51, 5, 51, 505, 10, 51, 3, 51, 3, 51, 3, 51, 2, 2, 5, 4, 12, 18, 52, 2, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 2, 60, 2, 62, 2, 64, 2, 66, 2, 68, 2, 70, 2, 72, 2, 74, 2, 76, 2, 78, 2, 80, 2, 82, 2, 84, 2, 86, 2, 88, 2, 90, 2, 92, 2, 94, 2, 96, 2, 98, 2, 100, 2, 2, 11, 3, 2, 60, 61, 3, 2, 62, 64, 4, 2, 68, 68, 73, 73, 3, 2, 67, 68, 4, 2, 68, 68, 77, 77, 4, 2, 33, 33, 36, 36, 3, 2, 39, 40, 4, 2, 38, 38, 52, 52, 3, 2, 53, 59, 2, 535, 2, 102, 3, 2, 2, 2, 4, 105, 3, 2, 2, 2, 6, 120, 3, 2, 2, 2, 8, 135, 3, 2, 2, 2, 10, 137, 3, 2, 2, 2, 12, 168, 3, 2, 2, 2, 14, 195, 3, 2, 2, 2, 16, 202, 3, 2, 2, 2, 18, 208, 3, 2, 2, 2, 20, 228, 3, 2, 2, 2, 22, 230, 3, 2, 2, 2, 24, 245, 3, 2, 2, 2, 26, 248, 3, 2, 2, 2, 28, 261, 3, 2, 2, 2, 30, 263, 3, 2, 2, 2, 32, 277, 3, 2, 2, 2, 34, 279, 3, 2, 2, 2, 36, 288, 3, 2, 2, 2, 38, 292, 3, 2, 2, 2, 40, 295, 3, 2, 2, 2, 42, 303, 3, 2, 2, 2, 44, 309, 3, 2, 2, 2, 46, 311, 3, 2, 2, 2, 48, 319, 3, 2, 2, 2, 50, 327, 3, 2, 2, 2, 52, 329, 3, 2, 2, 2, 54, 373, 3, 2, 2, 2, 56, 375, 3, 2, 2, 2, 58, 378, 3, 2, 2, 2, 60, 387, 3, 2, 2, 2, 62, 395, 3, 2, 2, 2, 64, 404, 3, 2, 2, 2, 66, 413, 3, 2, 2, 2, 68, 422, 3, 2, 2, 2, 70, 426, 3, 2, 2, 2, 72, 432, 3, 2, 2, 2, 74, 436, 3, 2, 2, 2, 76, 439, 3, 2, 2, 2, 78, 447, 3, 2, 2, 2, 80, 451, 3, 2, 2, 2, 82, 455, 3, 2, 2, 2, 84, 458, 3, 2, 2, 2, 86, 463, 3, 2, 2, 2, 88, 467, 3, 2, 2, 2, 90, 469, 3, 2, 2, 2, 92, 471, 3, 2, 2, 2, 94, 474, 3, 2, 2, 2, 96, 482, 3, 2, 2, 2, 98, 484, 3, 2, 2, 2, 100, 504, 3, 2, 2, 2, 102, 103, 5, 4, 3, 2, 103, 104, 7, 2, 2, 3, 104, 3, 3, 2, 2, 2, 105, 106, 8, 3, 1, 2, 106, 107, 5, 6, 4, 2, 107, 113, 3, 2, 2, 2, 108, 109, 12, 3, 2, 2, 109, 110, 7, 27, 2, 2, 110, 112, 5, 8, 5, 2, 111, 108, 3, 2, 2, 2, 112, 115, 3, 2, 2, 2, 113, 111, 3, 2, 2, 2, 113, 114, 3, 2, 2, 2, 114, 5, 3, 2, 2, 2, 115, 113, 3, 2, 2, 2, 116, 121, 5, 92, 47, 2, 117, 121, 5, 30, 16, 2, 118, 121, 5, 24, 13, 2, 119, 121, 5, 96, 49, 2, 120, 116, 3, 2, 2, 2, 120, 117, 3, 2, 2, 2, 120, 118, 3, 2, 2, 2, 120, 119, 3, 2, 2, 2, 121, 7, 3, 2, 2, 2, 122, 136, 5, 38, 20, 2, 123, 136, 5, 42, 22, 2, 124, 136, 5, 56, 29, 2, 125, 136, 5, 62, 32, 2, 126, 136, 5, 58, 30, 2, 127, 136, 5, 40, 21, 2, 128, 136, 5, 10, 6, 2, 129, 136, 5, 64, 33, 2, 130, 136, 5, 66, 34, 2, 131, 136, 5, 70, 36, 2, 132, 136, 5, 72, 37, 2, 133, 136, 5, 98, 50, 2, 134, 136, 5, 74, 38, 2, 135, 122, 3, 2, 2, 2, 135, 123, 3, 2, 2, 2, 135, 124, 3, 2, 2, 2, 135, 125, 3, 2, 2, 2, 135, 126, 3, 2, 2, 2, 135, 127, 3, 2, 2, 2, 135, 128, 3, 2, 2, 2, 135, 129, 3, 2, 2, 2, 135, 130, 3, 2, 2, 2, 135, 131, 3, 2, 2, 2, 135, 132, 3, 2, 2, 2, 135, 133, 3, 2, 2, 2, 135, 134, 3, 2, 2, 2, 136, 9, 3, 2, 2, 2, 137, 138, 7, 19, 2, 2, 138, 139, 5, 12, 7, 2, 139, 11, 3, 2, 2, 2, 140, 141, 8, 7, 1, 2, 141, 142, 7, 45, 2, 2, 142, 169, 5, 12, 7, 9, 143, 169, 5, 16, 9, 2, 144, 169, 5, 14, 8, 2, 145, 147, 5, 16, 9, 2, 146, 148, 7, 45, 2, 2, 147, 146, 3, 2, 2, 2, 147, 148, 3, 2, 2, 2, 148, 149, 3, 2, 2, 2, 149, 150, 7, 42, 2, 2, 150, 151, 7, 41, 2, 2, 151, 156, 5, 16, 9, 2, 152, 153, 7, 35, 2, 2, 153, 155, 5, 16, 9, 2, 154, 152, 3, 2, 2, 2, 155, 158, 3, 2, 2, 2, 156, 154, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 159, 3, 2, 2, 2, 158, 156, 3, 2, 2, 2, 159, 160, 7, 51, 2, 2, 160, 169, 3, 2, 2, 2, 161, 162, 5, 16, 9, 2, 162, 164, 7, 43, 2, 2, 163, 165, 7, 45, 2, 2, 164, 163, 3, 2, 2, 2, 164, 165, 3, 2, 2, 2, 165, 166, 3, 2, 2, 2, 166, 167, 7, 46, 2, 2, 167, 169, 3, 2, 2, 2, 168, 140, 3, 2, 2, 2, 168, 143, 3, 2, 2, 2, 168, 144, 3, 2, 2, 2, 168, 145, 3, 2, 2, 2, 168, 161, 3, 2, 2, 2, 169, 178, 3, 2, 2, 2, 170, 171, 12, 6, 2, 2, 171, 172, 7, 32, 2, 2, 172, 177, 5, 12, 7, 7, 173, 174, 12, 5, 2, 2, 174, 175, 7, 48, 2, 2, 175, 177, 5, 12, 7, 6, 176, 170, 3, 2, 2, 2, 176, 173, 3, 2, 2, 2, 177, 180, 3, 2, 2, 2, 178, 176, 3, 2, 2, 2, 178, 179, 3, 2, 2, 2, 179, 13, 3, 2, 2, 2, 180, 178, 3, 2, 2, 2, 181, 183, 5, 16, 9, 2, 182, 184, 7, 45, 2, 2, 183, 182, 3, 2, 2, 2, 183, 184, 3, 2, 2, 2, 184, 185, 3, 2, 2, 2, 185, 186, 7, 44, 2, 2, 186, 187, 5, 88, 45, 2, 187, 196, 3, 2, 2, 2, 188, 190, 5, 16, 9, 2, 189, 191, 7, 45, 2, 2, 190, 189, 3, 2, 2, 2, 190, 191, 3, 2, 2, 2, 191, 192, 3, 2, 2, 2, 192, 193, 7, 50, 2, 2, 193, 194, 5, 88, 45, 2, 194, 196, 3, 2, 2, 2, 195, 181, 3, 2, 2, 2, 195, 188, 3, 2, 2, 2, 196, 15, 3, 2, 2, 2, 197, 203, 5, 18, 10, 2, 198, 199, 5, 18, 10, 2, 199, 200, 5, 90, 46, 2, 200, 201, 5, 18, 10, 2, 201, 203, 3, 2, 2, 2, 202, 197, 3, 2, 2, 2, 202, 198, 3, 2, 2, 2, 203, 17, 3, 2, 2, 2, 204, 205, 8, 10, 1, 2, 205, 209, 5, 20, 11, 2, 206, 207, 9, 2, 2, 2, 207, 209, 5, 18, 10, 5, 208, 204, 3, 2, 2, 2, 208, 206, 3, 2, 2, 2, 209, 218, 3, 2, 2, 2, 210, 211, 12, 4, 2, 2, 211, 212, 9, 3, 2, 2, 212, 217, 5, 18, 10, 5, 213, 214, 12, 3, 2, 2, 214, 215, 9, 2, 2, 2, 215, 217, 5, 18, 10, 4, 216, 210, 3, 2, 2, 2, 216, 213, 3, 2, 2, 2, 217, 220, 3, 2, 2, 2, 218, 216, 3, 2, 2, 2, 218, 219, 3, 2, 2, 2, 219, 19, 3, 2, 2, 2, 220, 218, 3, 2, 2, 2, 221, 229, 5, 54, 28, 2, 222, 229, 5, 46, 24, 2, 223, 229, 5, 22, 12, 2, 224, 225, 7, 41, 2, 2, 225, 226, 5, 12, 7, 2, 226, 227, 7, 51, 2, 2, 227, 229, 3, 2, 2, 2, 228, 221, 3, 2, 2, 2, 228, 222, 3, 2, 2, 2, 228, 223, 3, 2, 2, 2, 228, 224, 3, 2, 2, 2, 229, 21, 3, 2, 2, 2, 230, 231, 5, 50, 26, 2, 231, 241, 7, 41, 2, 2, 232, 242, 7, 62, 2, 2, 233, 238, 5, 12, 7, 2, 234, 235, 7, 35, 2, 2, 235, 237, 5, 12, 7, 2, 236, 234, 3, 2, 2, 2, 237, 240, 3, 2, 2, 2, 238, 236, 3, 2, 2, 2, 238, 239, 3, 2, 2, 2, 239, 242, 3, 2, 2, 2, 240, 238, 3, 2, 2, 2, 241, 232, 3, 2, 2, 2, 241, 233, 3, 2, 2, 2, 241, 242, 3, 2, 2, 2, 242, 243, 3, 2, 2, 2, 243, 244, 7, 51, 2, 2, 244, 23, 3, 2, 2, 2, 245, 246, 7, 15, 2, 2, 246, 247, 5, 26, 14, 2, 247, 25, 3, 2, 2, 2, 248, 253, 5, 28, 15, 2, 249, 250, 7, 35, 2, 2, 250, 252, 5, 28, 15, 2, 251, 249, 3, 2, 2, 2, 252, 255, 3, 2, 2, 2, 253, 251, 3, 2, 2, 2, 253, 254, 3, 2, 2, 2, 254, 27, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 256, 262, 5, 12, 7, 2, 257, 258, 5, 46, 24, 2, 258, 259, 7, 34, 2, 2, 259, 260, 5, 12, 7, 2, 260, 262, 3, 2, 2, 2, 261, 256, 3, 2, 2, 2, 261, 257, 3, 2, 2, 2, 262, 29, 3, 2, 2, 2, 263, 264, 7, 8, 2, 2, 264, 269, 5, 44, 23, 2, 265, 266, 7, 35, 2, 2, 266, 268, 5, 44, 23, 2, 267, 265, 3, 2, 2, 2, 268, 271, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 269, 270, 3, 2, 2, 2, 270, 273, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 272, 274, 5, 32, 17, 2, 273, 272, 3, 2, 2, 2, 273, 274, 3, 2, 2, 2, 274, 31, 3, 2, 2, 2, 275, 278, 5, 34, 18, 2, 276, 278, 5, 36, 19, 2, 277, 275, 3, 2, 2, 2, 277, 276, 3, 2, 2, 2, 278, 33, 3, 2, 2, 2, 279, 280, 7, 72, 2, 2, 280, 285, 5, 44, 23, 2, 281, 282, 7, 35, 2, 2, 282, 284, 5, 44, 23, 2, 283, 281, 3, 2, 2, 2, 284, 287, 3, 2, 2, 2, 285, 283, 3, 2, 2, 2, 285, 286, 3, 2, 2, 2, 286, 35, 3, 2, 2, 2, 287, 285, 3, 2, 2, 2, 288, 289, 7, 65, 2, 2, 289, 290, 5, 34, 18, 2, 290, 291, 7, 66, 2, 2, 291, 37, 3, 2, 2, 2, 292, 293, 7, 6, 2, 2, 293, 294, 5, 26, 14, 2, 294, 39, 3, 2, 2, 2, 295, 297, 7, 18, 2, 2, 296, 298, 5, 26, 14, 2, 297, 296, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 301, 3, 2, 2, 2, 299, 300, 7, 31, 2, 2, 300, 302, 5, 26, 14, 2, 301, 299, 3, 2, 2, 2, 301, 302, 3, 2, 2, 2, 302, 41, 3, 2, 2, 2, 303, 304, 7, 10, 2, 2, 304, 307, 5, 26, 14, 2, 305, 306, 7, 31, 2, 2, 306, 308, 5, 26, 14, 2, 307, 305, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 43, 3, 2, 2, 2, 309, 310, 9, 4, 2, 2, 310, 45, 3, 2, 2, 2, 311, 316, 5, 50, 26, 2, 312, 313, 7, 37, 2, 2, 313, 315, 5, 50, 26, 2, 314, 312, 3, 2, 2, 2, 315, 318, 3, 2, 2, 2, 316, 314, 3, 2, 2, 2, 316, 317, 3, 2, 2, 2, 317, 47, 3, 2, 2, 2, 318, 316, 3, 2, 2, 2, 319, 324, 5, 52, 27, 2, 320, 321, 7, 37, 2, 2, 321, 323, 5, 52, 27, 2, 322, 320, 3, 2, 2, 2, 323, 326, 3, 2, 2, 2, 324, 322, 3, 2, 2, 2, 324, 325, 3, 2, 2, 2, 325, 49, 3, 2, 2, 2, 326, 324, 3, 2, 2, 2, 327, 328, 9, 5, 2, 2, 328, 51, 3, 2, 2, 2, 329, 330, 9, 6, 2, 2, 330, 53, 3, 2, 2, 2, 331, 374, 7, 46, 2, 2, 332, 333, 5, 86, 44, 2, 333, 334, 7, 67, 2, 2, 334, 374, 3, 2, 2, 2, 335, 374, 5, 84, 43, 2, 336, 374, 5, 86, 44, 2, 337, 374, 5, 80, 41, 2, 338, 374, 7, 49, 2, 2, 339, 374, 5, 88, 45, 2, 340, 341, 7, 65, 2, 2, 341, 346, 5, 82, 42, 2, 342, 343, 7, 35, 2, 2, 343, 345, 5, 82, 42, 2, 344, 342, 3, 2, 2, 2, 345, 348, 3, 2, 2, 2, 346, 344, 3, 2, 2, 2, 346, 347, 3, 2, 2, 2, 347, 349, 3, 2, 2, 2, 348, 346, 3, 2, 2, 2, 349, 350, 7, 66, 2, 2, 350, 374, 3, 2, 2, 2, 351, 352, 7, 65, 2, 2, 352, 357, 5, 80, 41, 2, 353, 354, 7, 35, 2, 2, 354, 356, 5, 80, 41, 2, 355, 353, 3, 2, 2, 2, 356, 359, 3, 2, 2, 2, 357, 355, 3, 2, 2, 2, 357, 358, 3, 2, 2, 2, 358, 360, 3, 2, 2, 2, 359, 357, 3, 2, 2, 2, 360, 361, 7, 66, 2, 2, 361, 374, 3, 2, 2, 2, 362, 363, 7, 65, 2, 2, 363, 368, 5, 88, 45, 2, 364, 365, 7, 35, 2, 2, 365, 367, 5, 88, 45, 2, 366, 364, 3, 2, 2, 2, 367, 370, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 368, 369, 3, 2, 2, 2, 369, 371, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 371, 372, 7, 66, 2, 2, 372, 374, 3, 2, 2, 2, 373, 331, 3, 2, 2, 2, 373, 332, 3, 2, 2, 2, 373, 335, 3, 2, 2, 2, 373, 336, 3, 2, 2, 2, 373, 337, 3, 2, 2, 2, 373, 338, 3, 2, 2, 2, 373, 339, 3, 2, 2, 2, 373, 340, 3, 2, 2, 2, 373, 351, 3, 2, 2, 2, 373, 362, 3, 2, 2, 2, 374, 55, 3, 2, 2, 2, 375, 376, 7, 12, 2, 2, 376, 377, 7, 29, 2, 2, 377, 57, 3, 2, 2, 2, 378, 379, 7, 17, 2, 2, 379, 384, 5, 60, 31, 2, 380, 381, 7, 35, 2, 2, 381, 383, 5, 60, 31, 2, 382, 380, 3, 2, 2, 2, 383, 386, 3, 2, 2, 2, 384, 382, 3, 2, 2, 2, 384, 385, 3, 2, 2, 2, 385, 59, 3, 2, 2, 2, 386, 384, 3, 2, 2, 2, 387, 389, 5, 12, 7, 2, 388, 390, 9, 7, 2, 2, 389, 388, 3, 2, 2, 2, 389, 390, 3, 2, 2, 2, 390, 393, 3, 2, 2, 2, 391, 392, 7, 47, 2, 2, 392, 394, 9, 8, 2, 2, 393, 391, 3, 2, 2, 2, 393, 394, 3, 2, 2, 2, 394, 61, 3, 2, 2, 2, 395, 396, 7, 11, 2, 2, 396, 401, 5, 48, 25, 2, 397, 398, 7, 35, 2, 2, 398, 400, 5, 48, 25, 2, 399, 397, 3, 2, 2, 2, 400, 403, 3, 2, 2, 2, 401, 399, 3, 2, 2, 2, 401, 402, 3, 2, 2, 2, 402, 63, 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 404, 405, 7, 4, 2, 2, 405, 410, 5, 48, 25, 2, 406, 407, 7, 35, 2, 2, 407, 409, 5, 48, 25, 2, 408, 406, 3, 2, 2, 2, 409, 412, 3, 2, 2, 2, 410, 408, 3, 2, 2, 2, 410, 411, 3, 2, 2, 2, 411, 65, 3, 2, 2, 2, 412, 410, 3, 2, 2, 2, 413, 414, 7, 14, 2, 2, 414, 419, 5, 68, 35, 2, 415, 416, 7, 35, 2, 2, 416, 418, 5, 68, 35, 2, 417, 415, 3, 2, 2, 2, 418, 421, 3, 2, 2, 2, 419, 417, 3, 2, 2, 2, 419, 420, 3, 2, 2, 2, 420, 67, 3, 2, 2, 2, 421, 419, 3, 2, 2, 2, 422, 423, 5, 48, 25, 2, 423, 424, 7, 81, 2, 2, 424, 425, 5, 48, 25, 2, 425, 69, 3, 2, 2, 2, 426, 427, 7, 3, 2, 2, 427, 428, 5, 20, 11, 2, 428, 430, 5, 88, 45, 2, 429, 431, 5, 76, 39, 2, 430, 429, 3, 2, 2, 2, 430, 431, 3, 2, 2, 2, 431, 71, 3, 2, 2, 2, 432, 433, 7, 9, 2, 2, 433, 434, 5, 20, 11, 2, 434, 435, 5, 88, 45, 2, 435, 73, 3, 2, 2, 2, 436, 437, 7, 13, 2, 2, 437, 438, 5, 46, 24, 2, 438, 75, 3, 2, 2, 2, 439, 444, 5, 78, 40, 2, 440, 441, 7, 35, 2, 2, 441, 443, 5, 78, 40, 2, 442, 440, 3, 2, 2, 2, 443, 446, 3, 2, 2, 2, 444, 442, 3, 2, 2, 2, 444, 445, 3, 2, 2, 2, 445, 77, 3, 2, 2, 2, 446, 444, 3, 2, 2, 2, 447, 448, 5, 50, 26, 2, 448, 449, 7, 34, 2, 2, 449, 450, 5, 54, 28, 2, 450, 79, 3, 2, 2, 2, 451, 452, 9, 9, 2, 2, 452, 81, 3, 2, 2, 2, 453, 456, 5, 84, 43, 2, 454, 456, 5, 86, 44, 2, 455, 453, 3, 2, 2, 2, 455, 454, 3, 2, 2, 2, 456, 83, 3, 2, 2, 2, 457, 459, 9, 2, 2, 2, 458, 457, 3, 2, 2, 2, 458, 459, 3, 2, 2, 2, 459, 460, 3, 2, 2, 2, 460, 461, 7, 30, 2, 2, 461, 85, 3, 2, 2, 2, 462, 464, 9, 2, 2, 2, 463, 462, 3, 2, 2, 2, 463, 464, 3, 2, 2, 2, 464, 465, 3, 2, 2, 2, 465, 466, 7, 29, 2, 2, 466, 87, 3, 2, 2, 2, 467, 468, 7, 28, 2, 2, 468, 89, 3, 2, 2, 2, 469, 470, 9, 10, 2, 2, 470, 91, 3, 2, 2, 2, 471, 472, 7, 7, 2, 2, 472, 473, 5, 94, 48, 2, 473, 93, 3, 2, 2, 2, 474, 475, 7, 65, 2, 2, 475, 476, 5, 4, 3, 2, 476, 477, 7, 66, 2, 2, 477, 95, 3, 2, 2, 2, 478, 479, 7, 16, 2, 2, 479, 483, 7, 97, 2, 2, 480, 481, 7, 16, 2, 2, 481, 483, 7, 98, 2, 2, 482, 478, 3, 2, 2, 2, 482, 480, 3, 2, 2, 2, 483, 97, 3, 2, 2, 2, 484, 485, 7, 5, 2, 2, 485, 488, 7, 87, 2, 2, 486, 487, 7, 85, 2, 2, 487, 489, 5, 48, 25, 2, 488, 486, 3, 2, 2, 2, 488, 489, 3, 2, 2, 2, 489, 499, 3, 2, 2, 2, 490, 491, 7, 86, 2, 2, 491, 496, 5, 100, 51, 2, 492, 493, 7, 35, 2, 2, 493, 495, 5, 100, 51, 2, 494, 492, 3, 2, 2, 2, 495, 498, 3, 2, 2, 2, 496, 494, 3, 2, 2, 2, 496, 497, 3, 2, 2, 2, 497, 500, 3, 2, 2, 2, 498, 496, 3, 2, 2, 2, 499, 490, 3, 2, 2, 2, 499, 500, 3, 2, 2, 2, 500, 99, 3, 2, 2, 2, 501, 502, 5, 48, 25, 2, 502, 503, 7, 34, 2, 2, 503, 505, 3, 2, 2, 2, 504, 501, 3, 2, 2, 2, 504, 505, 3, 2, 2, 2, 505, 506, 3, 2, 2, 2, 506, 507, 5, 48, 25, 2, 507, 101, 3, 2, 2, 2, 52, 113, 120, 135, 147, 156, 164, 168, 176, 178, 183, 190, 195, 202, 208, 216, 218, 228, 238, 241, 253, 261, 269, 273, 277, 285, 297, 301, 307, 316, 324, 346, 357, 368, 373, 384, 389, 393, 401, 410, 419, 430, 444, 455, 458, 463, 482, 488, 496, 499, 504] \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens b/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens index 4bdf0572a3b8a..1f49f7e26406b 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens @@ -9,118 +9,117 @@ INLINESTATS=8 KEEP=9 LIMIT=10 MV_EXPAND=11 -PROJECT=12 -RENAME=13 -ROW=14 -SHOW=15 -SORT=16 -STATS=17 -WHERE=18 -UNKNOWN_CMD=19 -LINE_COMMENT=20 -MULTILINE_COMMENT=21 -WS=22 -EXPLAIN_WS=23 -EXPLAIN_LINE_COMMENT=24 -EXPLAIN_MULTILINE_COMMENT=25 -PIPE=26 -STRING=27 -INTEGER_LITERAL=28 -DECIMAL_LITERAL=29 -BY=30 -AND=31 -ASC=32 -ASSIGN=33 -COMMA=34 -DESC=35 -DOT=36 -FALSE=37 -FIRST=38 -LAST=39 -LP=40 -IN=41 -IS=42 -LIKE=43 -NOT=44 -NULL=45 -NULLS=46 -OR=47 -PARAM=48 -RLIKE=49 -RP=50 -TRUE=51 -EQ=52 -CIEQ=53 -NEQ=54 -LT=55 -LTE=56 -GT=57 -GTE=58 -PLUS=59 -MINUS=60 -ASTERISK=61 -SLASH=62 -PERCENT=63 -OPENING_BRACKET=64 -CLOSING_BRACKET=65 -UNQUOTED_IDENTIFIER=66 -QUOTED_IDENTIFIER=67 -EXPR_LINE_COMMENT=68 -EXPR_MULTILINE_COMMENT=69 -EXPR_WS=70 -METADATA=71 -FROM_UNQUOTED_IDENTIFIER=72 -FROM_LINE_COMMENT=73 -FROM_MULTILINE_COMMENT=74 -FROM_WS=75 -UNQUOTED_ID_PATTERN=76 -PROJECT_LINE_COMMENT=77 -PROJECT_MULTILINE_COMMENT=78 -PROJECT_WS=79 -AS=80 -RENAME_LINE_COMMENT=81 -RENAME_MULTILINE_COMMENT=82 -RENAME_WS=83 -ON=84 -WITH=85 -ENRICH_POLICY_NAME=86 -ENRICH_LINE_COMMENT=87 -ENRICH_MULTILINE_COMMENT=88 -ENRICH_WS=89 -ENRICH_FIELD_LINE_COMMENT=90 -ENRICH_FIELD_MULTILINE_COMMENT=91 -ENRICH_FIELD_WS=92 -MVEXPAND_LINE_COMMENT=93 -MVEXPAND_MULTILINE_COMMENT=94 -MVEXPAND_WS=95 -INFO=96 -FUNCTIONS=97 -SHOW_LINE_COMMENT=98 -SHOW_MULTILINE_COMMENT=99 -SHOW_WS=100 -COLON=101 -SETTING=102 -SETTING_LINE_COMMENT=103 -SETTTING_MULTILINE_COMMENT=104 -SETTING_WS=105 -'|'=26 -'='=33 -','=34 -'.'=36 -'('=40 -'?'=48 -')'=50 -'=='=52 -'=~'=53 -'!='=54 -'<'=55 -'<='=56 -'>'=57 -'>='=58 -'+'=59 -'-'=60 -'*'=61 -'/'=62 -'%'=63 -']'=65 -':'=101 +RENAME=12 +ROW=13 +SHOW=14 +SORT=15 +STATS=16 +WHERE=17 +UNKNOWN_CMD=18 +LINE_COMMENT=19 +MULTILINE_COMMENT=20 +WS=21 +EXPLAIN_WS=22 +EXPLAIN_LINE_COMMENT=23 +EXPLAIN_MULTILINE_COMMENT=24 +PIPE=25 +STRING=26 +INTEGER_LITERAL=27 +DECIMAL_LITERAL=28 +BY=29 +AND=30 +ASC=31 +ASSIGN=32 +COMMA=33 +DESC=34 +DOT=35 +FALSE=36 +FIRST=37 +LAST=38 +LP=39 +IN=40 +IS=41 +LIKE=42 +NOT=43 +NULL=44 +NULLS=45 +OR=46 +PARAM=47 +RLIKE=48 +RP=49 +TRUE=50 +EQ=51 +CIEQ=52 +NEQ=53 +LT=54 +LTE=55 +GT=56 +GTE=57 +PLUS=58 +MINUS=59 +ASTERISK=60 +SLASH=61 +PERCENT=62 +OPENING_BRACKET=63 +CLOSING_BRACKET=64 +UNQUOTED_IDENTIFIER=65 +QUOTED_IDENTIFIER=66 +EXPR_LINE_COMMENT=67 +EXPR_MULTILINE_COMMENT=68 +EXPR_WS=69 +METADATA=70 +FROM_UNQUOTED_IDENTIFIER=71 +FROM_LINE_COMMENT=72 +FROM_MULTILINE_COMMENT=73 +FROM_WS=74 +UNQUOTED_ID_PATTERN=75 +PROJECT_LINE_COMMENT=76 +PROJECT_MULTILINE_COMMENT=77 +PROJECT_WS=78 +AS=79 +RENAME_LINE_COMMENT=80 +RENAME_MULTILINE_COMMENT=81 +RENAME_WS=82 +ON=83 +WITH=84 +ENRICH_POLICY_NAME=85 +ENRICH_LINE_COMMENT=86 +ENRICH_MULTILINE_COMMENT=87 +ENRICH_WS=88 +ENRICH_FIELD_LINE_COMMENT=89 +ENRICH_FIELD_MULTILINE_COMMENT=90 +ENRICH_FIELD_WS=91 +MVEXPAND_LINE_COMMENT=92 +MVEXPAND_MULTILINE_COMMENT=93 +MVEXPAND_WS=94 +INFO=95 +FUNCTIONS=96 +SHOW_LINE_COMMENT=97 +SHOW_MULTILINE_COMMENT=98 +SHOW_WS=99 +COLON=100 +SETTING=101 +SETTING_LINE_COMMENT=102 +SETTTING_MULTILINE_COMMENT=103 +SETTING_WS=104 +'|'=25 +'='=32 +','=33 +'.'=35 +'('=39 +'?'=47 +')'=49 +'=='=51 +'=~'=52 +'!='=53 +'<'=54 +'<='=55 +'>'=56 +'>='=57 +'+'=58 +'-'=59 +'*'=60 +'/'=61 +'%'=62 +']'=64 +':'=100 diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.ts b/packages/kbn-monaco/src/esql/antlr/esql_parser.ts index 696d67ba90f00..28d31ef92064a 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.ts @@ -38,100 +38,99 @@ export class esql_parser extends Parser { public static readonly KEEP = 9; public static readonly LIMIT = 10; public static readonly MV_EXPAND = 11; - public static readonly PROJECT = 12; - public static readonly RENAME = 13; - public static readonly ROW = 14; - public static readonly SHOW = 15; - public static readonly SORT = 16; - public static readonly STATS = 17; - public static readonly WHERE = 18; - public static readonly UNKNOWN_CMD = 19; - public static readonly LINE_COMMENT = 20; - public static readonly MULTILINE_COMMENT = 21; - public static readonly WS = 22; - public static readonly EXPLAIN_WS = 23; - public static readonly EXPLAIN_LINE_COMMENT = 24; - public static readonly EXPLAIN_MULTILINE_COMMENT = 25; - public static readonly PIPE = 26; - public static readonly STRING = 27; - public static readonly INTEGER_LITERAL = 28; - public static readonly DECIMAL_LITERAL = 29; - public static readonly BY = 30; - public static readonly AND = 31; - public static readonly ASC = 32; - public static readonly ASSIGN = 33; - public static readonly COMMA = 34; - public static readonly DESC = 35; - public static readonly DOT = 36; - public static readonly FALSE = 37; - public static readonly FIRST = 38; - public static readonly LAST = 39; - public static readonly LP = 40; - public static readonly IN = 41; - public static readonly IS = 42; - public static readonly LIKE = 43; - public static readonly NOT = 44; - public static readonly NULL = 45; - public static readonly NULLS = 46; - public static readonly OR = 47; - public static readonly PARAM = 48; - public static readonly RLIKE = 49; - public static readonly RP = 50; - public static readonly TRUE = 51; - public static readonly EQ = 52; - public static readonly CIEQ = 53; - public static readonly NEQ = 54; - public static readonly LT = 55; - public static readonly LTE = 56; - public static readonly GT = 57; - public static readonly GTE = 58; - public static readonly PLUS = 59; - public static readonly MINUS = 60; - public static readonly ASTERISK = 61; - public static readonly SLASH = 62; - public static readonly PERCENT = 63; - public static readonly OPENING_BRACKET = 64; - public static readonly CLOSING_BRACKET = 65; - public static readonly UNQUOTED_IDENTIFIER = 66; - public static readonly QUOTED_IDENTIFIER = 67; - public static readonly EXPR_LINE_COMMENT = 68; - public static readonly EXPR_MULTILINE_COMMENT = 69; - public static readonly EXPR_WS = 70; - public static readonly METADATA = 71; - public static readonly FROM_UNQUOTED_IDENTIFIER = 72; - public static readonly FROM_LINE_COMMENT = 73; - public static readonly FROM_MULTILINE_COMMENT = 74; - public static readonly FROM_WS = 75; - public static readonly UNQUOTED_ID_PATTERN = 76; - public static readonly PROJECT_LINE_COMMENT = 77; - public static readonly PROJECT_MULTILINE_COMMENT = 78; - public static readonly PROJECT_WS = 79; - public static readonly AS = 80; - public static readonly RENAME_LINE_COMMENT = 81; - public static readonly RENAME_MULTILINE_COMMENT = 82; - public static readonly RENAME_WS = 83; - public static readonly ON = 84; - public static readonly WITH = 85; - public static readonly ENRICH_POLICY_NAME = 86; - public static readonly ENRICH_LINE_COMMENT = 87; - public static readonly ENRICH_MULTILINE_COMMENT = 88; - public static readonly ENRICH_WS = 89; - public static readonly ENRICH_FIELD_LINE_COMMENT = 90; - public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 91; - public static readonly ENRICH_FIELD_WS = 92; - public static readonly MVEXPAND_LINE_COMMENT = 93; - public static readonly MVEXPAND_MULTILINE_COMMENT = 94; - public static readonly MVEXPAND_WS = 95; - public static readonly INFO = 96; - public static readonly FUNCTIONS = 97; - public static readonly SHOW_LINE_COMMENT = 98; - public static readonly SHOW_MULTILINE_COMMENT = 99; - public static readonly SHOW_WS = 100; - public static readonly COLON = 101; - public static readonly SETTING = 102; - public static readonly SETTING_LINE_COMMENT = 103; - public static readonly SETTTING_MULTILINE_COMMENT = 104; - public static readonly SETTING_WS = 105; + public static readonly RENAME = 12; + public static readonly ROW = 13; + public static readonly SHOW = 14; + public static readonly SORT = 15; + public static readonly STATS = 16; + public static readonly WHERE = 17; + public static readonly UNKNOWN_CMD = 18; + public static readonly LINE_COMMENT = 19; + public static readonly MULTILINE_COMMENT = 20; + public static readonly WS = 21; + public static readonly EXPLAIN_WS = 22; + public static readonly EXPLAIN_LINE_COMMENT = 23; + public static readonly EXPLAIN_MULTILINE_COMMENT = 24; + public static readonly PIPE = 25; + public static readonly STRING = 26; + public static readonly INTEGER_LITERAL = 27; + public static readonly DECIMAL_LITERAL = 28; + public static readonly BY = 29; + public static readonly AND = 30; + public static readonly ASC = 31; + public static readonly ASSIGN = 32; + public static readonly COMMA = 33; + public static readonly DESC = 34; + public static readonly DOT = 35; + public static readonly FALSE = 36; + public static readonly FIRST = 37; + public static readonly LAST = 38; + public static readonly LP = 39; + public static readonly IN = 40; + public static readonly IS = 41; + public static readonly LIKE = 42; + public static readonly NOT = 43; + public static readonly NULL = 44; + public static readonly NULLS = 45; + public static readonly OR = 46; + public static readonly PARAM = 47; + public static readonly RLIKE = 48; + public static readonly RP = 49; + public static readonly TRUE = 50; + public static readonly EQ = 51; + public static readonly CIEQ = 52; + public static readonly NEQ = 53; + public static readonly LT = 54; + public static readonly LTE = 55; + public static readonly GT = 56; + public static readonly GTE = 57; + public static readonly PLUS = 58; + public static readonly MINUS = 59; + public static readonly ASTERISK = 60; + public static readonly SLASH = 61; + public static readonly PERCENT = 62; + public static readonly OPENING_BRACKET = 63; + public static readonly CLOSING_BRACKET = 64; + public static readonly UNQUOTED_IDENTIFIER = 65; + public static readonly QUOTED_IDENTIFIER = 66; + public static readonly EXPR_LINE_COMMENT = 67; + public static readonly EXPR_MULTILINE_COMMENT = 68; + public static readonly EXPR_WS = 69; + public static readonly METADATA = 70; + public static readonly FROM_UNQUOTED_IDENTIFIER = 71; + public static readonly FROM_LINE_COMMENT = 72; + public static readonly FROM_MULTILINE_COMMENT = 73; + public static readonly FROM_WS = 74; + public static readonly UNQUOTED_ID_PATTERN = 75; + public static readonly PROJECT_LINE_COMMENT = 76; + public static readonly PROJECT_MULTILINE_COMMENT = 77; + public static readonly PROJECT_WS = 78; + public static readonly AS = 79; + public static readonly RENAME_LINE_COMMENT = 80; + public static readonly RENAME_MULTILINE_COMMENT = 81; + public static readonly RENAME_WS = 82; + public static readonly ON = 83; + public static readonly WITH = 84; + public static readonly ENRICH_POLICY_NAME = 85; + public static readonly ENRICH_LINE_COMMENT = 86; + public static readonly ENRICH_MULTILINE_COMMENT = 87; + public static readonly ENRICH_WS = 88; + public static readonly ENRICH_FIELD_LINE_COMMENT = 89; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 90; + public static readonly ENRICH_FIELD_WS = 91; + public static readonly MVEXPAND_LINE_COMMENT = 92; + public static readonly MVEXPAND_MULTILINE_COMMENT = 93; + public static readonly MVEXPAND_WS = 94; + public static readonly INFO = 95; + public static readonly FUNCTIONS = 96; + public static readonly SHOW_LINE_COMMENT = 97; + public static readonly SHOW_MULTILINE_COMMENT = 98; + public static readonly SHOW_WS = 99; + public static readonly COLON = 100; + public static readonly SETTING = 101; + public static readonly SETTING_LINE_COMMENT = 102; + public static readonly SETTTING_MULTILINE_COMMENT = 103; + public static readonly SETTING_WS = 104; public static readonly RULE_singleStatement = 0; public static readonly RULE_query = 1; public static readonly RULE_sourceCommand = 2; @@ -148,61 +147,62 @@ export class esql_parser extends Parser { public static readonly RULE_field = 13; public static readonly RULE_fromCommand = 14; public static readonly RULE_metadata = 15; - public static readonly RULE_evalCommand = 16; - public static readonly RULE_statsCommand = 17; - public static readonly RULE_inlinestatsCommand = 18; - public static readonly RULE_fromIdentifier = 19; - public static readonly RULE_qualifiedName = 20; - public static readonly RULE_qualifiedNamePattern = 21; - public static readonly RULE_identifier = 22; - public static readonly RULE_identifierPattern = 23; - public static readonly RULE_constant = 24; - public static readonly RULE_limitCommand = 25; - public static readonly RULE_sortCommand = 26; - public static readonly RULE_orderExpression = 27; - public static readonly RULE_keepCommand = 28; - public static readonly RULE_dropCommand = 29; - public static readonly RULE_renameCommand = 30; - public static readonly RULE_renameClause = 31; - public static readonly RULE_dissectCommand = 32; - public static readonly RULE_grokCommand = 33; - public static readonly RULE_mvExpandCommand = 34; - public static readonly RULE_commandOptions = 35; - public static readonly RULE_commandOption = 36; - public static readonly RULE_booleanValue = 37; - public static readonly RULE_numericValue = 38; - public static readonly RULE_decimalValue = 39; - public static readonly RULE_integerValue = 40; - public static readonly RULE_string = 41; - public static readonly RULE_comparisonOperator = 42; - public static readonly RULE_explainCommand = 43; - public static readonly RULE_subqueryExpression = 44; - public static readonly RULE_showCommand = 45; - public static readonly RULE_enrichCommand = 46; - public static readonly RULE_enrichWithClause = 47; - public static readonly RULE_setting = 48; + public static readonly RULE_metadataOption = 16; + public static readonly RULE_deprecated_metadata = 17; + public static readonly RULE_evalCommand = 18; + public static readonly RULE_statsCommand = 19; + public static readonly RULE_inlinestatsCommand = 20; + public static readonly RULE_fromIdentifier = 21; + public static readonly RULE_qualifiedName = 22; + public static readonly RULE_qualifiedNamePattern = 23; + public static readonly RULE_identifier = 24; + public static readonly RULE_identifierPattern = 25; + public static readonly RULE_constant = 26; + public static readonly RULE_limitCommand = 27; + public static readonly RULE_sortCommand = 28; + public static readonly RULE_orderExpression = 29; + public static readonly RULE_keepCommand = 30; + public static readonly RULE_dropCommand = 31; + public static readonly RULE_renameCommand = 32; + public static readonly RULE_renameClause = 33; + public static readonly RULE_dissectCommand = 34; + public static readonly RULE_grokCommand = 35; + public static readonly RULE_mvExpandCommand = 36; + public static readonly RULE_commandOptions = 37; + public static readonly RULE_commandOption = 38; + public static readonly RULE_booleanValue = 39; + public static readonly RULE_numericValue = 40; + public static readonly RULE_decimalValue = 41; + public static readonly RULE_integerValue = 42; + public static readonly RULE_string = 43; + public static readonly RULE_comparisonOperator = 44; + public static readonly RULE_explainCommand = 45; + public static readonly RULE_subqueryExpression = 46; + public static readonly RULE_showCommand = 47; + public static readonly RULE_enrichCommand = 48; + public static readonly RULE_enrichWithClause = 49; // tslint:disable:no-trailing-whitespace public static readonly ruleNames: string[] = [ "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand", "booleanExpression", "regexBooleanExpression", "valueExpression", "operatorExpression", "primaryExpression", "functionExpression", "rowCommand", "fields", "field", - "fromCommand", "metadata", "evalCommand", "statsCommand", "inlinestatsCommand", - "fromIdentifier", "qualifiedName", "qualifiedNamePattern", "identifier", - "identifierPattern", "constant", "limitCommand", "sortCommand", "orderExpression", - "keepCommand", "dropCommand", "renameCommand", "renameClause", "dissectCommand", - "grokCommand", "mvExpandCommand", "commandOptions", "commandOption", "booleanValue", - "numericValue", "decimalValue", "integerValue", "string", "comparisonOperator", - "explainCommand", "subqueryExpression", "showCommand", "enrichCommand", - "enrichWithClause", "setting", + "fromCommand", "metadata", "metadataOption", "deprecated_metadata", "evalCommand", + "statsCommand", "inlinestatsCommand", "fromIdentifier", "qualifiedName", + "qualifiedNamePattern", "identifier", "identifierPattern", "constant", + "limitCommand", "sortCommand", "orderExpression", "keepCommand", "dropCommand", + "renameCommand", "renameClause", "dissectCommand", "grokCommand", "mvExpandCommand", + "commandOptions", "commandOption", "booleanValue", "numericValue", "decimalValue", + "integerValue", "string", "comparisonOperator", "explainCommand", "subqueryExpression", + "showCommand", "enrichCommand", "enrichWithClause", ]; private static readonly _LITERAL_NAMES: Array<string | undefined> = [ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, "'|'", undefined, - undefined, undefined, undefined, undefined, undefined, "'='", "','", undefined, - "'.'", undefined, undefined, undefined, "'('", undefined, undefined, undefined, + undefined, undefined, undefined, undefined, "'|'", undefined, undefined, + undefined, undefined, undefined, undefined, "'='", "','", undefined, "'.'", + undefined, undefined, undefined, "'('", undefined, undefined, undefined, undefined, undefined, undefined, undefined, "'?'", undefined, "')'", undefined, "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", undefined, "']'", undefined, undefined, undefined, undefined, @@ -214,8 +214,8 @@ export class esql_parser extends Parser { ]; private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [ undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", - "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", - "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", + "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", @@ -262,9 +262,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 98; + this.state = 100; this.query(0); - this.state = 99; + this.state = 101; this.match(esql_parser.EOF); } } @@ -306,11 +306,11 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 102; + this.state = 104; this.sourceCommand(); } this._ctx._stop = this._input.tryLT(-1); - this.state = 109; + this.state = 111; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 0, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -323,18 +323,18 @@ export class esql_parser extends Parser { { _localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState)); this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_query); - this.state = 104; + this.state = 106; if (!(this.precpred(this._ctx, 1))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 1)"); } - this.state = 105; + this.state = 107; this.match(esql_parser.PIPE); - this.state = 106; + this.state = 108; this.processingCommand(); } } } - this.state = 111; + this.state = 113; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 0, this._ctx); } @@ -359,34 +359,34 @@ export class esql_parser extends Parser { let _localctx: SourceCommandContext = new SourceCommandContext(this._ctx, this.state); this.enterRule(_localctx, 4, esql_parser.RULE_sourceCommand); try { - this.state = 116; + this.state = 118; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.EXPLAIN: this.enterOuterAlt(_localctx, 1); { - this.state = 112; + this.state = 114; this.explainCommand(); } break; case esql_parser.FROM: this.enterOuterAlt(_localctx, 2); { - this.state = 113; + this.state = 115; this.fromCommand(); } break; case esql_parser.ROW: this.enterOuterAlt(_localctx, 3); { - this.state = 114; + this.state = 116; this.rowCommand(); } break; case esql_parser.SHOW: this.enterOuterAlt(_localctx, 4); { - this.state = 115; + this.state = 117; this.showCommand(); } break; @@ -413,98 +413,97 @@ export class esql_parser extends Parser { let _localctx: ProcessingCommandContext = new ProcessingCommandContext(this._ctx, this.state); this.enterRule(_localctx, 6, esql_parser.RULE_processingCommand); try { - this.state = 131; + this.state = 133; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.EVAL: this.enterOuterAlt(_localctx, 1); { - this.state = 118; + this.state = 120; this.evalCommand(); } break; case esql_parser.INLINESTATS: this.enterOuterAlt(_localctx, 2); { - this.state = 119; + this.state = 121; this.inlinestatsCommand(); } break; case esql_parser.LIMIT: this.enterOuterAlt(_localctx, 3); { - this.state = 120; + this.state = 122; this.limitCommand(); } break; case esql_parser.KEEP: - case esql_parser.PROJECT: this.enterOuterAlt(_localctx, 4); { - this.state = 121; + this.state = 123; this.keepCommand(); } break; case esql_parser.SORT: this.enterOuterAlt(_localctx, 5); { - this.state = 122; + this.state = 124; this.sortCommand(); } break; case esql_parser.STATS: this.enterOuterAlt(_localctx, 6); { - this.state = 123; + this.state = 125; this.statsCommand(); } break; case esql_parser.WHERE: this.enterOuterAlt(_localctx, 7); { - this.state = 124; + this.state = 126; this.whereCommand(); } break; case esql_parser.DROP: this.enterOuterAlt(_localctx, 8); { - this.state = 125; + this.state = 127; this.dropCommand(); } break; case esql_parser.RENAME: this.enterOuterAlt(_localctx, 9); { - this.state = 126; + this.state = 128; this.renameCommand(); } break; case esql_parser.DISSECT: this.enterOuterAlt(_localctx, 10); { - this.state = 127; + this.state = 129; this.dissectCommand(); } break; case esql_parser.GROK: this.enterOuterAlt(_localctx, 11); { - this.state = 128; + this.state = 130; this.grokCommand(); } break; case esql_parser.ENRICH: this.enterOuterAlt(_localctx, 12); { - this.state = 129; + this.state = 131; this.enrichCommand(); } break; case esql_parser.MV_EXPAND: this.enterOuterAlt(_localctx, 13); { - this.state = 130; + this.state = 132; this.mvExpandCommand(); } break; @@ -533,9 +532,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 133; + this.state = 135; this.match(esql_parser.WHERE); - this.state = 134; + this.state = 136; this.booleanExpression(0); } } @@ -573,7 +572,7 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 164; + this.state = 166; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 6, this._ctx) ) { case 1: @@ -582,9 +581,9 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 137; + this.state = 139; this.match(esql_parser.NOT); - this.state = 138; + this.state = 140; this.booleanExpression(7); } break; @@ -594,7 +593,7 @@ export class esql_parser extends Parser { _localctx = new BooleanDefaultContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 139; + this.state = 141; this.valueExpression(); } break; @@ -604,7 +603,7 @@ export class esql_parser extends Parser { _localctx = new RegexExpressionContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 140; + this.state = 142; this.regexBooleanExpression(); } break; @@ -614,41 +613,41 @@ export class esql_parser extends Parser { _localctx = new LogicalInContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 141; - this.valueExpression(); this.state = 143; + this.valueExpression(); + this.state = 145; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 142; + this.state = 144; this.match(esql_parser.NOT); } } - this.state = 145; + this.state = 147; this.match(esql_parser.IN); - this.state = 146; + this.state = 148; this.match(esql_parser.LP); - this.state = 147; + this.state = 149; this.valueExpression(); - this.state = 152; + this.state = 154; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 148; + this.state = 150; this.match(esql_parser.COMMA); - this.state = 149; + this.state = 151; this.valueExpression(); } } - this.state = 154; + this.state = 156; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 155; + this.state = 157; this.match(esql_parser.RP); } break; @@ -658,27 +657,27 @@ export class esql_parser extends Parser { _localctx = new IsNullContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 157; + this.state = 159; this.valueExpression(); - this.state = 158; - this.match(esql_parser.IS); this.state = 160; + this.match(esql_parser.IS); + this.state = 162; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 159; + this.state = 161; this.match(esql_parser.NOT); } } - this.state = 162; + this.state = 164; this.match(esql_parser.NULL); } break; } this._ctx._stop = this._input.tryLT(-1); - this.state = 174; + this.state = 176; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 8, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -688,7 +687,7 @@ export class esql_parser extends Parser { } _prevctx = _localctx; { - this.state = 172; + this.state = 174; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 7, this._ctx) ) { case 1: @@ -696,13 +695,13 @@ export class esql_parser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); (_localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 166; + this.state = 168; if (!(this.precpred(this._ctx, 4))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 4)"); } - this.state = 167; + this.state = 169; (_localctx as LogicalBinaryContext)._operator = this.match(esql_parser.AND); - this.state = 168; + this.state = 170; (_localctx as LogicalBinaryContext)._right = this.booleanExpression(5); } break; @@ -712,20 +711,20 @@ export class esql_parser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); (_localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 169; + this.state = 171; if (!(this.precpred(this._ctx, 3))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 3)"); } - this.state = 170; + this.state = 172; (_localctx as LogicalBinaryContext)._operator = this.match(esql_parser.OR); - this.state = 171; + this.state = 173; (_localctx as LogicalBinaryContext)._right = this.booleanExpression(4); } break; } } } - this.state = 176; + this.state = 178; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 8, this._ctx); } @@ -751,27 +750,27 @@ export class esql_parser extends Parser { this.enterRule(_localctx, 12, esql_parser.RULE_regexBooleanExpression); let _la: number; try { - this.state = 191; + this.state = 193; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 11, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 177; - this.valueExpression(); this.state = 179; + this.valueExpression(); + this.state = 181; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 178; + this.state = 180; this.match(esql_parser.NOT); } } - this.state = 181; + this.state = 183; _localctx._kind = this.match(esql_parser.LIKE); - this.state = 182; + this.state = 184; _localctx._pattern = this.string(); } break; @@ -779,21 +778,21 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 184; - this.valueExpression(); this.state = 186; + this.valueExpression(); + this.state = 188; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 185; + this.state = 187; this.match(esql_parser.NOT); } } - this.state = 188; + this.state = 190; _localctx._kind = this.match(esql_parser.RLIKE); - this.state = 189; + this.state = 191; _localctx._pattern = this.string(); } break; @@ -818,14 +817,14 @@ export class esql_parser extends Parser { let _localctx: ValueExpressionContext = new ValueExpressionContext(this._ctx, this.state); this.enterRule(_localctx, 14, esql_parser.RULE_valueExpression); try { - this.state = 198; + this.state = 200; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 12, this._ctx) ) { case 1: _localctx = new ValueExpressionDefaultContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 193; + this.state = 195; this.operatorExpression(0); } break; @@ -834,11 +833,11 @@ export class esql_parser extends Parser { _localctx = new ComparisonContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 194; + this.state = 196; (_localctx as ComparisonContext)._left = this.operatorExpression(0); - this.state = 195; + this.state = 197; this.comparisonOperator(); - this.state = 196; + this.state = 198; (_localctx as ComparisonContext)._right = this.operatorExpression(0); } break; @@ -878,7 +877,7 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 204; + this.state = 206; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 13, this._ctx) ) { case 1: @@ -887,7 +886,7 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 201; + this.state = 203; this.primaryExpression(); } break; @@ -897,7 +896,7 @@ export class esql_parser extends Parser { _localctx = new ArithmeticUnaryContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 202; + this.state = 204; (_localctx as ArithmeticUnaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { @@ -910,13 +909,13 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 203; + this.state = 205; this.operatorExpression(3); } break; } this._ctx._stop = this._input.tryLT(-1); - this.state = 214; + this.state = 216; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 15, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -926,7 +925,7 @@ export class esql_parser extends Parser { } _prevctx = _localctx; { - this.state = 212; + this.state = 214; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 14, this._ctx) ) { case 1: @@ -934,14 +933,14 @@ export class esql_parser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); (_localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 206; + this.state = 208; if (!(this.precpred(this._ctx, 2))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 2)"); } - this.state = 207; + this.state = 209; (_localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); - if (!(((((_la - 61)) & ~0x1F) === 0 && ((1 << (_la - 61)) & ((1 << (esql_parser.ASTERISK - 61)) | (1 << (esql_parser.SLASH - 61)) | (1 << (esql_parser.PERCENT - 61)))) !== 0))) { + if (!(((((_la - 60)) & ~0x1F) === 0 && ((1 << (_la - 60)) & ((1 << (esql_parser.ASTERISK - 60)) | (1 << (esql_parser.SLASH - 60)) | (1 << (esql_parser.PERCENT - 60)))) !== 0))) { (_localctx as ArithmeticBinaryContext)._operator = this._errHandler.recoverInline(this); } else { if (this._input.LA(1) === Token.EOF) { @@ -951,7 +950,7 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 208; + this.state = 210; (_localctx as ArithmeticBinaryContext)._right = this.operatorExpression(3); } break; @@ -961,11 +960,11 @@ export class esql_parser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); (_localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 209; + this.state = 211; if (!(this.precpred(this._ctx, 1))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 1)"); } - this.state = 210; + this.state = 212; (_localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { @@ -978,14 +977,14 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 211; + this.state = 213; (_localctx as ArithmeticBinaryContext)._right = this.operatorExpression(2); } break; } } } - this.state = 216; + this.state = 218; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 15, this._ctx); } @@ -1010,14 +1009,14 @@ export class esql_parser extends Parser { let _localctx: PrimaryExpressionContext = new PrimaryExpressionContext(this._ctx, this.state); this.enterRule(_localctx, 18, esql_parser.RULE_primaryExpression); try { - this.state = 224; + this.state = 226; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 16, this._ctx) ) { case 1: _localctx = new ConstantDefaultContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 217; + this.state = 219; this.constant(); } break; @@ -1026,7 +1025,7 @@ export class esql_parser extends Parser { _localctx = new DereferenceContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 218; + this.state = 220; this.qualifiedName(); } break; @@ -1035,7 +1034,7 @@ export class esql_parser extends Parser { _localctx = new FunctionContext(_localctx); this.enterOuterAlt(_localctx, 3); { - this.state = 219; + this.state = 221; this.functionExpression(); } break; @@ -1044,11 +1043,11 @@ export class esql_parser extends Parser { _localctx = new ParenthesizedExpressionContext(_localctx); this.enterOuterAlt(_localctx, 4); { - this.state = 220; + this.state = 222; this.match(esql_parser.LP); - this.state = 221; + this.state = 223; this.booleanExpression(0); - this.state = 222; + this.state = 224; this.match(esql_parser.RP); } break; @@ -1076,16 +1075,16 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 226; + this.state = 228; this.identifier(); - this.state = 227; + this.state = 229; this.match(esql_parser.LP); - this.state = 237; + this.state = 239; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.ASTERISK: { - this.state = 228; + this.state = 230; this.match(esql_parser.ASTERISK); } break; @@ -1105,21 +1104,21 @@ export class esql_parser extends Parser { case esql_parser.QUOTED_IDENTIFIER: { { - this.state = 229; + this.state = 231; this.booleanExpression(0); - this.state = 234; + this.state = 236; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 230; + this.state = 232; this.match(esql_parser.COMMA); - this.state = 231; + this.state = 233; this.booleanExpression(0); } } - this.state = 236; + this.state = 238; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -1131,7 +1130,7 @@ export class esql_parser extends Parser { default: break; } - this.state = 239; + this.state = 241; this.match(esql_parser.RP); } } @@ -1156,9 +1155,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 241; + this.state = 243; this.match(esql_parser.ROW); - this.state = 242; + this.state = 244; this.fields(); } } @@ -1184,23 +1183,23 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 244; + this.state = 246; this.field(); - this.state = 249; + this.state = 251; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 19, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 245; + this.state = 247; this.match(esql_parser.COMMA); - this.state = 246; + this.state = 248; this.field(); } } } - this.state = 251; + this.state = 253; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 19, this._ctx); } @@ -1225,13 +1224,13 @@ export class esql_parser extends Parser { let _localctx: FieldContext = new FieldContext(this._ctx, this.state); this.enterRule(_localctx, 26, esql_parser.RULE_field); try { - this.state = 257; + this.state = 259; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 20, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 252; + this.state = 254; this.booleanExpression(0); } break; @@ -1239,11 +1238,11 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 253; + this.state = 255; this.qualifiedName(); - this.state = 254; + this.state = 256; this.match(esql_parser.ASSIGN); - this.state = 255; + this.state = 257; this.booleanExpression(0); } break; @@ -1271,34 +1270,34 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 259; + this.state = 261; this.match(esql_parser.FROM); - this.state = 260; + this.state = 262; this.fromIdentifier(); - this.state = 265; + this.state = 267; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 21, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 261; + this.state = 263; this.match(esql_parser.COMMA); - this.state = 262; + this.state = 264; this.fromIdentifier(); } } } - this.state = 267; + this.state = 269; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 21, this._ctx); } - this.state = 269; + this.state = 271; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 22, this._ctx) ) { case 1: { - this.state = 268; + this.state = 270; this.metadata(); } break; @@ -1323,33 +1322,100 @@ export class esql_parser extends Parser { public metadata(): MetadataContext { let _localctx: MetadataContext = new MetadataContext(this._ctx, this.state); this.enterRule(_localctx, 30, esql_parser.RULE_metadata); - let _la: number; try { - this.enterOuterAlt(_localctx, 1); - { - this.state = 271; - this.match(esql_parser.OPENING_BRACKET); - this.state = 272; - this.match(esql_parser.METADATA); - this.state = 273; - this.fromIdentifier(); - this.state = 278; + this.state = 275; this._errHandler.sync(this); - _la = this._input.LA(1); - while (_la === esql_parser.COMMA) { + switch (this._input.LA(1)) { + case esql_parser.METADATA: + this.enterOuterAlt(_localctx, 1); { + this.state = 273; + this.metadataOption(); + } + break; + case esql_parser.OPENING_BRACKET: + this.enterOuterAlt(_localctx, 2); { this.state = 274; - this.match(esql_parser.COMMA); - this.state = 275; - this.fromIdentifier(); + this.deprecated_metadata(); } + break; + default: + throw new NoViableAltException(this); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public metadataOption(): MetadataOptionContext { + let _localctx: MetadataOptionContext = new MetadataOptionContext(this._ctx, this.state); + this.enterRule(_localctx, 32, esql_parser.RULE_metadataOption); + try { + let _alt: number; + this.enterOuterAlt(_localctx, 1); + { + this.state = 277; + this.match(esql_parser.METADATA); + this.state = 278; + this.fromIdentifier(); + this.state = 283; + this._errHandler.sync(this); + _alt = this.interpreter.adaptivePredict(this._input, 24, this._ctx); + while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { + if (_alt === 1) { + { + { + this.state = 279; + this.match(esql_parser.COMMA); + this.state = 280; + this.fromIdentifier(); + } + } } - this.state = 280; + this.state = 285; this._errHandler.sync(this); - _la = this._input.LA(1); + _alt = this.interpreter.adaptivePredict(this._input, 24, this._ctx); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; } - this.state = 281; + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public deprecated_metadata(): Deprecated_metadataContext { + let _localctx: Deprecated_metadataContext = new Deprecated_metadataContext(this._ctx, this.state); + this.enterRule(_localctx, 34, esql_parser.RULE_deprecated_metadata); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 286; + this.match(esql_parser.OPENING_BRACKET); + this.state = 287; + this.metadataOption(); + this.state = 288; this.match(esql_parser.CLOSING_BRACKET); } } @@ -1370,13 +1436,13 @@ export class esql_parser extends Parser { // @RuleVersion(0) public evalCommand(): EvalCommandContext { let _localctx: EvalCommandContext = new EvalCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 32, esql_parser.RULE_evalCommand); + this.enterRule(_localctx, 36, esql_parser.RULE_evalCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 283; + this.state = 290; this.match(esql_parser.EVAL); - this.state = 284; + this.state = 291; this.fields(); } } @@ -1397,30 +1463,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public statsCommand(): StatsCommandContext { let _localctx: StatsCommandContext = new StatsCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 34, esql_parser.RULE_statsCommand); + this.enterRule(_localctx, 38, esql_parser.RULE_statsCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 286; + this.state = 293; this.match(esql_parser.STATS); - this.state = 288; + this.state = 295; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 24, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 25, this._ctx) ) { case 1: { - this.state = 287; + this.state = 294; _localctx._stats = this.fields(); } break; } - this.state = 292; + this.state = 299; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 25, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 26, this._ctx) ) { case 1: { - this.state = 290; + this.state = 297; this.match(esql_parser.BY); - this.state = 291; + this.state = 298; _localctx._grouping = this.fields(); } break; @@ -1444,22 +1510,22 @@ export class esql_parser extends Parser { // @RuleVersion(0) public inlinestatsCommand(): InlinestatsCommandContext { let _localctx: InlinestatsCommandContext = new InlinestatsCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 36, esql_parser.RULE_inlinestatsCommand); + this.enterRule(_localctx, 40, esql_parser.RULE_inlinestatsCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 294; + this.state = 301; this.match(esql_parser.INLINESTATS); - this.state = 295; + this.state = 302; _localctx._stats = this.fields(); - this.state = 298; + this.state = 305; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 26, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 27, this._ctx) ) { case 1: { - this.state = 296; + this.state = 303; this.match(esql_parser.BY); - this.state = 297; + this.state = 304; _localctx._grouping = this.fields(); } break; @@ -1483,12 +1549,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public fromIdentifier(): FromIdentifierContext { let _localctx: FromIdentifierContext = new FromIdentifierContext(this._ctx, this.state); - this.enterRule(_localctx, 38, esql_parser.RULE_fromIdentifier); + this.enterRule(_localctx, 42, esql_parser.RULE_fromIdentifier); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 300; + this.state = 307; _la = this._input.LA(1); if (!(_la === esql_parser.QUOTED_IDENTIFIER || _la === esql_parser.FROM_UNQUOTED_IDENTIFIER)) { this._errHandler.recoverInline(this); @@ -1519,30 +1585,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public qualifiedName(): QualifiedNameContext { let _localctx: QualifiedNameContext = new QualifiedNameContext(this._ctx, this.state); - this.enterRule(_localctx, 40, esql_parser.RULE_qualifiedName); + this.enterRule(_localctx, 44, esql_parser.RULE_qualifiedName); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 302; + this.state = 309; this.identifier(); - this.state = 307; + this.state = 314; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 303; + this.state = 310; this.match(esql_parser.DOT); - this.state = 304; + this.state = 311; this.identifier(); } } } - this.state = 309; + this.state = 316; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); } } } @@ -1563,30 +1629,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public qualifiedNamePattern(): QualifiedNamePatternContext { let _localctx: QualifiedNamePatternContext = new QualifiedNamePatternContext(this._ctx, this.state); - this.enterRule(_localctx, 42, esql_parser.RULE_qualifiedNamePattern); + this.enterRule(_localctx, 46, esql_parser.RULE_qualifiedNamePattern); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 310; + this.state = 317; this.identifierPattern(); - this.state = 315; + this.state = 322; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 29, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 311; + this.state = 318; this.match(esql_parser.DOT); - this.state = 312; + this.state = 319; this.identifierPattern(); } } } - this.state = 317; + this.state = 324; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 29, this._ctx); } } } @@ -1607,12 +1673,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public identifier(): IdentifierContext { let _localctx: IdentifierContext = new IdentifierContext(this._ctx, this.state); - this.enterRule(_localctx, 44, esql_parser.RULE_identifier); + this.enterRule(_localctx, 48, esql_parser.RULE_identifier); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 318; + this.state = 325; _la = this._input.LA(1); if (!(_la === esql_parser.UNQUOTED_IDENTIFIER || _la === esql_parser.QUOTED_IDENTIFIER)) { this._errHandler.recoverInline(this); @@ -1643,12 +1709,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public identifierPattern(): IdentifierPatternContext { let _localctx: IdentifierPatternContext = new IdentifierPatternContext(this._ctx, this.state); - this.enterRule(_localctx, 46, esql_parser.RULE_identifierPattern); + this.enterRule(_localctx, 50, esql_parser.RULE_identifierPattern); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 320; + this.state = 327; _la = this._input.LA(1); if (!(_la === esql_parser.QUOTED_IDENTIFIER || _la === esql_parser.UNQUOTED_ID_PATTERN)) { this._errHandler.recoverInline(this); @@ -1679,17 +1745,17 @@ export class esql_parser extends Parser { // @RuleVersion(0) public constant(): ConstantContext { let _localctx: ConstantContext = new ConstantContext(this._ctx, this.state); - this.enterRule(_localctx, 48, esql_parser.RULE_constant); + this.enterRule(_localctx, 52, esql_parser.RULE_constant); let _la: number; try { - this.state = 364; + this.state = 371; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 32, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 33, this._ctx) ) { case 1: _localctx = new NullLiteralContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 322; + this.state = 329; this.match(esql_parser.NULL); } break; @@ -1698,9 +1764,9 @@ export class esql_parser extends Parser { _localctx = new QualifiedIntegerLiteralContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 323; + this.state = 330; this.integerValue(); - this.state = 324; + this.state = 331; this.match(esql_parser.UNQUOTED_IDENTIFIER); } break; @@ -1709,7 +1775,7 @@ export class esql_parser extends Parser { _localctx = new DecimalLiteralContext(_localctx); this.enterOuterAlt(_localctx, 3); { - this.state = 326; + this.state = 333; this.decimalValue(); } break; @@ -1718,7 +1784,7 @@ export class esql_parser extends Parser { _localctx = new IntegerLiteralContext(_localctx); this.enterOuterAlt(_localctx, 4); { - this.state = 327; + this.state = 334; this.integerValue(); } break; @@ -1727,7 +1793,7 @@ export class esql_parser extends Parser { _localctx = new BooleanLiteralContext(_localctx); this.enterOuterAlt(_localctx, 5); { - this.state = 328; + this.state = 335; this.booleanValue(); } break; @@ -1736,7 +1802,7 @@ export class esql_parser extends Parser { _localctx = new InputParamContext(_localctx); this.enterOuterAlt(_localctx, 6); { - this.state = 329; + this.state = 336; this.match(esql_parser.PARAM); } break; @@ -1745,7 +1811,7 @@ export class esql_parser extends Parser { _localctx = new StringLiteralContext(_localctx); this.enterOuterAlt(_localctx, 7); { - this.state = 330; + this.state = 337; this.string(); } break; @@ -1754,27 +1820,27 @@ export class esql_parser extends Parser { _localctx = new NumericArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 8); { - this.state = 331; + this.state = 338; this.match(esql_parser.OPENING_BRACKET); - this.state = 332; + this.state = 339; this.numericValue(); - this.state = 337; + this.state = 344; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 333; + this.state = 340; this.match(esql_parser.COMMA); - this.state = 334; + this.state = 341; this.numericValue(); } } - this.state = 339; + this.state = 346; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 340; + this.state = 347; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1783,27 +1849,27 @@ export class esql_parser extends Parser { _localctx = new BooleanArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 9); { - this.state = 342; + this.state = 349; this.match(esql_parser.OPENING_BRACKET); - this.state = 343; + this.state = 350; this.booleanValue(); - this.state = 348; + this.state = 355; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 344; + this.state = 351; this.match(esql_parser.COMMA); - this.state = 345; + this.state = 352; this.booleanValue(); } } - this.state = 350; + this.state = 357; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 351; + this.state = 358; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1812,27 +1878,27 @@ export class esql_parser extends Parser { _localctx = new StringArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 10); { - this.state = 353; + this.state = 360; this.match(esql_parser.OPENING_BRACKET); - this.state = 354; + this.state = 361; this.string(); - this.state = 359; + this.state = 366; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 355; + this.state = 362; this.match(esql_parser.COMMA); - this.state = 356; + this.state = 363; this.string(); } } - this.state = 361; + this.state = 368; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 362; + this.state = 369; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1855,13 +1921,13 @@ export class esql_parser extends Parser { // @RuleVersion(0) public limitCommand(): LimitCommandContext { let _localctx: LimitCommandContext = new LimitCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 50, esql_parser.RULE_limitCommand); + this.enterRule(_localctx, 54, esql_parser.RULE_limitCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 366; + this.state = 373; this.match(esql_parser.LIMIT); - this.state = 367; + this.state = 374; this.match(esql_parser.INTEGER_LITERAL); } } @@ -1882,32 +1948,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public sortCommand(): SortCommandContext { let _localctx: SortCommandContext = new SortCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 52, esql_parser.RULE_sortCommand); + this.enterRule(_localctx, 56, esql_parser.RULE_sortCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 369; + this.state = 376; this.match(esql_parser.SORT); - this.state = 370; + this.state = 377; this.orderExpression(); - this.state = 375; + this.state = 382; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 33, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 34, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 371; + this.state = 378; this.match(esql_parser.COMMA); - this.state = 372; + this.state = 379; this.orderExpression(); } } } - this.state = 377; + this.state = 384; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 33, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 34, this._ctx); } } } @@ -1928,19 +1994,19 @@ export class esql_parser extends Parser { // @RuleVersion(0) public orderExpression(): OrderExpressionContext { let _localctx: OrderExpressionContext = new OrderExpressionContext(this._ctx, this.state); - this.enterRule(_localctx, 54, esql_parser.RULE_orderExpression); + this.enterRule(_localctx, 58, esql_parser.RULE_orderExpression); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 378; + this.state = 385; this.booleanExpression(0); - this.state = 380; + this.state = 387; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 34, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 35, this._ctx) ) { case 1: { - this.state = 379; + this.state = 386; _localctx._ordering = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.ASC || _la === esql_parser.DESC)) { @@ -1956,14 +2022,14 @@ export class esql_parser extends Parser { } break; } - this.state = 384; + this.state = 391; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 35, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 36, this._ctx) ) { case 1: { - this.state = 382; + this.state = 389; this.match(esql_parser.NULLS); - this.state = 383; + this.state = 390; _localctx._nullOrdering = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.FIRST || _la === esql_parser.LAST)) { @@ -1998,68 +2064,33 @@ export class esql_parser extends Parser { // @RuleVersion(0) public keepCommand(): KeepCommandContext { let _localctx: KeepCommandContext = new KeepCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 56, esql_parser.RULE_keepCommand); + this.enterRule(_localctx, 60, esql_parser.RULE_keepCommand); try { let _alt: number; - this.state = 404; + this.enterOuterAlt(_localctx, 1); + { + this.state = 393; + this.match(esql_parser.KEEP); + this.state = 394; + this.qualifiedNamePattern(); + this.state = 399; this._errHandler.sync(this); - switch (this._input.LA(1)) { - case esql_parser.KEEP: - this.enterOuterAlt(_localctx, 1); - { - this.state = 386; - this.match(esql_parser.KEEP); - this.state = 387; - this.qualifiedNamePattern(); - this.state = 392; - this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 36, this._ctx); - while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { - if (_alt === 1) { - { - { - this.state = 388; - this.match(esql_parser.COMMA); - this.state = 389; - this.qualifiedNamePattern(); - } - } + _alt = this.interpreter.adaptivePredict(this._input, 37, this._ctx); + while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { + if (_alt === 1) { + { + { + this.state = 395; + this.match(esql_parser.COMMA); + this.state = 396; + this.qualifiedNamePattern(); + } } - this.state = 394; - this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 36, this._ctx); - } } - break; - case esql_parser.PROJECT: - this.enterOuterAlt(_localctx, 2); - { - this.state = 395; - this.match(esql_parser.PROJECT); - this.state = 396; - this.qualifiedNamePattern(); this.state = 401; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 37, this._ctx); - while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { - if (_alt === 1) { - { - { - this.state = 397; - this.match(esql_parser.COMMA); - this.state = 398; - this.qualifiedNamePattern(); - } - } - } - this.state = 403; - this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 37, this._ctx); - } - } - break; - default: - throw new NoViableAltException(this); + } } } catch (re) { @@ -2079,32 +2110,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public dropCommand(): DropCommandContext { let _localctx: DropCommandContext = new DropCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 58, esql_parser.RULE_dropCommand); + this.enterRule(_localctx, 62, esql_parser.RULE_dropCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 406; + this.state = 402; this.match(esql_parser.DROP); - this.state = 407; + this.state = 403; this.qualifiedNamePattern(); - this.state = 412; + this.state = 408; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 408; + this.state = 404; this.match(esql_parser.COMMA); - this.state = 409; + this.state = 405; this.qualifiedNamePattern(); } } } - this.state = 414; + this.state = 410; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); } } } @@ -2125,32 +2156,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public renameCommand(): RenameCommandContext { let _localctx: RenameCommandContext = new RenameCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 60, esql_parser.RULE_renameCommand); + this.enterRule(_localctx, 64, esql_parser.RULE_renameCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 415; + this.state = 411; this.match(esql_parser.RENAME); - this.state = 416; + this.state = 412; this.renameClause(); - this.state = 421; + this.state = 417; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 40, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 417; + this.state = 413; this.match(esql_parser.COMMA); - this.state = 418; + this.state = 414; this.renameClause(); } } } - this.state = 423; + this.state = 419; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 40, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); } } } @@ -2171,15 +2202,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public renameClause(): RenameClauseContext { let _localctx: RenameClauseContext = new RenameClauseContext(this._ctx, this.state); - this.enterRule(_localctx, 62, esql_parser.RULE_renameClause); + this.enterRule(_localctx, 66, esql_parser.RULE_renameClause); try { this.enterOuterAlt(_localctx, 1); { - this.state = 424; + this.state = 420; _localctx._oldName = this.qualifiedNamePattern(); - this.state = 425; + this.state = 421; this.match(esql_parser.AS); - this.state = 426; + this.state = 422; _localctx._newName = this.qualifiedNamePattern(); } } @@ -2200,22 +2231,22 @@ export class esql_parser extends Parser { // @RuleVersion(0) public dissectCommand(): DissectCommandContext { let _localctx: DissectCommandContext = new DissectCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 64, esql_parser.RULE_dissectCommand); + this.enterRule(_localctx, 68, esql_parser.RULE_dissectCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 428; + this.state = 424; this.match(esql_parser.DISSECT); - this.state = 429; + this.state = 425; this.primaryExpression(); - this.state = 430; + this.state = 426; this.string(); - this.state = 432; + this.state = 428; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 41, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 40, this._ctx) ) { case 1: { - this.state = 431; + this.state = 427; this.commandOptions(); } break; @@ -2239,15 +2270,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public grokCommand(): GrokCommandContext { let _localctx: GrokCommandContext = new GrokCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 66, esql_parser.RULE_grokCommand); + this.enterRule(_localctx, 70, esql_parser.RULE_grokCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 434; + this.state = 430; this.match(esql_parser.GROK); - this.state = 435; + this.state = 431; this.primaryExpression(); - this.state = 436; + this.state = 432; this.string(); } } @@ -2268,13 +2299,13 @@ export class esql_parser extends Parser { // @RuleVersion(0) public mvExpandCommand(): MvExpandCommandContext { let _localctx: MvExpandCommandContext = new MvExpandCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 68, esql_parser.RULE_mvExpandCommand); + this.enterRule(_localctx, 72, esql_parser.RULE_mvExpandCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 438; + this.state = 434; this.match(esql_parser.MV_EXPAND); - this.state = 439; + this.state = 435; this.qualifiedName(); } } @@ -2295,30 +2326,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public commandOptions(): CommandOptionsContext { let _localctx: CommandOptionsContext = new CommandOptionsContext(this._ctx, this.state); - this.enterRule(_localctx, 70, esql_parser.RULE_commandOptions); + this.enterRule(_localctx, 74, esql_parser.RULE_commandOptions); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 441; + this.state = 437; this.commandOption(); - this.state = 446; + this.state = 442; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 42, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 442; + this.state = 438; this.match(esql_parser.COMMA); - this.state = 443; + this.state = 439; this.commandOption(); } } } - this.state = 448; + this.state = 444; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 42, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); } } } @@ -2339,15 +2370,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public commandOption(): CommandOptionContext { let _localctx: CommandOptionContext = new CommandOptionContext(this._ctx, this.state); - this.enterRule(_localctx, 72, esql_parser.RULE_commandOption); + this.enterRule(_localctx, 76, esql_parser.RULE_commandOption); try { this.enterOuterAlt(_localctx, 1); { - this.state = 449; + this.state = 445; this.identifier(); - this.state = 450; + this.state = 446; this.match(esql_parser.ASSIGN); - this.state = 451; + this.state = 447; this.constant(); } } @@ -2368,12 +2399,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public booleanValue(): BooleanValueContext { let _localctx: BooleanValueContext = new BooleanValueContext(this._ctx, this.state); - this.enterRule(_localctx, 74, esql_parser.RULE_booleanValue); + this.enterRule(_localctx, 78, esql_parser.RULE_booleanValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 453; + this.state = 449; _la = this._input.LA(1); if (!(_la === esql_parser.FALSE || _la === esql_parser.TRUE)) { this._errHandler.recoverInline(this); @@ -2404,15 +2435,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public numericValue(): NumericValueContext { let _localctx: NumericValueContext = new NumericValueContext(this._ctx, this.state); - this.enterRule(_localctx, 76, esql_parser.RULE_numericValue); + this.enterRule(_localctx, 80, esql_parser.RULE_numericValue); try { - this.state = 457; + this.state = 453; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 43, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 42, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 455; + this.state = 451; this.decimalValue(); } break; @@ -2420,7 +2451,7 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 456; + this.state = 452; this.integerValue(); } break; @@ -2443,17 +2474,17 @@ export class esql_parser extends Parser { // @RuleVersion(0) public decimalValue(): DecimalValueContext { let _localctx: DecimalValueContext = new DecimalValueContext(this._ctx, this.state); - this.enterRule(_localctx, 78, esql_parser.RULE_decimalValue); + this.enterRule(_localctx, 82, esql_parser.RULE_decimalValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 460; + this.state = 456; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.PLUS || _la === esql_parser.MINUS) { { - this.state = 459; + this.state = 455; _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { this._errHandler.recoverInline(this); @@ -2468,7 +2499,7 @@ export class esql_parser extends Parser { } } - this.state = 462; + this.state = 458; this.match(esql_parser.DECIMAL_LITERAL); } } @@ -2489,17 +2520,17 @@ export class esql_parser extends Parser { // @RuleVersion(0) public integerValue(): IntegerValueContext { let _localctx: IntegerValueContext = new IntegerValueContext(this._ctx, this.state); - this.enterRule(_localctx, 80, esql_parser.RULE_integerValue); + this.enterRule(_localctx, 84, esql_parser.RULE_integerValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 465; + this.state = 461; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.PLUS || _la === esql_parser.MINUS) { { - this.state = 464; + this.state = 460; _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { this._errHandler.recoverInline(this); @@ -2514,7 +2545,7 @@ export class esql_parser extends Parser { } } - this.state = 467; + this.state = 463; this.match(esql_parser.INTEGER_LITERAL); } } @@ -2535,11 +2566,11 @@ export class esql_parser extends Parser { // @RuleVersion(0) public string(): StringContext { let _localctx: StringContext = new StringContext(this._ctx, this.state); - this.enterRule(_localctx, 82, esql_parser.RULE_string); + this.enterRule(_localctx, 86, esql_parser.RULE_string); try { this.enterOuterAlt(_localctx, 1); { - this.state = 469; + this.state = 465; this.match(esql_parser.STRING); } } @@ -2560,14 +2591,14 @@ export class esql_parser extends Parser { // @RuleVersion(0) public comparisonOperator(): ComparisonOperatorContext { let _localctx: ComparisonOperatorContext = new ComparisonOperatorContext(this._ctx, this.state); - this.enterRule(_localctx, 84, esql_parser.RULE_comparisonOperator); + this.enterRule(_localctx, 88, esql_parser.RULE_comparisonOperator); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 471; + this.state = 467; _la = this._input.LA(1); - if (!(((((_la - 52)) & ~0x1F) === 0 && ((1 << (_la - 52)) & ((1 << (esql_parser.EQ - 52)) | (1 << (esql_parser.CIEQ - 52)) | (1 << (esql_parser.NEQ - 52)) | (1 << (esql_parser.LT - 52)) | (1 << (esql_parser.LTE - 52)) | (1 << (esql_parser.GT - 52)) | (1 << (esql_parser.GTE - 52)))) !== 0))) { + if (!(((((_la - 51)) & ~0x1F) === 0 && ((1 << (_la - 51)) & ((1 << (esql_parser.EQ - 51)) | (1 << (esql_parser.CIEQ - 51)) | (1 << (esql_parser.NEQ - 51)) | (1 << (esql_parser.LT - 51)) | (1 << (esql_parser.LTE - 51)) | (1 << (esql_parser.GT - 51)) | (1 << (esql_parser.GTE - 51)))) !== 0))) { this._errHandler.recoverInline(this); } else { if (this._input.LA(1) === Token.EOF) { @@ -2596,13 +2627,13 @@ export class esql_parser extends Parser { // @RuleVersion(0) public explainCommand(): ExplainCommandContext { let _localctx: ExplainCommandContext = new ExplainCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 86, esql_parser.RULE_explainCommand); + this.enterRule(_localctx, 90, esql_parser.RULE_explainCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 473; + this.state = 469; this.match(esql_parser.EXPLAIN); - this.state = 474; + this.state = 470; this.subqueryExpression(); } } @@ -2623,15 +2654,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public subqueryExpression(): SubqueryExpressionContext { let _localctx: SubqueryExpressionContext = new SubqueryExpressionContext(this._ctx, this.state); - this.enterRule(_localctx, 88, esql_parser.RULE_subqueryExpression); + this.enterRule(_localctx, 92, esql_parser.RULE_subqueryExpression); try { this.enterOuterAlt(_localctx, 1); { - this.state = 476; + this.state = 472; this.match(esql_parser.OPENING_BRACKET); - this.state = 477; + this.state = 473; this.query(0); - this.state = 478; + this.state = 474; this.match(esql_parser.CLOSING_BRACKET); } } @@ -2652,18 +2683,18 @@ export class esql_parser extends Parser { // @RuleVersion(0) public showCommand(): ShowCommandContext { let _localctx: ShowCommandContext = new ShowCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 90, esql_parser.RULE_showCommand); + this.enterRule(_localctx, 94, esql_parser.RULE_showCommand); try { - this.state = 484; + this.state = 480; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 46, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 45, this._ctx) ) { case 1: _localctx = new ShowInfoContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 480; + this.state = 476; this.match(esql_parser.SHOW); - this.state = 481; + this.state = 477; this.match(esql_parser.INFO); } break; @@ -2672,9 +2703,9 @@ export class esql_parser extends Parser { _localctx = new ShowFunctionsContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 482; + this.state = 478; this.match(esql_parser.SHOW); - this.state = 483; + this.state = 479; this.match(esql_parser.FUNCTIONS); } break; @@ -2697,68 +2728,53 @@ export class esql_parser extends Parser { // @RuleVersion(0) public enrichCommand(): EnrichCommandContext { let _localctx: EnrichCommandContext = new EnrichCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 92, esql_parser.RULE_enrichCommand); - let _la: number; + this.enterRule(_localctx, 96, esql_parser.RULE_enrichCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 486; + this.state = 482; this.match(esql_parser.ENRICH); - this.state = 490; - this._errHandler.sync(this); - _la = this._input.LA(1); - while (_la === esql_parser.OPENING_BRACKET) { - { - { - this.state = 487; - this.setting(); - } - } - this.state = 492; - this._errHandler.sync(this); - _la = this._input.LA(1); - } - this.state = 493; + this.state = 483; _localctx._policyName = this.match(esql_parser.ENRICH_POLICY_NAME); - this.state = 496; + this.state = 486; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 48, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 46, this._ctx) ) { case 1: { - this.state = 494; + this.state = 484; this.match(esql_parser.ON); - this.state = 495; + this.state = 485; _localctx._matchField = this.qualifiedNamePattern(); } break; } - this.state = 507; + this.state = 497; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 50, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 48, this._ctx) ) { case 1: { - this.state = 498; + this.state = 488; this.match(esql_parser.WITH); - this.state = 499; + this.state = 489; this.enrichWithClause(); - this.state = 504; + this.state = 494; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 49, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 47, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 500; + this.state = 490; this.match(esql_parser.COMMA); - this.state = 501; + this.state = 491; this.enrichWithClause(); } } } - this.state = 506; + this.state = 496; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 49, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 47, this._ctx); } } break; @@ -2782,23 +2798,23 @@ export class esql_parser extends Parser { // @RuleVersion(0) public enrichWithClause(): EnrichWithClauseContext { let _localctx: EnrichWithClauseContext = new EnrichWithClauseContext(this._ctx, this.state); - this.enterRule(_localctx, 94, esql_parser.RULE_enrichWithClause); + this.enterRule(_localctx, 98, esql_parser.RULE_enrichWithClause); try { this.enterOuterAlt(_localctx, 1); { - this.state = 512; + this.state = 502; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 51, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 49, this._ctx) ) { case 1: { - this.state = 509; + this.state = 499; _localctx._newName = this.qualifiedNamePattern(); - this.state = 510; + this.state = 500; this.match(esql_parser.ASSIGN); } break; } - this.state = 514; + this.state = 504; _localctx._enrichField = this.qualifiedNamePattern(); } } @@ -2816,39 +2832,6 @@ export class esql_parser extends Parser { } return _localctx; } - // @RuleVersion(0) - public setting(): SettingContext { - let _localctx: SettingContext = new SettingContext(this._ctx, this.state); - this.enterRule(_localctx, 96, esql_parser.RULE_setting); - try { - this.enterOuterAlt(_localctx, 1); - { - this.state = 516; - this.match(esql_parser.OPENING_BRACKET); - this.state = 517; - _localctx._name = this.match(esql_parser.SETTING); - this.state = 518; - this.match(esql_parser.COLON); - this.state = 519; - _localctx._value = this.match(esql_parser.SETTING); - this.state = 520; - this.match(esql_parser.CLOSING_BRACKET); - } - } - catch (re) { - if (re instanceof RecognitionException) { - _localctx.exception = re; - this._errHandler.reportError(this, re); - this._errHandler.recover(this, re); - } else { - throw re; - } - } - finally { - this.exitRule(); - } - return _localctx; - } public sempred(_localctx: RuleContext, ruleIndex: number, predIndex: number): boolean { switch (ruleIndex) { @@ -2892,7 +2875,7 @@ export class esql_parser extends Parser { } public static readonly _serializedATN: string = - "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03k\u020D\x04\x02" + + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03j\u01FD\x04\x02" + "\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07" + "\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r\x04" + "\x0E\t\x0E\x04\x0F\t\x0F\x04\x10\t\x10\x04\x11\t\x11\x04\x12\t\x12\x04" + @@ -2900,251 +2883,242 @@ export class esql_parser extends Parser { "\x18\t\x18\x04\x19\t\x19\x04\x1A\t\x1A\x04\x1B\t\x1B\x04\x1C\t\x1C\x04" + "\x1D\t\x1D\x04\x1E\t\x1E\x04\x1F\t\x1F\x04 \t \x04!\t!\x04\"\t\"\x04#" + "\t#\x04$\t$\x04%\t%\x04&\t&\x04\'\t\'\x04(\t(\x04)\t)\x04*\t*\x04+\t+" + - "\x04,\t,\x04-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x042\t2\x03\x02\x03\x02" + - "\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x07\x03n\n\x03" + - "\f\x03\x0E\x03q\v\x03\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04w\n\x04\x03" + - "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" + - "\x05\x03\x05\x03\x05\x03\x05\x05\x05\x86\n\x05\x03\x06\x03\x06\x03\x06" + - "\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07\x92\n" + - "\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x07\x07\x99\n\x07\f\x07\x0E" + - "\x07\x9C\v\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07\xA3\n\x07" + - "\x03\x07\x03\x07\x05\x07\xA7\n\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03" + - "\x07\x03\x07\x07\x07\xAF\n\x07\f\x07\x0E\x07\xB2\v\x07\x03\b\x03\b\x05" + - "\b\xB6\n\b\x03\b\x03\b\x03\b\x03\b\x03\b\x05\b\xBD\n\b\x03\b\x03\b\x03" + - "\b\x05\b\xC2\n\b\x03\t\x03\t\x03\t\x03\t\x03\t\x05\t\xC9\n\t\x03\n\x03" + - "\n\x03\n\x03\n\x05\n\xCF\n\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x07\n" + - "\xD7\n\n\f\n\x0E\n\xDA\v\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x05" + - "\v\xE3\n\v\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x07\f\xEB\n\f\f\f\x0E\f" + - "\xEE\v\f\x05\f\xF0\n\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\x0E\x03\x0E\x03" + - "\x0E\x07\x0E\xFA\n\x0E\f\x0E\x0E\x0E\xFD\v\x0E\x03\x0F\x03\x0F\x03\x0F" + - "\x03\x0F\x03\x0F\x05\x0F\u0104\n\x0F\x03\x10\x03\x10\x03\x10\x03\x10\x07" + - "\x10\u010A\n\x10\f\x10\x0E\x10\u010D\v\x10\x03\x10\x05\x10\u0110\n\x10" + - "\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x07\x11\u0117\n\x11\f\x11\x0E" + - "\x11\u011A\v\x11\x03\x11\x03\x11\x03\x12\x03\x12\x03\x12\x03\x13\x03\x13" + - "\x05\x13\u0123\n\x13\x03\x13\x03\x13\x05\x13\u0127\n\x13\x03\x14\x03\x14" + - "\x03\x14\x03\x14\x05\x14\u012D\n\x14\x03\x15\x03\x15\x03\x16\x03\x16\x03" + - "\x16\x07\x16\u0134\n\x16\f\x16\x0E\x16\u0137\v\x16\x03\x17\x03\x17\x03" + - "\x17\x07\x17\u013C\n\x17\f\x17\x0E\x17\u013F\v\x17\x03\x18\x03\x18\x03" + - "\x19\x03\x19\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03" + - "\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x07\x1A\u0152\n\x1A\f\x1A" + - "\x0E\x1A\u0155\v\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x07" + - "\x1A\u015D\n\x1A\f\x1A\x0E\x1A\u0160\v\x1A\x03\x1A\x03\x1A\x03\x1A\x03" + - "\x1A\x03\x1A\x03\x1A\x07\x1A\u0168\n\x1A\f\x1A\x0E\x1A\u016B\v\x1A\x03" + - "\x1A\x03\x1A\x05\x1A\u016F\n\x1A\x03\x1B\x03\x1B\x03\x1B\x03\x1C\x03\x1C" + - "\x03\x1C\x03\x1C\x07\x1C\u0178\n\x1C\f\x1C\x0E\x1C\u017B\v\x1C\x03\x1D" + - "\x03\x1D\x05\x1D\u017F\n\x1D\x03\x1D\x03\x1D\x05\x1D\u0183\n\x1D\x03\x1E" + - "\x03\x1E\x03\x1E\x03\x1E\x07\x1E\u0189\n\x1E\f\x1E\x0E\x1E\u018C\v\x1E" + - "\x03\x1E\x03\x1E\x03\x1E\x03\x1E\x07\x1E\u0192\n\x1E\f\x1E\x0E\x1E\u0195" + - "\v\x1E\x05\x1E\u0197\n\x1E\x03\x1F\x03\x1F\x03\x1F\x03\x1F\x07\x1F\u019D" + - "\n\x1F\f\x1F\x0E\x1F\u01A0\v\x1F\x03 \x03 \x03 \x03 \x07 \u01A6\n \f " + - "\x0E \u01A9\v \x03!\x03!\x03!\x03!\x03\"\x03\"\x03\"\x03\"\x05\"\u01B3" + - "\n\"\x03#\x03#\x03#\x03#\x03$\x03$\x03$\x03%\x03%\x03%\x07%\u01BF\n%\f" + - "%\x0E%\u01C2\v%\x03&\x03&\x03&\x03&\x03\'\x03\'\x03(\x03(\x05(\u01CC\n" + - "(\x03)\x05)\u01CF\n)\x03)\x03)\x03*\x05*\u01D4\n*\x03*\x03*\x03+\x03+" + - "\x03,\x03,\x03-\x03-\x03-\x03.\x03.\x03.\x03.\x03/\x03/\x03/\x03/\x05" + - "/\u01E7\n/\x030\x030\x070\u01EB\n0\f0\x0E0\u01EE\v0\x030\x030\x030\x05" + - "0\u01F3\n0\x030\x030\x030\x030\x070\u01F9\n0\f0\x0E0\u01FC\v0\x050\u01FE" + - "\n0\x031\x031\x031\x051\u0203\n1\x031\x031\x032\x032\x032\x032\x032\x03" + - "2\x032\x02\x02\x05\x04\f\x123\x02\x02\x04\x02\x06\x02\b\x02\n\x02\f\x02" + - "\x0E\x02\x10\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C\x02\x1E\x02" + - " \x02\"\x02$\x02&\x02(\x02*\x02,\x02.\x020\x022\x024\x026\x028\x02:\x02" + - "<\x02>\x02@\x02B\x02D\x02F\x02H\x02J\x02L\x02N\x02P\x02R\x02T\x02V\x02" + - "X\x02Z\x02\\\x02^\x02`\x02b\x02\x02\v\x03\x02=>\x03\x02?A\x04\x02EEJJ" + - "\x03\x02DE\x04\x02EENN\x04\x02\"\"%%\x03\x02()\x04\x02\'\'55\x03\x026" + - "<\x02\u022A\x02d\x03\x02\x02\x02\x04g\x03\x02\x02\x02\x06v\x03\x02\x02" + - "\x02\b\x85\x03\x02\x02\x02\n\x87\x03\x02\x02\x02\f\xA6\x03\x02\x02\x02" + - "\x0E\xC1\x03\x02\x02\x02\x10\xC8\x03\x02\x02\x02\x12\xCE\x03\x02\x02\x02" + - "\x14\xE2\x03\x02\x02\x02\x16\xE4\x03\x02\x02\x02\x18\xF3\x03\x02\x02\x02" + - "\x1A\xF6\x03\x02\x02\x02\x1C\u0103\x03\x02\x02\x02\x1E\u0105\x03\x02\x02" + - "\x02 \u0111\x03\x02\x02\x02\"\u011D\x03\x02\x02\x02$\u0120\x03\x02\x02" + - "\x02&\u0128\x03\x02\x02\x02(\u012E\x03\x02\x02\x02*\u0130\x03\x02\x02" + - "\x02,\u0138\x03\x02\x02\x02.\u0140\x03\x02\x02\x020\u0142\x03\x02\x02" + - "\x022\u016E\x03\x02\x02\x024\u0170\x03\x02\x02\x026\u0173\x03\x02\x02" + - "\x028\u017C\x03\x02\x02\x02:\u0196\x03\x02\x02\x02<\u0198\x03\x02\x02" + - "\x02>\u01A1\x03\x02\x02\x02@\u01AA\x03\x02\x02\x02B\u01AE\x03\x02\x02" + - "\x02D\u01B4\x03\x02\x02\x02F\u01B8\x03\x02\x02\x02H\u01BB\x03\x02\x02" + - "\x02J\u01C3\x03\x02\x02\x02L\u01C7\x03\x02\x02\x02N\u01CB\x03\x02\x02" + - "\x02P\u01CE\x03\x02\x02\x02R\u01D3\x03\x02\x02\x02T\u01D7\x03\x02\x02" + - "\x02V\u01D9\x03\x02\x02\x02X\u01DB\x03\x02\x02\x02Z\u01DE\x03\x02\x02" + - "\x02\\\u01E6\x03\x02\x02\x02^\u01E8\x03\x02\x02\x02`\u0202\x03\x02\x02" + - "\x02b\u0206\x03\x02\x02\x02de\x05\x04\x03\x02ef\x07\x02\x02\x03f\x03\x03" + - "\x02\x02\x02gh\b\x03\x01\x02hi\x05\x06\x04\x02io\x03\x02\x02\x02jk\f\x03" + - "\x02\x02kl\x07\x1C\x02\x02ln\x05\b\x05\x02mj\x03\x02\x02\x02nq\x03\x02" + - "\x02\x02om\x03\x02\x02\x02op\x03\x02\x02\x02p\x05\x03\x02\x02\x02qo\x03" + - "\x02\x02\x02rw\x05X-\x02sw\x05\x1E\x10\x02tw\x05\x18\r\x02uw\x05\\/\x02" + - "vr\x03\x02\x02\x02vs\x03\x02\x02\x02vt\x03\x02\x02\x02vu\x03\x02\x02\x02" + - "w\x07\x03\x02\x02\x02x\x86\x05\"\x12\x02y\x86\x05&\x14\x02z\x86\x054\x1B" + - "\x02{\x86\x05:\x1E\x02|\x86\x056\x1C\x02}\x86\x05$\x13\x02~\x86\x05\n" + - "\x06\x02\x7F\x86\x05<\x1F\x02\x80\x86\x05> \x02\x81\x86\x05B\"\x02\x82" + - "\x86\x05D#\x02\x83\x86\x05^0\x02\x84\x86\x05F$\x02\x85x\x03\x02\x02\x02" + - "\x85y\x03\x02\x02\x02\x85z\x03\x02\x02\x02\x85{\x03\x02\x02\x02\x85|\x03" + - "\x02\x02\x02\x85}\x03\x02\x02\x02\x85~\x03\x02\x02\x02\x85\x7F\x03\x02" + - "\x02\x02\x85\x80\x03\x02\x02\x02\x85\x81\x03\x02\x02\x02\x85\x82\x03\x02" + - "\x02\x02\x85\x83\x03\x02\x02\x02\x85\x84\x03\x02\x02\x02\x86\t\x03\x02" + - "\x02\x02\x87\x88\x07\x14\x02\x02\x88\x89\x05\f\x07\x02\x89\v\x03\x02\x02" + - "\x02\x8A\x8B\b\x07\x01\x02\x8B\x8C\x07.\x02\x02\x8C\xA7\x05\f\x07\t\x8D" + - "\xA7\x05\x10\t\x02\x8E\xA7\x05\x0E\b\x02\x8F\x91\x05\x10\t\x02\x90\x92" + - "\x07.\x02\x02\x91\x90\x03\x02\x02\x02\x91\x92\x03\x02\x02\x02\x92\x93" + - "\x03\x02\x02\x02\x93\x94\x07+\x02\x02\x94\x95\x07*\x02\x02\x95\x9A\x05" + - "\x10\t\x02\x96\x97\x07$\x02\x02\x97\x99\x05\x10\t\x02\x98\x96\x03\x02" + - "\x02\x02\x99\x9C\x03\x02\x02\x02\x9A\x98\x03\x02\x02\x02\x9A\x9B\x03\x02" + - "\x02\x02\x9B\x9D\x03\x02\x02\x02\x9C\x9A\x03\x02\x02\x02\x9D\x9E\x074" + - "\x02\x02\x9E\xA7\x03\x02\x02\x02\x9F\xA0\x05\x10\t\x02\xA0\xA2\x07,\x02" + - "\x02\xA1\xA3\x07.\x02\x02\xA2\xA1\x03\x02\x02\x02\xA2\xA3\x03\x02\x02" + - "\x02\xA3\xA4\x03\x02\x02\x02\xA4\xA5\x07/\x02\x02\xA5\xA7\x03\x02\x02" + - "\x02\xA6\x8A\x03\x02\x02\x02\xA6\x8D\x03\x02\x02\x02\xA6\x8E\x03\x02\x02" + - "\x02\xA6\x8F\x03\x02\x02\x02\xA6\x9F\x03\x02\x02\x02\xA7\xB0\x03\x02\x02" + - "\x02\xA8\xA9\f\x06\x02\x02\xA9\xAA\x07!\x02\x02\xAA\xAF\x05\f\x07\x07" + - "\xAB\xAC\f\x05\x02\x02\xAC\xAD\x071\x02\x02\xAD\xAF\x05\f\x07\x06\xAE" + - "\xA8\x03\x02\x02\x02\xAE\xAB\x03\x02\x02\x02\xAF\xB2\x03\x02\x02\x02\xB0" + - "\xAE\x03\x02\x02\x02\xB0\xB1\x03\x02\x02\x02\xB1\r\x03\x02\x02\x02\xB2" + - "\xB0\x03\x02\x02\x02\xB3\xB5\x05\x10\t\x02\xB4\xB6\x07.\x02\x02\xB5\xB4" + - "\x03\x02\x02\x02\xB5\xB6\x03\x02\x02\x02\xB6\xB7\x03\x02\x02\x02\xB7\xB8" + - "\x07-\x02\x02\xB8\xB9\x05T+\x02\xB9\xC2\x03\x02\x02\x02\xBA\xBC\x05\x10" + - "\t\x02\xBB\xBD\x07.\x02\x02\xBC\xBB\x03\x02\x02\x02\xBC\xBD\x03\x02\x02" + - "\x02\xBD\xBE\x03\x02\x02\x02\xBE\xBF\x073\x02\x02\xBF\xC0\x05T+\x02\xC0" + - "\xC2\x03\x02\x02\x02\xC1\xB3\x03\x02\x02\x02\xC1\xBA\x03\x02\x02\x02\xC2" + - "\x0F\x03\x02\x02\x02\xC3\xC9\x05\x12\n\x02\xC4\xC5\x05\x12\n\x02\xC5\xC6" + - "\x05V,\x02\xC6\xC7\x05\x12\n\x02\xC7\xC9\x03\x02\x02\x02\xC8\xC3\x03\x02" + - "\x02\x02\xC8\xC4\x03\x02\x02\x02\xC9\x11\x03\x02\x02\x02\xCA\xCB\b\n\x01" + - "\x02\xCB\xCF\x05\x14\v\x02\xCC\xCD\t\x02\x02\x02\xCD\xCF\x05\x12\n\x05" + - "\xCE\xCA\x03\x02\x02\x02\xCE\xCC\x03\x02\x02\x02\xCF\xD8\x03\x02\x02\x02" + - "\xD0\xD1\f\x04\x02\x02\xD1\xD2\t\x03\x02\x02\xD2\xD7\x05\x12\n\x05\xD3" + - "\xD4\f\x03\x02\x02\xD4\xD5\t\x02\x02\x02\xD5\xD7\x05\x12\n\x04\xD6\xD0" + - "\x03\x02\x02\x02\xD6\xD3\x03\x02\x02\x02\xD7\xDA\x03\x02\x02\x02\xD8\xD6" + - "\x03\x02\x02\x02\xD8\xD9\x03\x02\x02\x02\xD9\x13\x03\x02\x02\x02\xDA\xD8" + - "\x03\x02\x02\x02\xDB\xE3\x052\x1A\x02\xDC\xE3\x05*\x16\x02\xDD\xE3\x05" + - "\x16\f\x02\xDE\xDF\x07*\x02\x02\xDF\xE0\x05\f\x07\x02\xE0\xE1\x074\x02" + - "\x02\xE1\xE3\x03\x02\x02\x02\xE2\xDB\x03\x02\x02\x02\xE2\xDC\x03\x02\x02" + - "\x02\xE2\xDD\x03\x02\x02\x02\xE2\xDE\x03\x02\x02\x02\xE3\x15\x03\x02\x02" + - "\x02\xE4\xE5\x05.\x18\x02\xE5\xEF\x07*\x02\x02\xE6\xF0\x07?\x02\x02\xE7" + - "\xEC\x05\f\x07\x02\xE8\xE9\x07$\x02\x02\xE9\xEB\x05\f\x07\x02\xEA\xE8" + - "\x03\x02\x02\x02\xEB\xEE\x03\x02\x02\x02\xEC\xEA\x03\x02\x02\x02\xEC\xED" + - "\x03\x02\x02\x02\xED\xF0\x03\x02\x02\x02\xEE\xEC\x03\x02\x02\x02\xEF\xE6" + - "\x03\x02\x02\x02\xEF\xE7\x03\x02\x02\x02\xEF\xF0\x03\x02\x02\x02\xF0\xF1" + - "\x03\x02\x02\x02\xF1\xF2\x074\x02\x02\xF2\x17\x03\x02\x02\x02\xF3\xF4" + - "\x07\x10\x02\x02\xF4\xF5\x05\x1A\x0E\x02\xF5\x19\x03\x02\x02\x02\xF6\xFB" + - "\x05\x1C\x0F\x02\xF7\xF8\x07$\x02\x02\xF8\xFA\x05\x1C\x0F\x02\xF9\xF7" + - "\x03\x02\x02\x02\xFA\xFD\x03\x02\x02\x02\xFB\xF9\x03\x02\x02\x02\xFB\xFC" + - "\x03\x02\x02\x02\xFC\x1B\x03\x02\x02\x02\xFD\xFB\x03\x02\x02\x02\xFE\u0104" + - "\x05\f\x07\x02\xFF\u0100\x05*\x16\x02\u0100\u0101\x07#\x02\x02\u0101\u0102" + - "\x05\f\x07\x02\u0102\u0104\x03\x02\x02\x02\u0103\xFE\x03\x02\x02\x02\u0103" + - "\xFF\x03\x02\x02\x02\u0104\x1D\x03\x02\x02\x02\u0105\u0106\x07\b\x02\x02" + - "\u0106\u010B\x05(\x15\x02\u0107\u0108\x07$\x02\x02\u0108\u010A\x05(\x15" + - "\x02\u0109\u0107\x03\x02\x02\x02\u010A\u010D\x03\x02\x02\x02\u010B\u0109" + - "\x03\x02\x02\x02\u010B\u010C\x03\x02\x02\x02\u010C\u010F\x03\x02\x02\x02" + - "\u010D\u010B\x03\x02\x02\x02\u010E\u0110\x05 \x11\x02\u010F\u010E\x03" + - "\x02\x02\x02\u010F\u0110\x03\x02\x02\x02\u0110\x1F\x03\x02\x02\x02\u0111" + - "\u0112\x07B\x02\x02\u0112\u0113\x07I\x02\x02\u0113\u0118\x05(\x15\x02" + - "\u0114\u0115\x07$\x02\x02\u0115\u0117\x05(\x15\x02\u0116\u0114\x03\x02" + - "\x02\x02\u0117\u011A\x03\x02\x02\x02\u0118\u0116\x03\x02\x02\x02\u0118" + - "\u0119\x03\x02\x02\x02\u0119\u011B\x03\x02\x02\x02\u011A\u0118\x03\x02" + - "\x02\x02\u011B\u011C\x07C\x02\x02\u011C!\x03\x02\x02\x02\u011D\u011E\x07" + - "\x06\x02\x02\u011E\u011F\x05\x1A\x0E\x02\u011F#\x03\x02\x02\x02\u0120" + - "\u0122\x07\x13\x02\x02\u0121\u0123\x05\x1A\x0E\x02\u0122\u0121\x03\x02" + - "\x02\x02\u0122\u0123\x03\x02\x02\x02\u0123\u0126\x03\x02\x02\x02\u0124" + - "\u0125\x07 \x02\x02\u0125\u0127\x05\x1A\x0E\x02\u0126\u0124\x03\x02\x02" + - "\x02\u0126\u0127\x03\x02\x02\x02\u0127%\x03\x02\x02\x02\u0128\u0129\x07" + - "\n\x02\x02\u0129\u012C\x05\x1A\x0E\x02\u012A\u012B\x07 \x02\x02\u012B" + - "\u012D\x05\x1A\x0E\x02\u012C\u012A\x03\x02\x02\x02\u012C\u012D\x03\x02" + - "\x02\x02\u012D\'\x03\x02\x02\x02\u012E\u012F\t\x04\x02\x02\u012F)\x03" + - "\x02\x02\x02\u0130\u0135\x05.\x18\x02\u0131\u0132\x07&\x02\x02\u0132\u0134" + - "\x05.\x18\x02\u0133\u0131\x03\x02\x02\x02\u0134\u0137\x03\x02\x02\x02" + - "\u0135\u0133\x03\x02\x02\x02\u0135\u0136\x03\x02\x02\x02\u0136+\x03\x02" + - "\x02\x02\u0137\u0135\x03\x02\x02\x02\u0138\u013D\x050\x19\x02\u0139\u013A" + - "\x07&\x02\x02\u013A\u013C\x050\x19\x02\u013B\u0139\x03\x02\x02\x02\u013C" + - "\u013F\x03\x02\x02\x02\u013D\u013B\x03\x02\x02\x02\u013D\u013E\x03\x02" + - "\x02\x02\u013E-\x03\x02\x02\x02\u013F\u013D\x03\x02\x02\x02\u0140\u0141" + - "\t\x05\x02\x02\u0141/\x03\x02\x02\x02\u0142\u0143\t\x06\x02\x02\u0143" + - "1\x03\x02\x02\x02\u0144\u016F\x07/\x02\x02\u0145\u0146\x05R*\x02\u0146" + - "\u0147\x07D\x02\x02\u0147\u016F\x03\x02\x02\x02\u0148\u016F\x05P)\x02" + - "\u0149\u016F\x05R*\x02\u014A\u016F\x05L\'\x02\u014B\u016F\x072\x02\x02" + - "\u014C\u016F\x05T+\x02\u014D\u014E\x07B\x02\x02\u014E\u0153\x05N(\x02" + - "\u014F\u0150\x07$\x02\x02\u0150\u0152\x05N(\x02\u0151\u014F\x03\x02\x02" + - "\x02\u0152\u0155\x03\x02\x02\x02\u0153\u0151\x03\x02\x02\x02\u0153\u0154" + - "\x03\x02\x02\x02\u0154\u0156\x03\x02\x02\x02\u0155\u0153\x03\x02\x02\x02" + - "\u0156\u0157\x07C\x02\x02\u0157\u016F\x03\x02\x02\x02\u0158\u0159\x07" + - "B\x02\x02\u0159\u015E\x05L\'\x02\u015A\u015B\x07$\x02\x02\u015B\u015D" + - "\x05L\'\x02\u015C\u015A\x03\x02\x02\x02\u015D\u0160\x03\x02\x02\x02\u015E" + - "\u015C\x03\x02\x02\x02\u015E\u015F\x03\x02\x02\x02\u015F\u0161\x03\x02" + - "\x02\x02\u0160\u015E\x03\x02\x02\x02\u0161\u0162\x07C\x02\x02\u0162\u016F" + - "\x03\x02\x02\x02\u0163\u0164\x07B\x02\x02\u0164\u0169\x05T+\x02\u0165" + - "\u0166\x07$\x02\x02\u0166\u0168\x05T+\x02\u0167\u0165\x03\x02\x02\x02" + - "\u0168\u016B\x03\x02\x02\x02\u0169\u0167\x03\x02\x02\x02\u0169\u016A\x03" + - "\x02\x02\x02\u016A\u016C\x03\x02\x02\x02\u016B\u0169\x03\x02\x02\x02\u016C" + - "\u016D\x07C\x02\x02\u016D\u016F\x03\x02\x02\x02\u016E\u0144\x03\x02\x02" + - "\x02\u016E\u0145\x03\x02\x02\x02\u016E\u0148\x03\x02\x02\x02\u016E\u0149" + - "\x03\x02\x02\x02\u016E\u014A\x03\x02\x02\x02\u016E\u014B\x03\x02\x02\x02" + - "\u016E\u014C\x03\x02\x02\x02\u016E\u014D\x03\x02\x02\x02\u016E\u0158\x03" + - "\x02\x02\x02\u016E\u0163\x03\x02\x02\x02\u016F3\x03\x02\x02\x02\u0170" + - "\u0171\x07\f\x02\x02\u0171\u0172\x07\x1E\x02\x02\u01725\x03\x02\x02\x02" + - "\u0173\u0174\x07\x12\x02\x02\u0174\u0179\x058\x1D\x02\u0175\u0176\x07" + - "$\x02\x02\u0176\u0178\x058\x1D\x02\u0177\u0175\x03\x02\x02\x02\u0178\u017B" + - "\x03\x02\x02\x02\u0179\u0177\x03\x02\x02\x02\u0179\u017A\x03\x02\x02\x02" + - "\u017A7\x03\x02\x02\x02\u017B\u0179\x03\x02\x02\x02\u017C\u017E\x05\f" + - "\x07\x02\u017D\u017F\t\x07\x02\x02\u017E\u017D\x03\x02\x02\x02\u017E\u017F" + - "\x03\x02\x02\x02\u017F\u0182\x03\x02\x02\x02\u0180\u0181\x070\x02\x02" + - "\u0181\u0183\t\b\x02\x02\u0182\u0180\x03\x02\x02\x02\u0182\u0183\x03\x02" + - "\x02\x02\u01839\x03\x02\x02\x02\u0184\u0185\x07\v\x02\x02\u0185\u018A" + - "\x05,\x17\x02\u0186\u0187\x07$\x02\x02\u0187\u0189\x05,\x17\x02\u0188" + - "\u0186\x03\x02\x02\x02\u0189\u018C\x03\x02\x02\x02\u018A\u0188\x03\x02" + - "\x02\x02\u018A\u018B\x03\x02\x02\x02\u018B\u0197\x03\x02\x02\x02\u018C" + - "\u018A\x03\x02\x02\x02\u018D\u018E\x07\x0E\x02\x02\u018E\u0193\x05,\x17" + - "\x02\u018F\u0190\x07$\x02\x02\u0190\u0192\x05,\x17\x02\u0191\u018F\x03" + - "\x02\x02\x02\u0192\u0195\x03\x02\x02\x02\u0193\u0191\x03\x02\x02\x02\u0193" + - "\u0194\x03\x02\x02\x02\u0194\u0197\x03\x02\x02\x02\u0195\u0193\x03\x02" + - "\x02\x02\u0196\u0184\x03\x02\x02\x02\u0196\u018D\x03\x02\x02\x02\u0197" + - ";\x03\x02\x02\x02\u0198\u0199\x07\x04\x02\x02\u0199\u019E\x05,\x17\x02" + - "\u019A\u019B\x07$\x02\x02\u019B\u019D\x05,\x17\x02\u019C\u019A\x03\x02" + - "\x02\x02\u019D\u01A0\x03\x02\x02\x02\u019E\u019C\x03\x02\x02\x02\u019E" + - "\u019F\x03\x02\x02\x02\u019F=\x03\x02\x02\x02\u01A0\u019E\x03\x02\x02" + - "\x02\u01A1\u01A2\x07\x0F\x02\x02\u01A2\u01A7\x05@!\x02\u01A3\u01A4\x07" + - "$\x02\x02\u01A4\u01A6\x05@!\x02\u01A5\u01A3\x03\x02\x02\x02\u01A6\u01A9" + - "\x03\x02\x02\x02\u01A7\u01A5\x03\x02\x02\x02\u01A7\u01A8\x03\x02\x02\x02" + - "\u01A8?\x03\x02\x02\x02\u01A9\u01A7\x03\x02\x02\x02\u01AA\u01AB\x05,\x17" + - "\x02\u01AB\u01AC\x07R\x02\x02\u01AC\u01AD\x05,\x17\x02\u01ADA\x03\x02" + - "\x02\x02\u01AE\u01AF\x07\x03\x02\x02\u01AF\u01B0\x05\x14\v\x02\u01B0\u01B2" + - "\x05T+\x02\u01B1\u01B3\x05H%\x02\u01B2\u01B1\x03\x02\x02\x02\u01B2\u01B3" + - "\x03\x02\x02\x02\u01B3C\x03\x02\x02\x02\u01B4\u01B5\x07\t\x02\x02\u01B5" + - "\u01B6\x05\x14\v\x02\u01B6\u01B7\x05T+\x02\u01B7E\x03\x02\x02\x02\u01B8" + - "\u01B9\x07\r\x02\x02\u01B9\u01BA\x05*\x16\x02\u01BAG\x03\x02\x02\x02\u01BB" + - "\u01C0\x05J&\x02\u01BC\u01BD\x07$\x02\x02\u01BD\u01BF\x05J&\x02\u01BE" + - "\u01BC\x03\x02\x02\x02\u01BF\u01C2\x03\x02\x02\x02\u01C0\u01BE\x03\x02" + - "\x02\x02\u01C0\u01C1\x03\x02\x02\x02\u01C1I\x03\x02\x02\x02\u01C2\u01C0" + - "\x03\x02\x02\x02\u01C3\u01C4\x05.\x18\x02\u01C4\u01C5\x07#\x02\x02\u01C5" + - "\u01C6\x052\x1A\x02\u01C6K\x03\x02\x02\x02\u01C7\u01C8\t\t\x02\x02\u01C8" + - "M\x03\x02\x02\x02\u01C9\u01CC\x05P)\x02\u01CA\u01CC\x05R*\x02\u01CB\u01C9" + - "\x03\x02\x02\x02\u01CB\u01CA\x03\x02\x02\x02\u01CCO\x03\x02\x02\x02\u01CD" + - "\u01CF\t\x02\x02\x02\u01CE\u01CD\x03\x02\x02\x02\u01CE\u01CF\x03\x02\x02" + - "\x02\u01CF\u01D0\x03\x02\x02\x02\u01D0\u01D1\x07\x1F\x02\x02\u01D1Q\x03" + - "\x02\x02\x02\u01D2\u01D4\t\x02\x02\x02\u01D3\u01D2\x03\x02\x02\x02\u01D3" + - "\u01D4\x03\x02\x02\x02\u01D4\u01D5\x03\x02\x02\x02\u01D5\u01D6\x07\x1E" + - "\x02\x02\u01D6S\x03\x02\x02\x02\u01D7\u01D8\x07\x1D\x02\x02\u01D8U\x03" + - "\x02\x02\x02\u01D9\u01DA\t\n\x02\x02\u01DAW\x03\x02\x02\x02\u01DB\u01DC" + - "\x07\x07\x02\x02\u01DC\u01DD\x05Z.\x02\u01DDY\x03\x02\x02\x02\u01DE\u01DF" + - "\x07B\x02\x02\u01DF\u01E0\x05\x04\x03\x02\u01E0\u01E1\x07C\x02\x02\u01E1" + - "[\x03\x02\x02\x02\u01E2\u01E3\x07\x11\x02\x02\u01E3\u01E7\x07b\x02\x02" + - "\u01E4\u01E5\x07\x11\x02\x02\u01E5\u01E7\x07c\x02\x02\u01E6\u01E2\x03" + - "\x02\x02\x02\u01E6\u01E4\x03\x02\x02\x02\u01E7]\x03\x02\x02\x02\u01E8" + - "\u01EC\x07\x05\x02\x02\u01E9\u01EB\x05b2\x02\u01EA\u01E9\x03\x02\x02\x02" + - "\u01EB\u01EE\x03\x02\x02\x02\u01EC\u01EA\x03\x02\x02\x02\u01EC\u01ED\x03" + - "\x02\x02\x02\u01ED\u01EF\x03\x02\x02\x02\u01EE\u01EC\x03\x02\x02\x02\u01EF" + - "\u01F2\x07X\x02\x02\u01F0\u01F1\x07V\x02\x02\u01F1\u01F3\x05,\x17\x02" + - "\u01F2\u01F0\x03\x02\x02\x02\u01F2\u01F3\x03\x02\x02\x02\u01F3\u01FD\x03" + - "\x02\x02\x02\u01F4\u01F5\x07W\x02\x02\u01F5\u01FA\x05`1\x02\u01F6\u01F7" + - "\x07$\x02\x02\u01F7\u01F9\x05`1\x02\u01F8\u01F6\x03\x02\x02\x02\u01F9" + - "\u01FC\x03\x02\x02\x02\u01FA\u01F8\x03\x02\x02\x02\u01FA\u01FB\x03\x02" + - "\x02\x02\u01FB\u01FE\x03\x02\x02\x02\u01FC\u01FA\x03\x02\x02\x02\u01FD" + - "\u01F4\x03\x02\x02\x02\u01FD\u01FE\x03\x02\x02\x02\u01FE_\x03\x02\x02" + - "\x02\u01FF\u0200\x05,\x17\x02\u0200\u0201\x07#\x02\x02\u0201\u0203\x03" + - "\x02\x02\x02\u0202\u01FF\x03\x02\x02\x02\u0202\u0203\x03\x02\x02\x02\u0203" + - "\u0204\x03\x02\x02\x02\u0204\u0205\x05,\x17\x02\u0205a\x03\x02\x02\x02" + - "\u0206\u0207\x07B\x02\x02\u0207\u0208\x07h\x02\x02\u0208\u0209\x07g\x02" + - "\x02\u0209\u020A\x07h\x02\x02\u020A\u020B\x07C\x02\x02\u020Bc\x03\x02" + - "\x02\x026ov\x85\x91\x9A\xA2\xA6\xAE\xB0\xB5\xBC\xC1\xC8\xCE\xD6\xD8\xE2" + - "\xEC\xEF\xFB\u0103\u010B\u010F\u0118\u0122\u0126\u012C\u0135\u013D\u0153" + - "\u015E\u0169\u016E\u0179\u017E\u0182\u018A\u0193\u0196\u019E\u01A7\u01B2" + - "\u01C0\u01CB\u01CE\u01D3\u01E6\u01EC\u01F2\u01FA\u01FD\u0202"; + "\x04,\t,\x04-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x042\t2\x043\t3\x03\x02" + + "\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x07\x03" + + "p\n\x03\f\x03\x0E\x03s\v\x03\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04y" + + "\n\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" + + "\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x05\x05\x88\n\x05\x03\x06\x03" + + "\x06\x03\x06\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05" + + "\x07\x94\n\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x07\x07\x9B\n\x07" + + "\f\x07\x0E\x07\x9E\v\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07" + + "\xA5\n\x07\x03\x07\x03\x07\x05\x07\xA9\n\x07\x03\x07\x03\x07\x03\x07\x03" + + "\x07\x03\x07\x03\x07\x07\x07\xB1\n\x07\f\x07\x0E\x07\xB4\v\x07\x03\b\x03" + + "\b\x05\b\xB8\n\b\x03\b\x03\b\x03\b\x03\b\x03\b\x05\b\xBF\n\b\x03\b\x03" + + "\b\x03\b\x05\b\xC4\n\b\x03\t\x03\t\x03\t\x03\t\x03\t\x05\t\xCB\n\t\x03" + + "\n\x03\n\x03\n\x03\n\x05\n\xD1\n\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n" + + "\x07\n\xD9\n\n\f\n\x0E\n\xDC\v\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03" + + "\v\x05\v\xE5\n\v\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x07\f\xED\n\f\f\f" + + "\x0E\f\xF0\v\f\x05\f\xF2\n\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\x0E\x03" + + "\x0E\x03\x0E\x07\x0E\xFC\n\x0E\f\x0E\x0E\x0E\xFF\v\x0E\x03\x0F\x03\x0F" + + "\x03\x0F\x03\x0F\x03\x0F\x05\x0F\u0106\n\x0F\x03\x10\x03\x10\x03\x10\x03" + + "\x10\x07\x10\u010C\n\x10\f\x10\x0E\x10\u010F\v\x10\x03\x10\x05\x10\u0112" + + "\n\x10\x03\x11\x03\x11\x05\x11\u0116\n\x11\x03\x12\x03\x12\x03\x12\x03" + + "\x12\x07\x12\u011C\n\x12\f\x12\x0E\x12\u011F\v\x12\x03\x13\x03\x13\x03" + + "\x13\x03\x13\x03\x14\x03\x14\x03\x14\x03\x15\x03\x15\x05\x15\u012A\n\x15" + + "\x03\x15\x03\x15\x05\x15\u012E\n\x15\x03\x16\x03\x16\x03\x16\x03\x16\x05" + + "\x16\u0134\n\x16\x03\x17\x03\x17\x03\x18\x03\x18\x03\x18\x07\x18\u013B" + + "\n\x18\f\x18\x0E\x18\u013E\v\x18\x03\x19\x03\x19\x03\x19\x07\x19\u0143" + + "\n\x19\f\x19\x0E\x19\u0146\v\x19\x03\x1A\x03\x1A\x03\x1B\x03\x1B\x03\x1C" + + "\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C" + + "\x03\x1C\x03\x1C\x03\x1C\x07\x1C\u0159\n\x1C\f\x1C\x0E\x1C\u015C\v\x1C" + + "\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x07\x1C\u0164\n\x1C\f" + + "\x1C\x0E\x1C\u0167\v\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C" + + "\x07\x1C\u016F\n\x1C\f\x1C\x0E\x1C\u0172\v\x1C\x03\x1C\x03\x1C\x05\x1C" + + "\u0176\n\x1C\x03\x1D\x03\x1D\x03\x1D\x03\x1E\x03\x1E\x03\x1E\x03\x1E\x07" + + "\x1E\u017F\n\x1E\f\x1E\x0E\x1E\u0182\v\x1E\x03\x1F\x03\x1F\x05\x1F\u0186" + + "\n\x1F\x03\x1F\x03\x1F\x05\x1F\u018A\n\x1F\x03 \x03 \x03 \x03 \x07 \u0190" + + "\n \f \x0E \u0193\v \x03!\x03!\x03!\x03!\x07!\u0199\n!\f!\x0E!\u019C\v" + + "!\x03\"\x03\"\x03\"\x03\"\x07\"\u01A2\n\"\f\"\x0E\"\u01A5\v\"\x03#\x03" + + "#\x03#\x03#\x03$\x03$\x03$\x03$\x05$\u01AF\n$\x03%\x03%\x03%\x03%\x03" + + "&\x03&\x03&\x03\'\x03\'\x03\'\x07\'\u01BB\n\'\f\'\x0E\'\u01BE\v\'\x03" + + "(\x03(\x03(\x03(\x03)\x03)\x03*\x03*\x05*\u01C8\n*\x03+\x05+\u01CB\n+" + + "\x03+\x03+\x03,\x05,\u01D0\n,\x03,\x03,\x03-\x03-\x03.\x03.\x03/\x03/" + + "\x03/\x030\x030\x030\x030\x031\x031\x031\x031\x051\u01E3\n1\x032\x032" + + "\x032\x032\x052\u01E9\n2\x032\x032\x032\x032\x072\u01EF\n2\f2\x0E2\u01F2" + + "\v2\x052\u01F4\n2\x033\x033\x033\x053\u01F9\n3\x033\x033\x033\x02\x02" + + "\x05\x04\f\x124\x02\x02\x04\x02\x06\x02\b\x02\n\x02\f\x02\x0E\x02\x10" + + "\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C\x02\x1E\x02 \x02\"\x02" + + "$\x02&\x02(\x02*\x02,\x02.\x020\x022\x024\x026\x028\x02:\x02<\x02>\x02" + + "@\x02B\x02D\x02F\x02H\x02J\x02L\x02N\x02P\x02R\x02T\x02V\x02X\x02Z\x02" + + "\\\x02^\x02`\x02b\x02d\x02\x02\v\x03\x02<=\x03\x02>@\x04\x02DDII\x03\x02" + + "CD\x04\x02DDMM\x04\x02!!$$\x03\x02\'(\x04\x02&&44\x03\x025;\x02\u0217" + + "\x02f\x03\x02\x02\x02\x04i\x03\x02\x02\x02\x06x\x03\x02\x02\x02\b\x87" + + "\x03\x02\x02\x02\n\x89\x03\x02\x02\x02\f\xA8\x03\x02\x02\x02\x0E\xC3\x03" + + "\x02\x02\x02\x10\xCA\x03\x02\x02\x02\x12\xD0\x03\x02\x02\x02\x14\xE4\x03" + + "\x02\x02\x02\x16\xE6\x03\x02\x02\x02\x18\xF5\x03\x02\x02\x02\x1A\xF8\x03" + + "\x02\x02\x02\x1C\u0105\x03\x02\x02\x02\x1E\u0107\x03\x02\x02\x02 \u0115" + + "\x03\x02\x02\x02\"\u0117\x03\x02\x02\x02$\u0120\x03\x02\x02\x02&\u0124" + + "\x03\x02\x02\x02(\u0127\x03\x02\x02\x02*\u012F\x03\x02\x02\x02,\u0135" + + "\x03\x02\x02\x02.\u0137\x03\x02\x02\x020\u013F\x03\x02\x02\x022\u0147" + + "\x03\x02\x02\x024\u0149\x03\x02\x02\x026\u0175\x03\x02\x02\x028\u0177" + + "\x03\x02\x02\x02:\u017A\x03\x02\x02\x02<\u0183\x03\x02\x02\x02>\u018B" + + "\x03\x02\x02\x02@\u0194\x03\x02\x02\x02B\u019D\x03\x02\x02\x02D\u01A6" + + "\x03\x02\x02\x02F\u01AA\x03\x02\x02\x02H\u01B0\x03\x02\x02\x02J\u01B4" + + "\x03\x02\x02\x02L\u01B7\x03\x02\x02\x02N\u01BF\x03\x02\x02\x02P\u01C3" + + "\x03\x02\x02\x02R\u01C7\x03\x02\x02\x02T\u01CA\x03\x02\x02\x02V\u01CF" + + "\x03\x02\x02\x02X\u01D3\x03\x02\x02\x02Z\u01D5\x03\x02\x02\x02\\\u01D7" + + "\x03\x02\x02\x02^\u01DA\x03\x02\x02\x02`\u01E2\x03\x02\x02\x02b\u01E4" + + "\x03\x02\x02\x02d\u01F8\x03\x02\x02\x02fg\x05\x04\x03\x02gh\x07\x02\x02" + + "\x03h\x03\x03\x02\x02\x02ij\b\x03\x01\x02jk\x05\x06\x04\x02kq\x03\x02" + + "\x02\x02lm\f\x03\x02\x02mn\x07\x1B\x02\x02np\x05\b\x05\x02ol\x03\x02\x02" + + "\x02ps\x03\x02\x02\x02qo\x03\x02\x02\x02qr\x03\x02\x02\x02r\x05\x03\x02" + + "\x02\x02sq\x03\x02\x02\x02ty\x05\\/\x02uy\x05\x1E\x10\x02vy\x05\x18\r" + + "\x02wy\x05`1\x02xt\x03\x02\x02\x02xu\x03\x02\x02\x02xv\x03\x02\x02\x02" + + "xw\x03\x02\x02\x02y\x07\x03\x02\x02\x02z\x88\x05&\x14\x02{\x88\x05*\x16" + + "\x02|\x88\x058\x1D\x02}\x88\x05> \x02~\x88\x05:\x1E\x02\x7F\x88\x05(\x15" + + "\x02\x80\x88\x05\n\x06\x02\x81\x88\x05@!\x02\x82\x88\x05B\"\x02\x83\x88" + + "\x05F$\x02\x84\x88\x05H%\x02\x85\x88\x05b2\x02\x86\x88\x05J&\x02\x87z" + + "\x03\x02\x02\x02\x87{\x03\x02\x02\x02\x87|\x03\x02\x02\x02\x87}\x03\x02" + + "\x02\x02\x87~\x03\x02\x02\x02\x87\x7F\x03\x02\x02\x02\x87\x80\x03\x02" + + "\x02\x02\x87\x81\x03\x02\x02\x02\x87\x82\x03\x02\x02\x02\x87\x83\x03\x02" + + "\x02\x02\x87\x84\x03\x02\x02\x02\x87\x85\x03\x02\x02\x02\x87\x86\x03\x02" + + "\x02\x02\x88\t\x03\x02\x02\x02\x89\x8A\x07\x13\x02\x02\x8A\x8B\x05\f\x07" + + "\x02\x8B\v\x03\x02\x02\x02\x8C\x8D\b\x07\x01\x02\x8D\x8E\x07-\x02\x02" + + "\x8E\xA9\x05\f\x07\t\x8F\xA9\x05\x10\t\x02\x90\xA9\x05\x0E\b\x02\x91\x93" + + "\x05\x10\t\x02\x92\x94\x07-\x02\x02\x93\x92\x03\x02\x02\x02\x93\x94\x03" + + "\x02\x02\x02\x94\x95\x03\x02\x02\x02\x95\x96\x07*\x02\x02\x96\x97\x07" + + ")\x02\x02\x97\x9C\x05\x10\t\x02\x98\x99\x07#\x02\x02\x99\x9B\x05\x10\t" + + "\x02\x9A\x98\x03\x02\x02\x02\x9B\x9E\x03\x02\x02\x02\x9C\x9A\x03\x02\x02" + + "\x02\x9C\x9D\x03\x02\x02\x02\x9D\x9F\x03\x02\x02\x02\x9E\x9C\x03\x02\x02" + + "\x02\x9F\xA0\x073\x02\x02\xA0\xA9\x03\x02\x02\x02\xA1\xA2\x05\x10\t\x02" + + "\xA2\xA4\x07+\x02\x02\xA3\xA5\x07-\x02\x02\xA4\xA3\x03\x02\x02\x02\xA4" + + "\xA5\x03\x02\x02\x02\xA5\xA6\x03\x02\x02\x02\xA6\xA7\x07.\x02\x02\xA7" + + "\xA9\x03\x02\x02\x02\xA8\x8C\x03\x02\x02\x02\xA8\x8F\x03\x02\x02\x02\xA8" + + "\x90\x03\x02\x02\x02\xA8\x91\x03\x02\x02\x02\xA8\xA1\x03\x02\x02\x02\xA9" + + "\xB2\x03\x02\x02\x02\xAA\xAB\f\x06\x02\x02\xAB\xAC\x07 \x02\x02\xAC\xB1" + + "\x05\f\x07\x07\xAD\xAE\f\x05\x02\x02\xAE\xAF\x070\x02\x02\xAF\xB1\x05" + + "\f\x07\x06\xB0\xAA\x03\x02\x02\x02\xB0\xAD\x03\x02\x02\x02\xB1\xB4\x03" + + "\x02\x02\x02\xB2\xB0\x03\x02\x02\x02\xB2\xB3\x03\x02\x02\x02\xB3\r\x03" + + "\x02\x02\x02\xB4\xB2\x03\x02\x02\x02\xB5\xB7\x05\x10\t\x02\xB6\xB8\x07" + + "-\x02\x02\xB7\xB6\x03\x02\x02\x02\xB7\xB8\x03\x02\x02\x02\xB8\xB9\x03" + + "\x02\x02\x02\xB9\xBA\x07,\x02\x02\xBA\xBB\x05X-\x02\xBB\xC4\x03\x02\x02" + + "\x02\xBC\xBE\x05\x10\t\x02\xBD\xBF\x07-\x02\x02\xBE\xBD\x03\x02\x02\x02" + + "\xBE\xBF\x03\x02\x02\x02\xBF\xC0\x03\x02\x02\x02\xC0\xC1\x072\x02\x02" + + "\xC1\xC2\x05X-\x02\xC2\xC4\x03\x02\x02\x02\xC3\xB5\x03\x02\x02\x02\xC3" + + "\xBC\x03\x02\x02\x02\xC4\x0F\x03\x02\x02\x02\xC5\xCB\x05\x12\n\x02\xC6" + + "\xC7\x05\x12\n\x02\xC7\xC8\x05Z.\x02\xC8\xC9\x05\x12\n\x02\xC9\xCB\x03" + + "\x02\x02\x02\xCA\xC5\x03\x02\x02\x02\xCA\xC6\x03\x02\x02\x02\xCB\x11\x03" + + "\x02\x02\x02\xCC\xCD\b\n\x01\x02\xCD\xD1\x05\x14\v\x02\xCE\xCF\t\x02\x02" + + "\x02\xCF\xD1\x05\x12\n\x05\xD0\xCC\x03\x02\x02\x02\xD0\xCE\x03\x02\x02" + + "\x02\xD1\xDA\x03\x02\x02\x02\xD2\xD3\f\x04\x02\x02\xD3\xD4\t\x03\x02\x02" + + "\xD4\xD9\x05\x12\n\x05\xD5\xD6\f\x03\x02\x02\xD6\xD7\t\x02\x02\x02\xD7" + + "\xD9\x05\x12\n\x04\xD8\xD2\x03\x02\x02\x02\xD8\xD5\x03\x02\x02\x02\xD9" + + "\xDC\x03\x02\x02\x02\xDA\xD8\x03\x02\x02\x02\xDA\xDB\x03\x02\x02\x02\xDB" + + "\x13\x03\x02\x02\x02\xDC\xDA\x03\x02\x02\x02\xDD\xE5\x056\x1C\x02\xDE" + + "\xE5\x05.\x18\x02\xDF\xE5\x05\x16\f\x02\xE0\xE1\x07)\x02\x02\xE1\xE2\x05" + + "\f\x07\x02\xE2\xE3\x073\x02\x02\xE3\xE5\x03\x02\x02\x02\xE4\xDD\x03\x02" + + "\x02\x02\xE4\xDE\x03\x02\x02\x02\xE4\xDF\x03\x02\x02\x02\xE4\xE0\x03\x02" + + "\x02\x02\xE5\x15\x03\x02\x02\x02\xE6\xE7\x052\x1A\x02\xE7\xF1\x07)\x02" + + "\x02\xE8\xF2\x07>\x02\x02\xE9\xEE\x05\f\x07\x02\xEA\xEB\x07#\x02\x02\xEB" + + "\xED\x05\f\x07\x02\xEC\xEA\x03\x02\x02\x02\xED\xF0\x03\x02\x02\x02\xEE" + + "\xEC\x03\x02\x02\x02\xEE\xEF\x03\x02\x02\x02\xEF\xF2\x03\x02\x02\x02\xF0" + + "\xEE\x03\x02\x02\x02\xF1\xE8\x03\x02\x02\x02\xF1\xE9\x03\x02\x02\x02\xF1" + + "\xF2\x03\x02\x02\x02\xF2\xF3\x03\x02\x02\x02\xF3\xF4\x073\x02\x02\xF4" + + "\x17\x03\x02\x02\x02\xF5\xF6\x07\x0F\x02\x02\xF6\xF7\x05\x1A\x0E\x02\xF7" + + "\x19\x03\x02\x02\x02\xF8\xFD\x05\x1C\x0F\x02\xF9\xFA\x07#\x02\x02\xFA" + + "\xFC\x05\x1C\x0F\x02\xFB\xF9\x03\x02\x02\x02\xFC\xFF\x03\x02\x02\x02\xFD" + + "\xFB\x03\x02\x02\x02\xFD\xFE\x03\x02\x02\x02\xFE\x1B\x03\x02\x02\x02\xFF" + + "\xFD\x03\x02\x02\x02\u0100\u0106\x05\f\x07\x02\u0101\u0102\x05.\x18\x02" + + "\u0102\u0103\x07\"\x02\x02\u0103\u0104\x05\f\x07\x02\u0104\u0106\x03\x02" + + "\x02\x02\u0105\u0100\x03\x02\x02\x02\u0105\u0101\x03\x02\x02\x02\u0106" + + "\x1D\x03\x02\x02\x02\u0107\u0108\x07\b\x02\x02\u0108\u010D\x05,\x17\x02" + + "\u0109\u010A\x07#\x02\x02\u010A\u010C\x05,\x17\x02\u010B\u0109\x03\x02" + + "\x02\x02\u010C\u010F\x03\x02\x02\x02\u010D\u010B\x03\x02\x02\x02\u010D" + + "\u010E\x03\x02\x02\x02\u010E\u0111\x03\x02\x02\x02\u010F\u010D\x03\x02" + + "\x02\x02\u0110\u0112\x05 \x11\x02\u0111\u0110\x03\x02\x02\x02\u0111\u0112" + + "\x03\x02\x02\x02\u0112\x1F\x03\x02\x02\x02\u0113\u0116\x05\"\x12\x02\u0114" + + "\u0116\x05$\x13\x02\u0115\u0113\x03\x02\x02\x02\u0115\u0114\x03\x02\x02" + + "\x02\u0116!\x03\x02\x02\x02\u0117\u0118\x07H\x02\x02\u0118\u011D\x05," + + "\x17\x02\u0119\u011A\x07#\x02\x02\u011A\u011C\x05,\x17\x02\u011B\u0119" + + "\x03\x02\x02\x02\u011C\u011F\x03\x02\x02\x02\u011D\u011B\x03\x02\x02\x02" + + "\u011D\u011E\x03\x02\x02\x02\u011E#\x03\x02\x02\x02\u011F\u011D\x03\x02" + + "\x02\x02\u0120\u0121\x07A\x02\x02\u0121\u0122\x05\"\x12\x02\u0122\u0123" + + "\x07B\x02\x02\u0123%\x03\x02\x02\x02\u0124\u0125\x07\x06\x02\x02\u0125" + + "\u0126\x05\x1A\x0E\x02\u0126\'\x03\x02\x02\x02\u0127\u0129\x07\x12\x02" + + "\x02\u0128\u012A\x05\x1A\x0E\x02\u0129\u0128\x03\x02\x02\x02\u0129\u012A" + + "\x03\x02\x02\x02\u012A\u012D\x03\x02\x02\x02\u012B\u012C\x07\x1F\x02\x02" + + "\u012C\u012E\x05\x1A\x0E\x02\u012D\u012B\x03\x02\x02\x02\u012D\u012E\x03" + + "\x02\x02\x02\u012E)\x03\x02\x02\x02\u012F\u0130\x07\n\x02\x02\u0130\u0133" + + "\x05\x1A\x0E\x02\u0131\u0132\x07\x1F\x02\x02\u0132\u0134\x05\x1A\x0E\x02" + + "\u0133\u0131\x03\x02\x02\x02\u0133\u0134\x03\x02\x02\x02\u0134+\x03\x02" + + "\x02\x02\u0135\u0136\t\x04\x02\x02\u0136-\x03\x02\x02\x02\u0137\u013C" + + "\x052\x1A\x02\u0138\u0139\x07%\x02\x02\u0139\u013B\x052\x1A\x02\u013A" + + "\u0138\x03\x02\x02\x02\u013B\u013E\x03\x02\x02\x02\u013C\u013A\x03\x02" + + "\x02\x02\u013C\u013D\x03\x02\x02\x02\u013D/\x03\x02\x02\x02\u013E\u013C" + + "\x03\x02\x02\x02\u013F\u0144\x054\x1B\x02\u0140\u0141\x07%\x02\x02\u0141" + + "\u0143\x054\x1B\x02\u0142\u0140\x03\x02\x02\x02\u0143\u0146\x03\x02\x02" + + "\x02\u0144\u0142\x03\x02\x02\x02\u0144\u0145\x03\x02\x02\x02\u01451\x03" + + "\x02\x02\x02\u0146\u0144\x03\x02\x02\x02\u0147\u0148\t\x05\x02\x02\u0148" + + "3\x03\x02\x02\x02\u0149\u014A\t\x06\x02\x02\u014A5\x03\x02\x02\x02\u014B" + + "\u0176\x07.\x02\x02\u014C\u014D\x05V,\x02\u014D\u014E\x07C\x02\x02\u014E" + + "\u0176\x03\x02\x02\x02\u014F\u0176\x05T+\x02\u0150\u0176\x05V,\x02\u0151" + + "\u0176\x05P)\x02\u0152\u0176\x071\x02\x02\u0153\u0176\x05X-\x02\u0154" + + "\u0155\x07A\x02\x02\u0155\u015A\x05R*\x02\u0156\u0157\x07#\x02\x02\u0157" + + "\u0159\x05R*\x02\u0158\u0156\x03\x02\x02\x02\u0159\u015C\x03\x02\x02\x02" + + "\u015A\u0158\x03\x02\x02\x02\u015A\u015B\x03\x02\x02\x02\u015B\u015D\x03" + + "\x02\x02\x02\u015C\u015A\x03\x02\x02\x02\u015D\u015E\x07B\x02\x02\u015E" + + "\u0176\x03\x02\x02\x02\u015F\u0160\x07A\x02\x02\u0160\u0165\x05P)\x02" + + "\u0161\u0162\x07#\x02\x02\u0162\u0164\x05P)\x02\u0163\u0161\x03\x02\x02" + + "\x02\u0164\u0167\x03\x02\x02\x02\u0165\u0163\x03\x02\x02\x02\u0165\u0166" + + "\x03\x02\x02\x02\u0166\u0168\x03\x02\x02\x02\u0167\u0165\x03\x02\x02\x02" + + "\u0168\u0169\x07B\x02\x02\u0169\u0176\x03\x02\x02\x02\u016A\u016B\x07" + + "A\x02\x02\u016B\u0170\x05X-\x02\u016C\u016D\x07#\x02\x02\u016D\u016F\x05" + + "X-\x02\u016E\u016C\x03\x02\x02\x02\u016F\u0172\x03\x02\x02\x02\u0170\u016E" + + "\x03\x02\x02\x02\u0170\u0171\x03\x02\x02\x02\u0171\u0173\x03\x02\x02\x02" + + "\u0172\u0170\x03\x02\x02\x02\u0173\u0174\x07B\x02\x02\u0174\u0176\x03" + + "\x02\x02\x02\u0175\u014B\x03\x02\x02\x02\u0175\u014C\x03\x02\x02\x02\u0175" + + "\u014F\x03\x02\x02\x02\u0175\u0150\x03\x02\x02\x02\u0175\u0151\x03\x02" + + "\x02\x02\u0175\u0152\x03\x02\x02\x02\u0175\u0153\x03\x02\x02\x02\u0175" + + "\u0154\x03\x02\x02\x02\u0175\u015F\x03\x02\x02\x02\u0175\u016A\x03\x02" + + "\x02\x02\u01767\x03\x02\x02\x02\u0177\u0178\x07\f\x02\x02\u0178\u0179" + + "\x07\x1D\x02\x02\u01799\x03\x02\x02\x02\u017A\u017B\x07\x11\x02\x02\u017B" + + "\u0180\x05<\x1F\x02\u017C\u017D\x07#\x02\x02\u017D\u017F\x05<\x1F\x02" + + "\u017E\u017C\x03\x02\x02\x02\u017F\u0182\x03\x02\x02\x02\u0180\u017E\x03" + + "\x02\x02\x02\u0180\u0181\x03\x02\x02\x02\u0181;\x03\x02\x02\x02\u0182" + + "\u0180\x03\x02\x02\x02\u0183\u0185\x05\f\x07\x02\u0184\u0186\t\x07\x02" + + "\x02\u0185\u0184\x03\x02\x02\x02\u0185\u0186\x03\x02\x02\x02\u0186\u0189" + + "\x03\x02\x02\x02\u0187\u0188\x07/\x02\x02\u0188\u018A\t\b\x02\x02\u0189" + + "\u0187\x03\x02\x02\x02\u0189\u018A\x03\x02\x02\x02\u018A=\x03\x02\x02" + + "\x02\u018B\u018C\x07\v\x02\x02\u018C\u0191\x050\x19\x02\u018D\u018E\x07" + + "#\x02\x02\u018E\u0190\x050\x19\x02\u018F\u018D\x03\x02\x02\x02\u0190\u0193" + + "\x03\x02\x02\x02\u0191\u018F\x03\x02\x02\x02\u0191\u0192\x03\x02\x02\x02" + + "\u0192?\x03\x02\x02\x02\u0193\u0191\x03\x02\x02\x02\u0194\u0195\x07\x04" + + "\x02\x02\u0195\u019A\x050\x19\x02\u0196\u0197\x07#\x02\x02\u0197\u0199" + + "\x050\x19\x02\u0198\u0196\x03\x02\x02\x02\u0199\u019C\x03\x02\x02\x02" + + "\u019A\u0198\x03\x02\x02\x02\u019A\u019B\x03\x02\x02\x02\u019BA\x03\x02" + + "\x02\x02\u019C\u019A\x03\x02\x02\x02\u019D\u019E\x07\x0E\x02\x02\u019E" + + "\u01A3\x05D#\x02\u019F\u01A0\x07#\x02\x02\u01A0\u01A2\x05D#\x02\u01A1" + + "\u019F\x03\x02\x02\x02\u01A2\u01A5\x03\x02\x02\x02\u01A3\u01A1\x03\x02" + + "\x02\x02\u01A3\u01A4\x03\x02\x02\x02\u01A4C\x03\x02\x02\x02\u01A5\u01A3" + + "\x03\x02\x02\x02\u01A6\u01A7\x050\x19\x02\u01A7\u01A8\x07Q\x02\x02\u01A8" + + "\u01A9\x050\x19\x02\u01A9E\x03\x02\x02\x02\u01AA\u01AB\x07\x03\x02\x02" + + "\u01AB\u01AC\x05\x14\v\x02\u01AC\u01AE\x05X-\x02\u01AD\u01AF\x05L\'\x02" + + "\u01AE\u01AD\x03\x02\x02\x02\u01AE\u01AF\x03\x02\x02\x02\u01AFG\x03\x02" + + "\x02\x02\u01B0\u01B1\x07\t\x02\x02\u01B1\u01B2\x05\x14\v\x02\u01B2\u01B3" + + "\x05X-\x02\u01B3I\x03\x02\x02\x02\u01B4\u01B5\x07\r\x02\x02\u01B5\u01B6" + + "\x05.\x18\x02\u01B6K\x03\x02\x02\x02\u01B7\u01BC\x05N(\x02\u01B8\u01B9" + + "\x07#\x02\x02\u01B9\u01BB\x05N(\x02\u01BA\u01B8\x03\x02\x02\x02\u01BB" + + "\u01BE\x03\x02\x02\x02\u01BC\u01BA\x03\x02\x02\x02\u01BC\u01BD\x03\x02" + + "\x02\x02\u01BDM\x03\x02\x02\x02\u01BE\u01BC\x03\x02\x02\x02\u01BF\u01C0" + + "\x052\x1A\x02\u01C0\u01C1\x07\"\x02\x02\u01C1\u01C2\x056\x1C\x02\u01C2" + + "O\x03\x02\x02\x02\u01C3\u01C4\t\t\x02\x02\u01C4Q\x03\x02\x02\x02\u01C5" + + "\u01C8\x05T+\x02\u01C6\u01C8\x05V,\x02\u01C7\u01C5\x03\x02\x02\x02\u01C7" + + "\u01C6\x03\x02\x02\x02\u01C8S\x03\x02\x02\x02\u01C9\u01CB\t\x02\x02\x02" + + "\u01CA\u01C9\x03\x02\x02\x02\u01CA\u01CB\x03\x02\x02\x02\u01CB\u01CC\x03" + + "\x02\x02\x02\u01CC\u01CD\x07\x1E\x02\x02\u01CDU\x03\x02\x02\x02\u01CE" + + "\u01D0\t\x02\x02\x02\u01CF\u01CE\x03\x02\x02\x02\u01CF\u01D0\x03\x02\x02" + + "\x02\u01D0\u01D1\x03\x02\x02\x02\u01D1\u01D2\x07\x1D\x02\x02\u01D2W\x03" + + "\x02\x02\x02\u01D3\u01D4\x07\x1C\x02\x02\u01D4Y\x03\x02\x02\x02\u01D5" + + "\u01D6\t\n\x02\x02\u01D6[\x03\x02\x02\x02\u01D7\u01D8\x07\x07\x02\x02" + + "\u01D8\u01D9\x05^0\x02\u01D9]\x03\x02\x02\x02\u01DA\u01DB\x07A\x02\x02" + + "\u01DB\u01DC\x05\x04\x03\x02\u01DC\u01DD\x07B\x02\x02\u01DD_\x03\x02\x02" + + "\x02\u01DE\u01DF\x07\x10\x02\x02\u01DF\u01E3\x07a\x02\x02\u01E0\u01E1" + + "\x07\x10\x02\x02\u01E1\u01E3\x07b\x02\x02\u01E2\u01DE\x03\x02\x02\x02" + + "\u01E2\u01E0\x03\x02\x02\x02\u01E3a\x03\x02\x02\x02\u01E4\u01E5\x07\x05" + + "\x02\x02\u01E5\u01E8\x07W\x02\x02\u01E6\u01E7\x07U\x02\x02\u01E7\u01E9" + + "\x050\x19\x02\u01E8\u01E6\x03\x02\x02\x02\u01E8\u01E9\x03\x02\x02\x02" + + "\u01E9\u01F3\x03\x02\x02\x02\u01EA\u01EB\x07V\x02\x02\u01EB\u01F0\x05" + + "d3\x02\u01EC\u01ED\x07#\x02\x02\u01ED\u01EF\x05d3\x02\u01EE\u01EC\x03" + + "\x02\x02\x02\u01EF\u01F2\x03\x02\x02\x02\u01F0\u01EE\x03\x02\x02\x02\u01F0" + + "\u01F1\x03\x02\x02\x02\u01F1\u01F4\x03\x02\x02\x02\u01F2\u01F0\x03\x02" + + "\x02\x02\u01F3\u01EA\x03\x02\x02\x02\u01F3\u01F4\x03\x02\x02\x02\u01F4" + + "c\x03\x02\x02\x02\u01F5\u01F6\x050\x19\x02\u01F6\u01F7\x07\"\x02\x02\u01F7" + + "\u01F9\x03\x02\x02\x02\u01F8\u01F5\x03\x02\x02\x02\u01F8\u01F9\x03\x02" + + "\x02\x02\u01F9\u01FA\x03\x02\x02\x02\u01FA\u01FB\x050\x19\x02\u01FBe\x03" + + "\x02\x02\x024qx\x87\x93\x9C\xA4\xA8\xB0\xB2\xB7\xBE\xC3\xCA\xD0\xD8\xDA" + + "\xE4\xEE\xF1\xFD\u0105\u010D\u0111\u0115\u011D\u0129\u012D\u0133\u013C" + + "\u0144\u015A\u0165\u0170\u0175\u0180\u0185\u0189\u0191\u019A\u01A3\u01AE" + + "\u01BC\u01C7\u01CA\u01CF\u01E2\u01E8\u01F0\u01F3\u01F8"; public static __ATN: ATN; public static get _ATN(): ATN { if (!esql_parser.__ATN) { @@ -3997,7 +3971,33 @@ export class FromCommandContext extends ParserRuleContext { export class MetadataContext extends ParserRuleContext { - public OPENING_BRACKET(): TerminalNode { return this.getToken(esql_parser.OPENING_BRACKET, 0); } + public metadataOption(): MetadataOptionContext | undefined { + return this.tryGetRuleContext(0, MetadataOptionContext); + } + public deprecated_metadata(): Deprecated_metadataContext | undefined { + return this.tryGetRuleContext(0, Deprecated_metadataContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_metadata; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterMetadata) { + listener.enterMetadata(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitMetadata) { + listener.exitMetadata(this); + } + } +} + + +export class MetadataOptionContext extends ParserRuleContext { public METADATA(): TerminalNode { return this.getToken(esql_parser.METADATA, 0); } public fromIdentifier(): FromIdentifierContext[]; public fromIdentifier(i: number): FromIdentifierContext; @@ -4008,7 +4008,6 @@ export class MetadataContext extends ParserRuleContext { return this.getRuleContext(i, FromIdentifierContext); } } - public CLOSING_BRACKET(): TerminalNode { return this.getToken(esql_parser.CLOSING_BRACKET, 0); } public COMMA(): TerminalNode[]; public COMMA(i: number): TerminalNode; public COMMA(i?: number): TerminalNode | TerminalNode[] { @@ -4022,17 +4021,43 @@ export class MetadataContext extends ParserRuleContext { super(parent, invokingState); } // @Override - public get ruleIndex(): number { return esql_parser.RULE_metadata; } + public get ruleIndex(): number { return esql_parser.RULE_metadataOption; } // @Override public enterRule(listener: esql_parserListener): void { - if (listener.enterMetadata) { - listener.enterMetadata(this); + if (listener.enterMetadataOption) { + listener.enterMetadataOption(this); } } // @Override public exitRule(listener: esql_parserListener): void { - if (listener.exitMetadata) { - listener.exitMetadata(this); + if (listener.exitMetadataOption) { + listener.exitMetadataOption(this); + } + } +} + + +export class Deprecated_metadataContext extends ParserRuleContext { + public OPENING_BRACKET(): TerminalNode { return this.getToken(esql_parser.OPENING_BRACKET, 0); } + public metadataOption(): MetadataOptionContext { + return this.getRuleContext(0, MetadataOptionContext); + } + public CLOSING_BRACKET(): TerminalNode { return this.getToken(esql_parser.CLOSING_BRACKET, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_deprecated_metadata; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterDeprecated_metadata) { + listener.enterDeprecated_metadata(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitDeprecated_metadata) { + listener.exitDeprecated_metadata(this); } } } @@ -4643,7 +4668,7 @@ export class OrderExpressionContext extends ParserRuleContext { export class KeepCommandContext extends ParserRuleContext { - public KEEP(): TerminalNode | undefined { return this.tryGetToken(esql_parser.KEEP, 0); } + public KEEP(): TerminalNode { return this.getToken(esql_parser.KEEP, 0); } public qualifiedNamePattern(): QualifiedNamePatternContext[]; public qualifiedNamePattern(i: number): QualifiedNamePatternContext; public qualifiedNamePattern(i?: number): QualifiedNamePatternContext | QualifiedNamePatternContext[] { @@ -4662,7 +4687,6 @@ export class KeepCommandContext extends ParserRuleContext { return this.getToken(esql_parser.COMMA, i); } } - public PROJECT(): TerminalNode | undefined { return this.tryGetToken(esql_parser.PROJECT, 0); } constructor(parent: ParserRuleContext | undefined, invokingState: number) { super(parent, invokingState); } @@ -5203,15 +5227,6 @@ export class EnrichCommandContext extends ParserRuleContext { public _matchField: QualifiedNamePatternContext; public ENRICH(): TerminalNode { return this.getToken(esql_parser.ENRICH, 0); } public ENRICH_POLICY_NAME(): TerminalNode { return this.getToken(esql_parser.ENRICH_POLICY_NAME, 0); } - public setting(): SettingContext[]; - public setting(i: number): SettingContext; - public setting(i?: number): SettingContext | SettingContext[] { - if (i === undefined) { - return this.getRuleContexts(SettingContext); - } else { - return this.getRuleContext(i, SettingContext); - } - } public ON(): TerminalNode | undefined { return this.tryGetToken(esql_parser.ON, 0); } public WITH(): TerminalNode | undefined { return this.tryGetToken(esql_parser.WITH, 0); } public enrichWithClause(): EnrichWithClauseContext[]; @@ -5288,38 +5303,3 @@ export class EnrichWithClauseContext extends ParserRuleContext { } -export class SettingContext extends ParserRuleContext { - public _name: Token; - public _value: Token; - public OPENING_BRACKET(): TerminalNode { return this.getToken(esql_parser.OPENING_BRACKET, 0); } - public COLON(): TerminalNode { return this.getToken(esql_parser.COLON, 0); } - public CLOSING_BRACKET(): TerminalNode { return this.getToken(esql_parser.CLOSING_BRACKET, 0); } - public SETTING(): TerminalNode[]; - public SETTING(i: number): TerminalNode; - public SETTING(i?: number): TerminalNode | TerminalNode[] { - if (i === undefined) { - return this.getTokens(esql_parser.SETTING); - } else { - return this.getToken(esql_parser.SETTING, i); - } - } - constructor(parent: ParserRuleContext | undefined, invokingState: number) { - super(parent, invokingState); - } - // @Override - public get ruleIndex(): number { return esql_parser.RULE_setting; } - // @Override - public enterRule(listener: esql_parserListener): void { - if (listener.enterSetting) { - listener.enterSetting(this); - } - } - // @Override - public exitRule(listener: esql_parserListener): void { - if (listener.exitSetting) { - listener.exitSetting(this); - } - } -} - - diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts b/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts index 31c0d1ec27beb..233518b74555e 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts @@ -49,6 +49,8 @@ import { FieldsContext } from "./esql_parser"; import { FieldContext } from "./esql_parser"; import { FromCommandContext } from "./esql_parser"; import { MetadataContext } from "./esql_parser"; +import { MetadataOptionContext } from "./esql_parser"; +import { Deprecated_metadataContext } from "./esql_parser"; import { EvalCommandContext } from "./esql_parser"; import { StatsCommandContext } from "./esql_parser"; import { InlinestatsCommandContext } from "./esql_parser"; @@ -81,7 +83,6 @@ import { SubqueryExpressionContext } from "./esql_parser"; import { ShowCommandContext } from "./esql_parser"; import { EnrichCommandContext } from "./esql_parser"; import { EnrichWithClauseContext } from "./esql_parser"; -import { SettingContext } from "./esql_parser"; /** @@ -642,6 +643,28 @@ export interface esql_parserListener extends ParseTreeListener { */ exitMetadata?: (ctx: MetadataContext) => void; + /** + * Enter a parse tree produced by `esql_parser.metadataOption`. + * @param ctx the parse tree + */ + enterMetadataOption?: (ctx: MetadataOptionContext) => void; + /** + * Exit a parse tree produced by `esql_parser.metadataOption`. + * @param ctx the parse tree + */ + exitMetadataOption?: (ctx: MetadataOptionContext) => void; + + /** + * Enter a parse tree produced by `esql_parser.deprecated_metadata`. + * @param ctx the parse tree + */ + enterDeprecated_metadata?: (ctx: Deprecated_metadataContext) => void; + /** + * Exit a parse tree produced by `esql_parser.deprecated_metadata`. + * @param ctx the parse tree + */ + exitDeprecated_metadata?: (ctx: Deprecated_metadataContext) => void; + /** * Enter a parse tree produced by `esql_parser.evalCommand`. * @param ctx the parse tree @@ -993,16 +1016,5 @@ export interface esql_parserListener extends ParseTreeListener { * @param ctx the parse tree */ exitEnrichWithClause?: (ctx: EnrichWithClauseContext) => void; - - /** - * Enter a parse tree produced by `esql_parser.setting`. - * @param ctx the parse tree - */ - enterSetting?: (ctx: SettingContext) => void; - /** - * Exit a parse tree produced by `esql_parser.setting`. - * @param ctx the parse tree - */ - exitSetting?: (ctx: SettingContext) => void; } diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_factory.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_factory.ts index 724e1d5bb0f78..328dfd51bc9bc 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_factory.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_factory.ts @@ -43,7 +43,6 @@ import { getPolicyName, getMatchField, getEnrichClauses, - getPolicySettings, } from './ast_walker'; import type { ESQLAst } from './types'; @@ -117,10 +116,12 @@ export class AstListener implements ESQLParserListener { this.ast.push(commandAst); commandAst.args.push(...collectAllSourceIdentifiers(ctx)); const metadataContext = ctx.metadata(); - if (metadataContext) { - const option = createOption(metadataContext.METADATA().text.toLowerCase(), metadataContext); + const metadataContent = + metadataContext?.deprecated_metadata()?.metadataOption() || metadataContext?.metadataOption(); + if (metadataContent) { + const option = createOption(metadataContent.METADATA().text.toLowerCase(), metadataContent); commandAst.args.push(option); - option.args.push(...collectAllColumnIdentifiers(metadataContext)); + option.args.push(...collectAllColumnIdentifiers(metadataContent)); } } @@ -251,11 +252,6 @@ export class AstListener implements ESQLParserListener { exitEnrichCommand(ctx: EnrichCommandContext) { const command = createCommand('enrich', ctx); this.ast.push(command); - command.args.push( - ...getPolicySettings(ctx), - ...getPolicyName(ctx), - ...getMatchField(ctx), - ...getEnrichClauses(ctx) - ); + command.args.push(...getPolicyName(ctx), ...getMatchField(ctx), ...getEnrichClauses(ctx)); } } diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts index 73fd877f307bd..508fa7c371100 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts @@ -19,7 +19,6 @@ import type { DecimalValueContext, IntegerValueContext, QualifiedIntegerLiteralContext, - SettingContext, } from '../../antlr/esql_parser'; import { getPosition } from './ast_position_utils'; import type { @@ -198,15 +197,15 @@ export function computeLocationExtends(fn: ESQLFunction) { /* SCRIPT_MARKER_START */ function getQuotedText(ctx: ParserRuleContext) { - return [67 /* esql_parser.QUOTED_IDENTIFIER */] + return [66 /* esql_parser.QUOTED_IDENTIFIER */] .map((keyCode) => ctx.tryGetToken(keyCode, 0)) .filter(nonNullable)[0]; } function getUnquotedText(ctx: ParserRuleContext) { return [ - 66 /* esql_parser.UNQUOTED_IDENTIFIER */, 72 /* esql_parser.FROM_UNQUOTED_IDENTIFIER */, - 76 /* esql_parser.UNQUOTED_ID_PATTERN */, + 65 /* esql_parser.UNQUOTED_IDENTIFIER */, 71 /* esql_parser.FROM_UNQUOTED_IDENTIFIER */, + 75 /* esql_parser.UNQUOTED_ID_PATTERN */, ] .map((keyCode) => ctx.tryGetToken(keyCode, 0)) .filter(nonNullable)[0]; @@ -231,16 +230,13 @@ export function wrapIdentifierAsArray<T extends ParserRuleContext>(identifierCtx return Array.isArray(identifierCtx) ? identifierCtx : [identifierCtx]; } -export function createSettingTuple(ctx: SettingContext): ESQLCommandMode { +export function createSetting(policyName: Token, mode: string): ESQLCommandMode { return { type: 'mode', - name: ctx._name?.text || '', - text: ctx.text!, - location: getPosition(ctx.start, ctx.stop), - incomplete: - (ctx._name?.text ? isMissingText(ctx._name.text) : true) || - (ctx._value?.text ? isMissingText(ctx._value.text) : true), - args: [], + name: mode.replace('_', '').toLowerCase(), + text: mode, + location: getPosition(policyName, { stopIndex: policyName.startIndex + mode.length - 1 }), // unfortunately this is the only location we have + incomplete: false, }; } @@ -248,13 +244,16 @@ export function createSettingTuple(ctx: SettingContext): ESQLCommandMode { * In https://github.com/elastic/elasticsearch/pull/103949 the ENRICH policy name * changed from rule to token type so we need to handle this specifically */ -export function createPolicy(token: Token): ESQLSource { +export function createPolicy(token: Token, policy: string): ESQLSource { return { type: 'source', - name: token.text!, - text: token.text!, + name: policy, + text: policy, sourceType: 'policy', - location: getPosition(token), + location: getPosition({ + startIndex: token.stopIndex - policy.length + 1, + stopIndex: token.stopIndex, + }), // take into account ccq modes incomplete: false, }; } diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_position_utils.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_position_utils.ts index 73745b12f4908..24d3a806ace01 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_position_utils.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_position_utils.ts @@ -8,7 +8,10 @@ import type { Token } from 'antlr4ts'; -export function getPosition(token: Token | undefined, lastToken?: Token | undefined) { +export function getPosition( + token: Pick<Token, 'startIndex' | 'stopIndex'> | undefined, + lastToken?: Pick<Token, 'stopIndex'> | undefined +) { if (!token || token.startIndex < 0) { return { min: 0, max: 0 }; } diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts index 00a84dd3d3214..fd33f33af976d 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts @@ -37,7 +37,7 @@ import { LogicalBinaryContext, LogicalInContext, LogicalNotContext, - MetadataContext, + MetadataOptionContext, MvExpandCommandContext, NullLiteralContext, NumericArrayLiteralContext, @@ -74,9 +74,8 @@ import { createColumnStar, wrapIdentifierAsArray, createPolicy, - createSettingTuple, - createLiteralString, isMissingText, + createSetting, } from './ast_helpers'; import { getPosition } from './ast_position_utils'; import type { @@ -92,9 +91,9 @@ export function collectAllSourceIdentifiers(ctx: FromCommandContext): ESQLAstIte } function extractIdentifiers( - ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataContext + ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataOptionContext ) { - if (ctx instanceof MetadataContext) { + if (ctx instanceof MetadataOptionContext) { return wrapIdentifierAsArray(ctx.fromIdentifier()); } if (ctx instanceof MvExpandCommandContext) { @@ -114,32 +113,22 @@ function makeColumnsOutOfIdentifiers(identifiers: ParserRuleContext[]) { } export function collectAllColumnIdentifiers( - ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataContext + ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataOptionContext ): ESQLAstItem[] { const identifiers = extractIdentifiers(ctx); return makeColumnsOutOfIdentifiers(identifiers); } export function getPolicyName(ctx: EnrichCommandContext) { - if (!ctx._policyName || (ctx._policyName.text && /<missing /.test(ctx._policyName.text))) { + if (!ctx._policyName || !ctx._policyName.text || /<missing /.test(ctx._policyName.text)) { return []; } - return [createPolicy(ctx._policyName)]; -} - -export function getPolicySettings(ctx: EnrichCommandContext) { - if (!ctx.setting() || !ctx.setting().length) { - return []; + const policyComponents = ctx._policyName.text.split(':'); + if (policyComponents.length > 1) { + const [setting, policyName] = policyComponents; + return [createSetting(ctx._policyName, setting), createPolicy(ctx._policyName, policyName)]; } - return ctx.setting().map((setting) => { - const node = createSettingTuple(setting); - if (setting._name?.text && setting._value?.text) { - node.args.push(createLiteralString(setting._value)!); - return node; - } - // incomplete setting - return node; - }); + return [createPolicy(ctx._policyName, policyComponents[0])]; } export function getMatchField(ctx: EnrichCommandContext) { diff --git a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.test.ts b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.test.ts index 55caf36f04c59..4190552d048e2 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.test.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.test.ts @@ -18,6 +18,7 @@ import { statsAggregationFunctionDefinitions } from '../definitions/aggs'; import { chronoLiterals, timeLiterals } from '../definitions/literals'; import { commandDefinitions } from '../definitions/commands'; import { TRIGGER_SUGGESTION_COMMAND } from './factories'; +import { camelCase } from 'lodash'; const triggerCharacters = [',', '(', '=', ' ']; @@ -332,11 +333,13 @@ describe('autocomplete', () => { ); testSuggestions('from ', suggestedIndexes); testSuggestions('from a,', suggestedIndexes); - testSuggestions('from a, b ', ['[metadata $0 ]', '|', ',']); + testSuggestions('from a, b ', ['metadata $0', '|', ',']); testSuggestions('from *,', suggestedIndexes); testSuggestions('from index', suggestedIndexes, 6 /* index index in from */); testSuggestions('from a, b [metadata ]', ['_index', '_score'], 20); + testSuggestions('from a, b metadata ', ['_index', '_score'], 19); testSuggestions('from a, b [metadata _index, ]', ['_score'], 27); + testSuggestions('from a, b metadata _index, ', ['_score'], 26); }); describe('show', () => { @@ -542,11 +545,11 @@ describe('autocomplete', () => { describe('rename', () => { testSuggestions('from a | rename ', getFieldNamesByType('any')); - testSuggestions('from a | rename stringField ', ['as']); + testSuggestions('from a | rename stringField ', ['as $0']); testSuggestions('from a | rename stringField as ', ['var0']); }); - for (const command of ['keep', 'drop', 'project']) { + for (const command of ['keep', 'drop']) { describe(command, () => { testSuggestions(`from a | ${command} `, getFieldNamesByType('any')); testSuggestions( @@ -560,40 +563,52 @@ describe('autocomplete', () => { const allAggFunctions = getFunctionSignaturesByReturnType('stats', 'any', { agg: true, }); - testSuggestions('from a | stats ', ['var0 =', ...allAggFunctions]); + const allEvaFunctions = getFunctionSignaturesByReturnType('stats', 'any', { + evalMath: true, + }); + testSuggestions('from a | stats ', ['var0 =', ...allAggFunctions, ...allEvaFunctions]); testSuggestions('from a | stats a ', ['= $0']); - testSuggestions('from a | stats a=', [...allAggFunctions]); + testSuggestions('from a | stats a=', [...allAggFunctions, ...allEvaFunctions]); testSuggestions('from a | stats a=max(b) by ', [ ...getFieldNamesByType('any'), - ...getFunctionSignaturesByReturnType('eval', 'any', { evalMath: true }), + ...allEvaFunctions, 'var0 =', ]); testSuggestions('from a | stats a=max(b) BY ', [ ...getFieldNamesByType('any'), - ...getFunctionSignaturesByReturnType('eval', 'any', { evalMath: true }), + ...allEvaFunctions, 'var0 =', ]); testSuggestions('from a | stats a=c by d ', ['|', ',']); testSuggestions('from a | stats a=c by d, ', [ ...getFieldNamesByType('any'), - ...getFunctionSignaturesByReturnType('eval', 'any', { evalMath: true }), + ...allEvaFunctions, 'var0 =', ]); - testSuggestions('from a | stats a=max(b), ', ['var0 =', ...allAggFunctions]); + testSuggestions('from a | stats a=max(b), ', [ + 'var0 =', + ...allAggFunctions, + ...allEvaFunctions, + ]); testSuggestions('from a | stats a=min()', getFieldNamesByType('number'), '('); - testSuggestions('from a | stats a=min(b) ', ['by', '|', ',']); + testSuggestions('from a | stats a=min(b) ', ['by $0', '|', ',']); testSuggestions('from a | stats a=min(b) by ', [ ...getFieldNamesByType('any'), - ...getFunctionSignaturesByReturnType('eval', 'any', { evalMath: true }), + ...allEvaFunctions, 'var0 =', ]); - testSuggestions('from a | stats a=min(b),', ['var0 =', ...allAggFunctions]); - testSuggestions('from a | stats var0=min(b),var1=c,', ['var2 =', ...allAggFunctions]); + testSuggestions('from a | stats a=min(b),', ['var0 =', ...allAggFunctions, ...allEvaFunctions]); + testSuggestions('from a | stats var0=min(b),var1=c,', [ + 'var2 =', + ...allAggFunctions, + ...allEvaFunctions, + ]); testSuggestions('from a | stats a=min(b), b=max()', getFieldNamesByType('number')); // @TODO: remove last 2 suggestions if possible testSuggestions('from a | eval var0=round(b), var1=round(c) | stats ', [ 'var2 =', ...allAggFunctions, + ...allEvaFunctions, 'var0', 'var1', ]); @@ -601,7 +616,7 @@ describe('autocomplete', () => { // smoke testing with suggestions not at the end of the string testSuggestions( 'from a | stats a = min(b) | sort b', - ['by', '|', ','], + ['by $0', '|', ','], 27 /* " " after min(b) */ ); testSuggestions( @@ -634,29 +649,25 @@ describe('autocomplete', () => { describe('enrich', () => { const modes = ['any', 'coordinator', 'remote']; + const policyNames = policies.map(({ name, suggestedAs }) => suggestedAs || name); for (const prevCommand of [ '', - '| enrich other-policy ', - '| enrich other-policy on b ', - '| enrich other-policy with c ', + // '| enrich other-policy ', + // '| enrich other-policy on b ', + // '| enrich other-policy with c ', ]) { + testSuggestions(`from a ${prevCommand}| enrich `, policyNames); testSuggestions( - `from a ${prevCommand}| enrich `, - policies.map(({ name, suggestedAs }) => suggestedAs || name) - ); - testSuggestions( - `from a ${prevCommand}| enrich [`, - modes.map((mode) => `ccq.mode:${mode}`), - '[' + `from a ${prevCommand}| enrich _`, + modes.map((mode) => `_${mode}:$0`), + '_' ); - // Not suggesting duplicate setting - testSuggestions(`from a ${prevCommand}| enrich [ccq.mode:any] [`, [], '['); - testSuggestions(`from a ${prevCommand}| enrich [ccq.mode:`, modes, ':'); - testSuggestions( - `from a ${prevCommand}| enrich [ccq.mode:any] `, - policies.map(({ name, suggestedAs }) => suggestedAs || name) - ); - testSuggestions(`from a ${prevCommand}| enrich policy `, ['on', 'with', '|']); + for (const mode of modes) { + testSuggestions(`from a ${prevCommand}| enrich _${mode}:`, policyNames, ':'); + testSuggestions(`from a ${prevCommand}| enrich _${mode.toUpperCase()}:`, policyNames, ':'); + testSuggestions(`from a ${prevCommand}| enrich _${camelCase(mode)}:`, policyNames, ':'); + } + testSuggestions(`from a ${prevCommand}| enrich policy `, ['on $0', 'with $0', '|']); testSuggestions(`from a ${prevCommand}| enrich policy on `, [ 'stringField', 'numberField', @@ -666,7 +677,7 @@ describe('autocomplete', () => { 'any#Char$Field', 'kubernetes.something.something', ]); - testSuggestions(`from a ${prevCommand}| enrich policy on b `, ['with', '|', ',']); + testSuggestions(`from a ${prevCommand}| enrich policy on b `, ['with $0', '|', ',']); testSuggestions(`from a ${prevCommand}| enrich policy on b with `, [ 'var0 =', ...getPolicyFields('policy'), @@ -1083,5 +1094,12 @@ describe('autocomplete', () => { suggestions.every(({ command }) => command === TRIGGER_SUGGESTION_COMMAND) ).toBeTruthy(); }); + it('should trigger further suggestions after enrich mode', async () => { + const suggestions = await getSuggestionsFor('from a | enrich _any:'); + // test that all commands will retrigger suggestions + expect( + suggestions.every(({ command }) => command === TRIGGER_SUGGESTION_COMMAND) + ).toBeTruthy(); + }); }); }); diff --git a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.ts b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.ts index 2f3e997478050..a947ab4d6d7c6 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/autocomplete.ts @@ -14,7 +14,6 @@ import { columnExists, getColumnHit, getCommandDefinition, - getCommandMode, getCommandOption, getFunctionDefinition, getLastCharFromTrimmed, @@ -40,7 +39,6 @@ import type { AstProviderFn, ESQLAstItem, ESQLCommand, - ESQLCommandMode, ESQLCommandOption, ESQLFunction, ESQLSingleAstItem, @@ -70,7 +68,6 @@ import { buildVariablesDefinitions, buildOptionDefinition, buildSettingDefinitions, - buildSettingValueDefinitions, } from './factories'; import { EDITOR_MARKER } from '../shared/constants'; import { getAstContext, removeMarkerArgFromArgsList } from '../shared/context'; @@ -166,9 +163,12 @@ export async function suggest( const unclosedBrackets = unclosedRoundBrackets + unclosedSquaredBrackets; // if it's a comma by the user or a forced trigger by a function argument suggestion // add a marker to make the expression still valid + const charThatNeedMarkers = [',', ':']; if ( - context.triggerCharacter === ',' || - (context.triggerKind === 0 && unclosedRoundBrackets === 0) || + (context.triggerCharacter && charThatNeedMarkers.includes(context.triggerCharacter)) || + (context.triggerKind === 0 && + unclosedRoundBrackets === 0 && + getLastCharFromTrimmed(innerText) !== '_') || (context.triggerCharacter === ' ' && (isMathFunction(innerText, offset) || isComma(innerText[offset - 2]))) ) { @@ -225,18 +225,14 @@ export async function suggest( ); } if (astContext.type === 'setting') { - // need this wrap/unwrap thing to make TS happy - const { setting, ...rest } = astContext; - if (setting && isSettingItem(setting)) { - return getSettingArgsSuggestions( - innerText, - ast, - { setting, ...rest }, - getFieldsByType, - getFieldsMap, - getPolicyMetadata - ); - } + return getSettingArgsSuggestions( + innerText, + ast, + astContext, + getFieldsByType, + getFieldsMap, + getPolicyMetadata + ); } if (astContext.type === 'option') { // need this wrap/unwrap thing to make TS happy @@ -1213,10 +1209,8 @@ async function getSettingArgsSuggestions( { command, node, - setting, }: { command: ESQLCommand; - setting: ESQLCommandMode; node: ESQLSingleAstItem | undefined; }, getFieldsByType: GetFieldsByTypeFn, @@ -1224,25 +1218,15 @@ async function getSettingArgsSuggestions( getPolicyMetadata: GetPolicyMetadataFn ) { const suggestions = []; - const existingSettingArgs = new Set( - command.args - .filter((item) => isSettingItem(item) && !item.incomplete) - .map((item) => (isSettingItem(item) ? item.name : undefined)) - ); - const settingDef = - setting.name && setting.incomplete - ? getCommandMode(setting.name) - : getCommandDefinition(command.name).modes.find(({ name }) => !existingSettingArgs.has(name)); + const settingDefs = getCommandDefinition(command.name).modes; - if (settingDef) { + if (settingDefs.length) { const lastChar = getLastCharFromTrimmed(innerText); - if (lastChar === '[') { - // COMMAND [<here> - suggestions.push(...buildSettingDefinitions(settingDef)); - } else if (lastChar === ':') { - // COMMAND [setting: <here> - suggestions.push(...buildSettingValueDefinitions(settingDef)); + const matchingSettingDefs = settingDefs.filter(({ prefix }) => lastChar === prefix); + if (matchingSettingDefs.length) { + // COMMAND _<here> + suggestions.push(...matchingSettingDefs.flatMap(buildSettingDefinitions)); } } return suggestions; diff --git a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/factories.ts b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/factories.ts index 7fb94f38b962b..85f097a566443 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/autocomplete/factories.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/autocomplete/factories.ts @@ -217,12 +217,8 @@ export const buildOptionDefinition = ( detail: option.description, sortText: 'D', }; - if (option.wrapped) { - completeItem.insertText = `${option.wrapped[0]}${option.name} $0 ${option.wrapped[1]}`; - completeItem.insertTextRules = 4; // monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet; - } - if (isAssignType) { - completeItem.insertText = `${option.name} = $0`; + if (isAssignType || option.signature.params.length) { + completeItem.insertText = isAssignType ? `${option.name} = $0` : `${option.name} $0`; completeItem.insertTextRules = 4; // monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet; completeItem.command = TRIGGER_SUGGESTION_COMMAND; } @@ -233,38 +229,15 @@ export const buildSettingDefinitions = ( setting: CommandModeDefinition ): AutocompleteCommandDefinition[] => { // for now there's just a single setting with one argument - return setting.signature.params.flatMap(({ values, valueDescriptions }) => { - return values!.map((value, i) => { - const completeItem: AutocompleteCommandDefinition = { - label: `${setting.name}:${value}`, - insertText: `${setting.name}:${value}`, - kind: 21, - detail: valueDescriptions - ? `${setting.description} - ${valueDescriptions[i]}` - : setting.description, - sortText: 'D', - }; - return completeItem; - }); - }); -}; - -export const buildSettingValueDefinitions = ( - setting: CommandModeDefinition -): AutocompleteCommandDefinition[] => { - // for now there's just a single setting with one argument - return setting.signature.params.flatMap(({ values, valueDescriptions }) => { - return values!.map((value, i) => { - const completeItem: AutocompleteCommandDefinition = { - label: value, - insertText: value, - kind: 21, - detail: valueDescriptions ? valueDescriptions[i] : setting.description, - sortText: 'D', - }; - return completeItem; - }); - }); + return setting.values.map(({ name, description }) => ({ + label: `${setting.prefix || ''}${name}`, + insertText: `${setting.prefix || ''}${name}:$0`, + insertTextRules: 4, // monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, + kind: 21, + detail: description ? `${setting.description} - ${description}` : setting.description, + sortText: 'D', + command: TRIGGER_SUGGESTION_COMMAND, + })); }; export const buildNoPoliciesAvailableDefinition = (): AutocompleteCommandDefinition => ({ diff --git a/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.test.ts b/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.test.ts index 4a69bb30a9806..4e82def27cb55 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.test.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.test.ts @@ -130,7 +130,7 @@ function testQuickFixesFn( }); } -type TestArgs = [string, string[], { equalityCheck?: 'include' | 'equal' }]; +type TestArgs = [string, string[], { equalityCheck?: 'include' | 'equal' }?]; // Make only and skip work with our custom wrapper const testQuickFixes = Object.assign(testQuickFixesFn, { @@ -184,9 +184,14 @@ describe('quick fixes logic', () => { ]); describe('metafields spellchecks', () => { - testQuickFixes(`FROM index [metadata _i_ndex]`, ['_index']); - testQuickFixes(`FROM index [metadata _id, _i_ndex]`, ['_index']); - testQuickFixes(`FROM index [METADATA _id, _i_ndex]`, ['_index']); + for (const isWrapped of [true, false]) { + function setWrapping(text: string) { + return isWrapped ? `[${text}]` : text; + } + testQuickFixes(`FROM index ${setWrapping('metadata _i_ndex')}`, ['_index']); + testQuickFixes(`FROM index ${setWrapping('metadata _id, _i_ndex')}`, ['_index']); + testQuickFixes(`FROM index ${setWrapping('METADATA _id, _i_ndex')}`, ['_index']); + } }); }); @@ -214,6 +219,15 @@ describe('quick fixes logic', () => { testQuickFixes(`FROM index | ENRICH poli`, ['policy']); testQuickFixes(`FROM index | ENRICH mypolicy`, ['policy']); testQuickFixes(`FROM index | ENRICH policy[`, ['policy', 'policy[]']); + + describe('modes', () => { + testQuickFixes(`FROM index | ENRICH _ann:policy`, ['_any']); + const modes = ['_any', '_coordinator', '_remote']; + for (const mode of modes) { + testQuickFixes(`FROM index | ENRICH ${mode.replace('_', '@')}:policy`, [mode]); + } + testQuickFixes(`FROM index | ENRICH unknown:policy`, modes); + }); }); describe('fixing function spellchecks', () => { @@ -281,4 +295,39 @@ describe('quick fixes logic', () => { testQuickFixes('FROM index | DROP any#Char$Field', ['`any#Char$Field`']); testQuickFixes('FROM index | DROP numberField, any#Char$Field', ['`any#Char$Field`']); }); + + describe('callbacks', () => { + it('should not crash if callback functions are not passed', async () => { + const callbackMocks = getCallbackMocks(); + const statement = `from a | eval b = a | enrich policy | dissect stringField "%{firstWord}"`; + const { model, range } = createModelAndRange(statement); + const { errors } = await validateAst(statement, getAstAndErrors, callbackMocks); + const monacoErrors = wrapAsMonacoMessage('error', statement, errors); + const context = createMonacoContext(monacoErrors); + try { + await getActions(model, range, context, getAstAndErrors, { + getFieldsFor: undefined, + getSources: undefined, + getPolicies: undefined, + getMetaFields: undefined, + }); + } catch { + fail('Should not throw'); + } + }); + + it('should not crash no callbacks are passed', async () => { + const callbackMocks = getCallbackMocks(); + const statement = `from a | eval b = a | enrich policy | dissect stringField "%{firstWord}"`; + const { model, range } = createModelAndRange(statement); + const { errors } = await validateAst(statement, getAstAndErrors, callbackMocks); + const monacoErrors = wrapAsMonacoMessage('error', statement, errors); + const context = createMonacoContext(monacoErrors); + try { + await getActions(model, range, context, getAstAndErrors, undefined); + } catch { + fail('Should not throw'); + } + }); + }); }); diff --git a/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.ts b/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.ts index 5adcd2fdde7c6..6d27682511d57 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/code_actions/actions.ts @@ -13,7 +13,12 @@ import { getPolicyHelper, getSourcesHelper, } from '../shared/resources_helpers'; -import { getAllFunctions, isSourceItem, shouldBeQuotedText } from '../shared/helpers'; +import { + getAllFunctions, + getCommandDefinition, + isSourceItem, + shouldBeQuotedText, +} from '../shared/helpers'; import { ESQLCallbacks } from '../shared/types'; import { AstProviderFn, ESQLAst, ESQLCommand } from '../types'; import { buildQueryForFieldsFromSource } from '../validation/helpers'; @@ -81,25 +86,13 @@ export function getMetaFieldsRetriever( export const getCompatibleFunctionDefinitions = ( command: string, - option: string | undefined, - returnTypes?: string[], - ignored: string[] = [] + option: string | undefined ): string[] => { const fnSupportedByCommand = getAllFunctions({ type: ['eval', 'agg'] }).filter( ({ name, supportedCommands, supportedOptions }) => - (option ? supportedOptions?.includes(option) : supportedCommands.includes(command)) && - !ignored.includes(name) + option ? supportedOptions?.includes(option) : supportedCommands.includes(command) ); - if (!returnTypes) { - return fnSupportedByCommand.map(({ name }) => name); - } - return fnSupportedByCommand - .filter((mathDefinition) => - mathDefinition.signatures.some( - (signature) => returnTypes[0] === 'any' || returnTypes.includes(signature.returnType) - ) - ) - .map(({ name }) => name); + return fnSupportedByCommand.map(({ name }) => name); }; function createAction( @@ -291,6 +284,32 @@ async function getSpellingActionForMetadata( return wrapIntoSpellingChangeAction(error, uri, possibleMetafields); } +async function getSpellingActionForEnrichMode( + error: monaco.editor.IMarkerData, + uri: monaco.Uri, + queryString: string, + ast: ESQLAst, + _callbacks: Callbacks +) { + const errorText = queryString.substring(error.startColumn - 1, error.endColumn - 1); + const commandContext = + ast.find((command) => command.location.max > error.endColumn) || ast[ast.length - 1]; + if (!commandContext) { + return []; + } + const commandDef = getCommandDefinition(commandContext.name); + const allModes = + commandDef.modes?.flatMap(({ values, prefix }) => + values.map(({ name }) => `${prefix || ''}${name}`) + ) || []; + const possibleEnrichModes = await getSpellingPossibilities(async () => allModes, errorText); + // if no possible solution is found, push all modes + if (!possibleEnrichModes.length) { + possibleEnrichModes.push(...allModes); + } + return wrapIntoSpellingChangeAction(error, uri, possibleEnrichModes); +} + function wrapIntoSpellingChangeAction( error: monaco.editor.IMarkerData, uri: monaco.Uri, @@ -414,6 +433,16 @@ export async function getActions( ) ); break; + case 'unsupportedSettingCommandValue': + const enrichModeSpellChanges = await getSpellingActionForEnrichMode( + error, + model.uri, + innerText, + ast, + callbacks + ); + actions.push(...enrichModeSpellChanges); + break; default: break; } diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/builtin.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/builtin.ts index 841d6728fc5ed..c8357574e7fcc 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/builtin.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/builtin.ts @@ -13,13 +13,13 @@ function createMathDefinition( name: string, types: Array<string | string[]>, description: string, - warning?: FunctionDefinition['warning'] + validate?: FunctionDefinition['validate'] ): FunctionDefinition { return { type: 'builtin', name, description, - supportedCommands: ['eval', 'where', 'row'], + supportedCommands: ['eval', 'where', 'row', 'stats'], supportedOptions: ['by'], signatures: types.map((type) => { if (Array.isArray(type)) { @@ -39,7 +39,7 @@ function createMathDefinition( returnType: type, }; }), - warning, + validate, }; } @@ -51,7 +51,7 @@ function createComparisonDefinition( name: string; description: string; }, - warning?: FunctionDefinition['warning'] + validate?: FunctionDefinition['validate'] ): FunctionDefinition { return { type: 'builtin' as const, @@ -59,6 +59,7 @@ function createComparisonDefinition( description, supportedCommands: ['eval', 'where', 'row'], supportedOptions: ['by'], + validate, signatures: [ { params: [ diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts index e405519d79ae9..35e9649f7f189 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts @@ -7,9 +7,15 @@ */ import { i18n } from '@kbn/i18n'; -import { isColumnItem, isSettingItem } from '../shared/helpers'; -import { ESQLColumn, ESQLCommand, ESQLCommandMode, ESQLMessage } from '../types'; -import { ccqMode } from './settings'; +import { + getFunctionDefinition, + isAssignment, + isAssignmentComplete, + isColumnItem, + isFunctionItem, +} from '../shared/helpers'; +import type { ESQLColumn, ESQLCommand, ESQLAstItem, ESQLMessage } from '../types'; +import { enrichModes } from './settings'; import { appendSeparatorOption, asOption, @@ -88,6 +94,64 @@ export const commandDefinitions: CommandDefinition[] = [ code: 'statsNoArguments', }); } + + // now that all functions are supported, there's a specific check to perform + // unfortunately the logic here is a bit complex as it needs to dig deeper into the args + // until an agg function is detected + // in the long run this might be integrated into the validation function + const fnArg = command.args.filter(isFunctionItem); + if (fnArg.length) { + function isAggFunction(arg: ESQLAstItem) { + return isFunctionItem(arg) && getFunctionDefinition(arg.name)?.type === 'agg'; + } + function isOtherFunction(arg: ESQLAstItem) { + return isFunctionItem(arg) && getFunctionDefinition(arg.name)?.type !== 'agg'; + } + function isOtherFunctionWithAggInside(arg: ESQLAstItem) { + return ( + isFunctionItem(arg) && + isOtherFunction(arg) && + arg.args.filter(isFunctionItem).some( + // this is recursive as builtin fns can be wrapped one withins another + (subArg): boolean => + isAggFunction(subArg) || + (isOtherFunction(subArg) ? isOtherFunctionWithAggInside(subArg) : false) + ) + ); + } + // which is the presence of at least one agg type function at root level + const hasAggFunction = fnArg.some(isAggFunction); + // or as builtin function arg with an agg function as sub arg + const hasAggFunctionWithinBuiltin = fnArg + .filter((arg) => !isAssignment(arg)) + .some(isOtherFunctionWithAggInside); + + // assignment requires a special handling + const hasAggFunctionWithinAssignment = fnArg + .filter((arg) => isAssignment(arg) && isAssignmentComplete(arg)) + // extract the right hand side of the assignments + .flatMap((arg) => arg.args[1]) + .filter(isFunctionItem) + // now check that they are either agg functions + // or builtin functions with an agg function as sub arg + .some((arg) => isAggFunction(arg) || isOtherFunctionWithAggInside(arg)); + + if (!hasAggFunction && !hasAggFunctionWithinBuiltin && !hasAggFunctionWithinAssignment) { + messages.push({ + location: command.location, + text: i18n.translate('monaco.esql.validation.noNestedArgumentSupport', { + defaultMessage: + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [{name}] of type [{argType}]", + values: { + name: fnArg[0].name, + argType: getFunctionDefinition(fnArg[0].name)?.signatures[0].returnType, + }, + }), + type: 'error', + code: 'noNestedArgumentSupport', + }); + } + } return messages; }, }, @@ -149,22 +213,6 @@ export const commandDefinitions: CommandDefinition[] = [ multipleParams: true, params: [{ name: 'column', type: 'column', wildcards: true }], }, - validate: (command: ESQLCommand) => { - // the command name is automatically converted into KEEP by the ast_walker - // so validate the actual text - const messages: ESQLMessage[] = []; - if (/^project/.test(command.text.toLowerCase())) { - messages.push({ - location: command.location, - text: i18n.translate('monaco.esql.validation.projectCommandDeprecated', { - defaultMessage: 'PROJECT command is no longer supported, please use KEEP instead', - }), - type: 'warning', - code: 'projectCommandDeprecated', - }); - } - return messages; - }, }, { name: 'drop', @@ -304,41 +352,10 @@ export const commandDefinitions: CommandDefinition[] = [ '… | enrich my-policy on pivotField with a = enrichFieldA, b = enrichFieldB', ], options: [onOption, withOption], - modes: [ccqMode], + modes: [enrichModes], signature: { multipleParams: false, params: [{ name: 'policyName', type: 'source', innerType: 'policy' }], }, - validate: (command: ESQLCommand) => { - const messages: ESQLMessage[] = []; - if (command.args.some(isSettingItem)) { - const settings = command.args.filter(isSettingItem); - const settingCounters: Record<string, number> = {}; - const settingLookup: Record<string, ESQLCommandMode> = {}; - for (const setting of settings) { - if (!settingCounters[setting.name]) { - settingCounters[setting.name] = 0; - settingLookup[setting.name] = setting; - } - settingCounters[setting.name]++; - } - const duplicateSettings = Object.entries(settingCounters).filter(([_, count]) => count > 1); - messages.push( - ...duplicateSettings.map(([name]) => ({ - location: settingLookup[name].location, - text: i18n.translate('monaco.esql.validation.duplicateSettingWarning', { - defaultMessage: - 'Multiple definition of setting [{name}]. Only last one will be applied.', - values: { - name, - }, - }), - type: 'warning' as const, - code: 'duplicateSettingWarning', - })) - ); - } - return messages; - }, }, ]; diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts index 25cc3ce27d77c..64382fa831a64 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts @@ -7,8 +7,32 @@ */ import { i18n } from '@kbn/i18n'; +import { isLiteralItem } from '../shared/helpers'; +import { ESQLFunction } from '../types'; import { FunctionDefinition } from './types'; +const validateLogFunctions = (fnDef: ESQLFunction) => { + const messages = []; + // do not really care here about the base and field + // just need to check both values are not negative + for (const arg of fnDef.args) { + if (isLiteralItem(arg) && arg.value < 0) { + messages.push({ + type: 'warning' as const, + code: 'logOfNegativeValue', + text: i18n.translate('monaco.esql.divide.warning.logOfNegativeValue', { + defaultMessage: 'Log of a negative number results in null: {value}', + values: { + value: arg.value, + }, + }), + location: arg.location, + }); + } + } + return messages; +}; + export const evalFunctionsDefinitions: FunctionDefinition[] = [ { name: 'round', @@ -68,6 +92,29 @@ export const evalFunctionsDefinitions: FunctionDefinition[] = [ examples: [`from index | eval log10_value = log10(field)`], }, ], + validate: validateLogFunctions, + }, + + { + name: 'log', + description: i18n.translate('monaco.esql.definitions.logDoc', { + defaultMessage: + 'A scalar function log(based, value) returns the logarithm of a value for a particular base, as specified in the argument', + }), + signatures: [ + { + params: [ + { name: 'baseOrField', type: 'number' }, + { name: 'field', type: 'number', optional: true }, + ], + returnType: 'number', + examples: [ + `from index | eval log2_value = log(2, field)`, + `from index | eval loge_value = log(field)`, + ], + }, + ], + validate: validateLogFunctions, }, { name: 'pow', @@ -1050,7 +1097,7 @@ export const evalFunctionsDefinitions: FunctionDefinition[] = [ .sort(({ name: a }, { name: b }) => a.localeCompare(b)) .map((def) => ({ ...def, - supportedCommands: ['eval', 'where', 'row'], + supportedCommands: ['stats', 'eval', 'where', 'row'], supportedOptions: ['by'], type: 'eval', })); diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/options.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/options.ts index efcfbb9c60243..cac6978970ce0 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/options.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/options.ts @@ -33,10 +33,20 @@ export const metadataOption: CommandOptionsDefinition = { params: [{ name: 'column', type: 'column' }], }, optional: true, - wrapped: ['[', ']'], skipCommonValidation: true, validate: (option, command, references) => { const messages: ESQLMessage[] = []; + // need to test the parent command here + if (/\[metadata/i.test(command.text)) { + messages.push({ + location: option.location, + text: i18n.translate('monaco.esql.validation.metadataBracketsDeprecation', { + defaultMessage: "Square brackets '[]' need to be removed from FROM METADATA declaration", + }), + type: 'warning', + code: 'metadataBracketsDeprecation', + }); + } const fields = option.args.filter(isColumnItem); const metadataFieldsAvailable = references as unknown as Set<string>; if (metadataFieldsAvailable.size > 0) { diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/settings.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/settings.ts index 5dad48913c408..4c76a87d9283c 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/settings.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/settings.ts @@ -9,30 +9,30 @@ import { i18n } from '@kbn/i18n'; import { CommandModeDefinition } from './types'; -export const ccqMode: CommandModeDefinition = { +export const enrichModes: CommandModeDefinition = { name: 'ccq.mode', description: i18n.translate('monaco.esql.definitions.ccqModeDoc', { defaultMessage: 'Cross-clusters query mode', }), - signature: { - multipleParams: false, - params: [ - { - name: 'mode', - type: 'string', - values: ['any', 'coordinator', 'remote'], - valueDescriptions: [ - i18n.translate('monaco.esql.definitions.ccqAnyDoc', { - defaultMessage: 'Enrich takes place on any cluster', - }), - i18n.translate('monaco.esql.definitions.ccqCoordinatorDoc', { - defaultMessage: 'Enrich takes place on the coordinating cluster receiving an ES|QL', - }), - i18n.translate('monaco.esql.definitions.ccqRemoteDoc', { - defaultMessage: 'Enrich takes place on the cluster hosting the target index.', - }), - ], - }, - ], - }, + prefix: '_', + values: [ + { + name: 'any', + description: i18n.translate('monaco.esql.definitions.ccqAnyDoc', { + defaultMessage: 'Enrich takes place on any cluster', + }), + }, + { + name: 'coordinator', + description: i18n.translate('monaco.esql.definitions.ccqCoordinatorDoc', { + defaultMessage: 'Enrich takes place on the coordinating cluster receiving an ES|QL', + }), + }, + { + name: 'remote', + description: i18n.translate('monaco.esql.definitions.ccqRemoteDoc', { + defaultMessage: 'Enrich takes place on the cluster hosting the target index.', + }), + }, + ], }; diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/types.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/types.ts index f77afa8731bb7..0c086cfe5e679 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/types.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/types.ts @@ -29,7 +29,7 @@ export interface FunctionDefinition { returnType: string; examples?: string[]; }>; - warning?: (fnDef: ESQLFunction) => ESQLMessage[]; + validate?: (fnDef: ESQLFunction) => ESQLMessage[]; } export interface CommandBaseDefinition { @@ -64,9 +64,11 @@ export interface CommandOptionsDefinition extends CommandBaseDefinition { ) => ESQLMessage[]; } -export interface CommandModeDefinition extends CommandBaseDefinition { +export interface CommandModeDefinition { name: string; description: string; + values: Array<{ name: string; description: string }>; + prefix?: string; } export interface CommandDefinition extends CommandBaseDefinition { diff --git a/packages/kbn-monaco/src/esql/lib/ast/hover/hover.test.ts b/packages/kbn-monaco/src/esql/lib/ast/hover/hover.test.ts index 9acc9039ec81f..960adfeba0a25 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/hover/hover.test.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/hover/hover.test.ts @@ -14,6 +14,7 @@ import { AstListener } from '../ast_factory'; import { getHoverItem } from './hover'; import { getFunctionDefinition } from '../shared/helpers'; import { getFunctionSignatures } from '../definitions/helpers'; +import { enrichModes } from '../definitions/settings'; const fields: Array<{ name: string; type: string; suggestedAs?: string }> = [ ...['string', 'number', 'date', 'boolean', 'ip'].map((type) => ({ @@ -187,6 +188,16 @@ describe('hover', () => { testSuggestions(`from a | enrich policy`, 'policy', createPolicyContent); testSuggestions(`from a | enrich policy on b `, 'policy', createPolicyContent); testSuggestions(`from a | enrich policy on b `, 'non-policy', createPolicyContent); + + describe('ccq mode', () => { + for (const mode of enrichModes.values) { + testSuggestions( + `from a | enrich ${enrichModes.prefix || ''}${mode.name}:policy`, + `${enrichModes.prefix || ''}${mode.name}`, + () => [enrichModes.description, `**${mode.name}**: ${mode.description}`] + ); + } + }); }); describe('functions', () => { function createFunctionContent(fn: string) { diff --git a/packages/kbn-monaco/src/esql/lib/ast/hover/hover.ts b/packages/kbn-monaco/src/esql/lib/ast/hover/hover.ts index c612571e13ce7..bcc2f8c76ec8a 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/hover/hover.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/hover/hover.ts @@ -10,7 +10,13 @@ import { i18n } from '@kbn/i18n'; import type { monaco } from '../../../../monaco_imports'; import { getFunctionSignatures } from '../definitions/helpers'; import { getAstContext } from '../shared/context'; -import { monacoPositionToOffset, getFunctionDefinition, isSourceItem } from '../shared/helpers'; +import { + monacoPositionToOffset, + getFunctionDefinition, + isSourceItem, + isSettingItem, + getCommandDefinition, +} from '../shared/helpers'; import { getPolicyHelper } from '../shared/resources_helpers'; import { ESQLCallbacks } from '../shared/types'; import type { AstProviderFn } from '../types'; @@ -47,32 +53,47 @@ export async function getHoverItem( } if (astContext.type === 'expression') { - if ( - astContext.node && - isSourceItem(astContext.node) && - astContext.node.sourceType === 'policy' - ) { - const policyMetadata = await getPolicyMetadata(astContext.node.name); - if (policyMetadata) { - return { - contents: [ - { - value: `${i18n.translate('monaco.esql.hover.policyIndexes', { - defaultMessage: '**Indexes**', - })}: ${policyMetadata.sourceIndices.join(', ')}`, - }, - { - value: `${i18n.translate('monaco.esql.hover.policyMatchingField', { - defaultMessage: '**Matching field**', - })}: ${policyMetadata.matchField}`, - }, - { - value: `${i18n.translate('monaco.esql.hover.policyEnrichedFields', { - defaultMessage: '**Fields**', - })}: ${policyMetadata.enrichFields.join(', ')}`, - }, - ], - }; + if (astContext.node) { + if (isSourceItem(astContext.node) && astContext.node.sourceType === 'policy') { + const policyMetadata = await getPolicyMetadata(astContext.node.name); + if (policyMetadata) { + return { + contents: [ + { + value: `${i18n.translate('monaco.esql.hover.policyIndexes', { + defaultMessage: '**Indexes**', + })}: ${policyMetadata.sourceIndices.join(', ')}`, + }, + { + value: `${i18n.translate('monaco.esql.hover.policyMatchingField', { + defaultMessage: '**Matching field**', + })}: ${policyMetadata.matchField}`, + }, + { + value: `${i18n.translate('monaco.esql.hover.policyEnrichedFields', { + defaultMessage: '**Fields**', + })}: ${policyMetadata.enrichFields.join(', ')}`, + }, + ], + }; + } + } + if (isSettingItem(astContext.node)) { + const commandDef = getCommandDefinition(astContext.command.name); + const settingDef = commandDef?.modes.find(({ values }) => + values.some(({ name }) => name === astContext.node!.name) + ); + if (settingDef) { + const mode = settingDef.values.find(({ name }) => name === astContext.node!.name)!; + return { + contents: [ + { value: settingDef.description }, + { + value: `**${mode.name}**: ${mode.description}`, + }, + ], + }; + } } } } diff --git a/packages/kbn-monaco/src/esql/lib/ast/shared/context.ts b/packages/kbn-monaco/src/esql/lib/ast/shared/context.ts index aecf9340b945c..d81c65184c8c5 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/shared/context.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/shared/context.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { enrichModes } from '../definitions/settings'; import type { ESQLAstItem, ESQLSingleAstItem, @@ -152,8 +153,9 @@ export function getAstContext(innerText: string, ast: ESQLAst, offset: number) { // command ... by <here> return { type: 'option' as const, command, node, option, setting }; } - if (node.type === 'mode' || option) { - // command [<here> + // for now it's only an enrich thing + if (node.type === 'source' && node.text === enrichModes.prefix) { + // command _<here> return { type: 'setting' as const, command, node, option, setting }; } } @@ -184,9 +186,6 @@ export function getAstContext(innerText: string, ast: ESQLAst, offset: number) { if (option) { return { type: 'option' as const, command, node, option, setting }; } - if (setting?.incomplete) { - return { type: 'setting' as const, command, node, option, setting }; - } } // command a ... <here> OR command a = ... <here> diff --git a/packages/kbn-monaco/src/esql/lib/ast/shared/helpers.ts b/packages/kbn-monaco/src/esql/lib/ast/shared/helpers.ts index f4c73a3f95776..ec51d4ec66c90 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/shared/helpers.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/shared/helpers.ts @@ -22,10 +22,8 @@ import { withOption, appendSeparatorOption, } from '../definitions/options'; -import { ccqMode } from '../definitions/settings'; import { CommandDefinition, - CommandModeDefinition, CommandOptionsDefinition, FunctionDefinition, SignatureArgType, @@ -219,10 +217,6 @@ export function getCommandOption(optionName: CommandOptionsDefinition['name']) { ); } -export function getCommandMode(settingName: CommandModeDefinition['name']) { - return [ccqMode].find(({ name }) => name === settingName); -} - function compareLiteralType(argTypes: string, item: ESQLLiteral) { if (item.literalType !== 'string') { return argTypes === item.literalType; diff --git a/packages/kbn-monaco/src/esql/lib/ast/types.ts b/packages/kbn-monaco/src/esql/lib/ast/types.ts index da5bff7551cad..32057a9ee3b65 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/types.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/types.ts @@ -46,7 +46,6 @@ export interface ESQLCommandOption extends ESQLAstBaseItem { export interface ESQLCommandMode extends ESQLAstBaseItem { type: 'mode'; - args: ESQLAstItem[]; } export interface ESQLFunction extends ESQLAstBaseItem { diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/errors.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/errors.ts index f04d3d0eb9b22..0749c16496c94 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/errors.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/errors.ts @@ -59,8 +59,13 @@ function getMessageAndTypeFromId<K extends ErrorTypes>({ return { message: i18n.translate('monaco.esql.validation.wrongArgumentNumber', { defaultMessage: - 'Error building [{fn}]: expects exactly {numArgs, plural, one {one argument} other {{numArgs} arguments}}, passed {passedArgs} instead.', - values: { fn: out.fn, numArgs: out.numArgs, passedArgs: out.passedArgs }, + 'Error building [{fn}]: expects {canHaveMoreArgs, plural, =0 {exactly } other {}}{numArgs, plural, one {one argument} other {{numArgs} arguments}}, passed {passedArgs} instead.', + values: { + fn: out.fn, + numArgs: out.numArgs, + passedArgs: out.passedArgs, + canHaveMoreArgs: out.exactly, + }, }), }; case 'noNestedArgumentSupport': @@ -209,9 +214,8 @@ function getMessageAndTypeFromId<K extends ErrorTypes>({ return { message: i18n.translate('monaco.esql.validation.unsupportedSettingValue', { defaultMessage: - 'Unrecognized value [{value}], {command} [{setting}] needs to be one of [{expected}]', + 'Unrecognized value [{value}] for {command}, mode needs to be one of [{expected}]', values: { - setting: out.setting, expected: out.expected, value: out.value, command: out.command, diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/resources.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/resources.ts index 76806b5385513..85133e81fd4e9 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/resources.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/resources.ts @@ -101,7 +101,7 @@ export async function retrieveFieldsFromStringSources( commands: ESQLCommand[], callbacks?: ESQLCallbacks ): Promise<Map<string, ESQLRealField>> { - if (!callbacks) { + if (!callbacks || !callbacks?.getMetaFields) { return new Map(); } const customQuery = buildQueryForFieldsForStringSources(queryString, commands); diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/types.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/types.ts index 04b40a5bfbbac..d632d3a31d085 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/types.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/types.ts @@ -47,7 +47,7 @@ export interface ValidationErrors { }; wrongArgumentNumber: { message: string; - type: { fn: string; numArgs: number; passedArgs: number }; + type: { fn: string; numArgs: number; passedArgs: number; exactly: number }; }; unknownColumn: { message: string; @@ -123,7 +123,7 @@ export interface ValidationErrors { }; unsupportedSettingCommandValue: { message: string; - type: { command: string; setting: string; value: string; expected: string }; + type: { command: string; value: string; expected: string }; }; } diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts index c1ea7d1bdec8c..7c339a8ab9fb8 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts @@ -27,21 +27,26 @@ const fieldTypes = ['number', 'date', 'boolean', 'ip', 'string', 'cartesian_poin function getCallbackMocks() { return { - getFieldsFor: jest.fn(async ({ query }) => - /enrich/.test(query) - ? [ - { name: 'otherField', type: 'string' }, - { name: 'yetAnotherField', type: 'number' }, - ] - : /unsupported_index/.test(query) - ? [{ name: 'unsupported_field', type: 'unsupported' }] - : [ - ...fieldTypes.map((type) => ({ name: `${camelCase(type)}Field`, type })), - { name: 'any#Char$Field', type: 'number' }, - { name: 'kubernetes.something.something', type: 'number' }, - { name: '@timestamp', type: 'date' }, - ] - ), + getFieldsFor: jest.fn(async ({ query }) => { + if (/enrich/.test(query)) { + return [ + { name: 'otherField', type: 'string' }, + { name: 'yetAnotherField', type: 'number' }, + ]; + } + if (/unsupported_index/.test(query)) { + return [{ name: 'unsupported_field', type: 'unsupported' }]; + } + if (/dissect|grok/.test(query)) { + return [{ name: 'firstWord', type: 'string' }]; + } + return [ + ...fieldTypes.map((type) => ({ name: `${camelCase(type)}Field`, type })), + { name: 'any#Char$Field', type: 'number' }, + { name: 'kubernetes.something.something', type: 'number' }, + { name: '@timestamp', type: 'date' }, + ]; + }), getSources: jest.fn(async () => ['a', 'index', 'otherIndex', '.secretIndex', 'my-index', 'unsupported_index'].map((name) => ({ name, @@ -250,7 +255,7 @@ describe('validation logic', () => { "SyntaxError: missing {QUOTED_IDENTIFIER, FROM_UNQUOTED_IDENTIFIER} at '<EOF>'", ]); testErrorsAndWarnings(`from assignment = 1`, [ - 'SyntaxError: expected {<EOF>, PIPE, COMMA, OPENING_BRACKET} but found "="', + 'SyntaxError: expected {<EOF>, PIPE, COMMA, OPENING_BRACKET, METADATA} but found "="', 'Unknown index [assignment]', ]); testErrorsAndWarnings(`from index`, []); @@ -262,21 +267,53 @@ describe('validation logic', () => { testErrorsAndWarnings(`from index, missingIndex`, ['Unknown index [missingIndex]']); testErrorsAndWarnings(`from fn()`, ['Unknown index [fn()]']); testErrorsAndWarnings(`from average()`, ['Unknown index [average()]']); - testErrorsAndWarnings(`from index [METADATA _id]`, []); - testErrorsAndWarnings(`from index [metadata _id]`, []); + for (const isWrapped of [true, false]) { + function setWrapping(option: string) { + return isWrapped ? `[${option}]` : option; + } + function addBracketsWarning() { + return isWrapped + ? ["Square brackets '[]' need to be removed from FROM METADATA declaration"] + : []; + } + testErrorsAndWarnings(`from index ${setWrapping('METADATA _id')}`, [], addBracketsWarning()); + testErrorsAndWarnings(`from index ${setWrapping('metadata _id')}`, [], addBracketsWarning()); - testErrorsAndWarnings(`from index [METADATA _id, _source]`, []); - testErrorsAndWarnings(`from index [METADATA _id, _source2]`, [ - 'Metadata field [_source2] is not available. Available metadata fields are: [_id, _source]', - ]); - testErrorsAndWarnings(`from index [metadata _id, _source] [METADATA _id2]`, [ - 'SyntaxError: expected {<EOF>, PIPE} but found "["', - ]); - testErrorsAndWarnings(`from index metadata _id`, [ - 'SyntaxError: expected {<EOF>, PIPE, COMMA, OPENING_BRACKET} but found "metadata"', - ]); + testErrorsAndWarnings( + `from index ${setWrapping('METADATA _id, _source')}`, + [], + addBracketsWarning() + ); + testErrorsAndWarnings( + `from index ${setWrapping('METADATA _id, _source2')}`, + [ + 'Metadata field [_source2] is not available. Available metadata fields are: [_id, _source]', + ], + addBracketsWarning() + ); + testErrorsAndWarnings( + `from index ${setWrapping('metadata _id, _source')} ${setWrapping('METADATA _id2')}`, + [ + isWrapped + ? 'SyntaxError: expected {COMMA, CLOSING_BRACKET} but found "["' + : 'SyntaxError: expected {<EOF>, PIPE, COMMA} but found "METADATA"', + ], + addBracketsWarning() + ); + + testErrorsAndWarnings( + `from remote-ccs:indexes ${setWrapping('METADATA _id')}`, + [], + addBracketsWarning() + ); + testErrorsAndWarnings( + `from *:indexes ${setWrapping('METADATA _id')}`, + [], + addBracketsWarning() + ); + } testErrorsAndWarnings(`from index (metadata _id)`, [ - 'SyntaxError: expected {<EOF>, PIPE, COMMA, OPENING_BRACKET} but found "(metadata"', + 'SyntaxError: expected {<EOF>, PIPE, COMMA, OPENING_BRACKET, METADATA} but found "(metadata"', ]); testErrorsAndWarnings(`from ind*, other*`, []); testErrorsAndWarnings(`from index*`, []); @@ -289,8 +326,6 @@ describe('validation logic', () => { testErrorsAndWarnings(`from remote-*:indexes`, []); testErrorsAndWarnings(`from remote-ccs:indexes`, []); testErrorsAndWarnings(`from a, remote-ccs:indexes`, []); - testErrorsAndWarnings(`from remote-ccs:indexes [METADATA _id]`, []); - testErrorsAndWarnings(`from *:indexes [METADATA _id]`, []); testErrorsAndWarnings('from .secretIndex', []); testErrorsAndWarnings('from my-index', []); testErrorsAndWarnings('from numberField', ['Unknown index [numberField]']); @@ -374,7 +409,7 @@ describe('validation logic', () => { ); testErrorsAndWarnings(`row var = ${signatureStringCorrect}`, []); - testErrorsAndWarnings(`row ${signatureStringCorrect}`); + testErrorsAndWarnings(`row ${signatureStringCorrect}`, []); if (alias) { for (const otherName of alias) { @@ -412,7 +447,7 @@ describe('validation logic', () => { )[0].declaration ); - testErrorsAndWarnings(`row var = ${signatureString}`); + testErrorsAndWarnings(`row var = ${signatureString}`, []); const wrongFieldMapping = params.map(({ name: _name, type, ...rest }) => { const typeString = type; @@ -580,26 +615,18 @@ describe('validation logic', () => { 'Unknown column [missingField]', ]); testErrorsAndWarnings('from index | keep `any#Char$Field`', []); - testErrorsAndWarnings( - 'from index | project ', - [`SyntaxError: missing {QUOTED_IDENTIFIER, UNQUOTED_ID_PATTERN} at '<EOF>'`], - ['PROJECT command is no longer supported, please use KEEP instead'] - ); - testErrorsAndWarnings( - 'from index | project stringField, numberField, dateField', - [], - ['PROJECT command is no longer supported, please use KEEP instead'] - ); - testErrorsAndWarnings( - 'from index | PROJECT stringField, numberField, dateField', - [], - ['PROJECT command is no longer supported, please use KEEP instead'] - ); - testErrorsAndWarnings( - 'from index | project missingField, numberField, dateField', - ['Unknown column [missingField]'], - ['PROJECT command is no longer supported, please use KEEP instead'] - ); + testErrorsAndWarnings('from index | project ', [ + `SyntaxError: expected {DISSECT, DROP, ENRICH, EVAL, GROK, INLINESTATS, KEEP, LIMIT, MV_EXPAND, RENAME, SORT, STATS, WHERE} but found \"project\"`, + ]); + testErrorsAndWarnings('from index | project stringField, numberField, dateField', [ + `SyntaxError: expected {DISSECT, DROP, ENRICH, EVAL, GROK, INLINESTATS, KEEP, LIMIT, MV_EXPAND, RENAME, SORT, STATS, WHERE} but found \"project\"`, + ]); + testErrorsAndWarnings('from index | PROJECT stringField, numberField, dateField', [ + `SyntaxError: expected {DISSECT, DROP, ENRICH, EVAL, GROK, INLINESTATS, KEEP, LIMIT, MV_EXPAND, RENAME, SORT, STATS, WHERE} but found \"PROJECT\"`, + ]); + testErrorsAndWarnings('from index | project missingField, numberField, dateField', [ + `SyntaxError: expected {DISSECT, DROP, ENRICH, EVAL, GROK, INLINESTATS, KEEP, LIMIT, MV_EXPAND, RENAME, SORT, STATS, WHERE} but found \"project\"`, + ]); testErrorsAndWarnings('from index | keep s*', []); testErrorsAndWarnings('from index | keep *Field', []); testErrorsAndWarnings('from index | keep s*Field', []); @@ -736,27 +763,28 @@ describe('validation logic', () => { "SyntaxError: missing STRING at '%'", ]); // Do not try to validate the dissect pattern string - testErrorsAndWarnings('from a | dissect stringField "%{a}"', []); - testErrorsAndWarnings('from a | dissect numberField "%{a}"', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}"', []); + testErrorsAndWarnings('from a | dissect numberField "%{firstWord}"', [ 'DISSECT only supports string type values, found [numberField] of type number', ]); - testErrorsAndWarnings('from a | dissect stringField "%{a}" option ', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" option ', [ 'SyntaxError: expected {ASSIGN} but found "<EOF>"', ]); - testErrorsAndWarnings('from a | dissect stringField "%{a}" option = ', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" option = ', [ 'SyntaxError: expected {STRING, INTEGER_LITERAL, DECIMAL_LITERAL, FALSE, NULL, PARAM, TRUE, PLUS, MINUS, OPENING_BRACKET} but found "<EOF>"', 'Invalid option for DISSECT: [option]', ]); - testErrorsAndWarnings('from a | dissect stringField "%{a}" option = 1', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" option = 1', [ 'Invalid option for DISSECT: [option]', ]); - testErrorsAndWarnings('from a | dissect stringField "%{a}" append_separator = "-"', []); - testErrorsAndWarnings('from a | dissect stringField "%{a}" ignore_missing = true', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" append_separator = "-"', []); + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" ignore_missing = true', [ 'Invalid option for DISSECT: [ignore_missing]', ]); - testErrorsAndWarnings('from a | dissect stringField "%{a}" append_separator = true', [ + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" append_separator = true', [ 'Invalid value for DISSECT append_separator: expected a string, but was [true]', ]); + testErrorsAndWarnings('from a | dissect stringField "%{firstWord}" | keep firstWord', []); // testErrorsAndWarnings('from a | dissect s* "%{a}"', [ // 'Using wildcards (*) in dissect is not allowed [s*]', // ]); @@ -776,10 +804,11 @@ describe('validation logic', () => { ]); testErrorsAndWarnings('from a | grok stringField %a', ["SyntaxError: missing STRING at '%'"]); // Do not try to validate the grok pattern string - testErrorsAndWarnings('from a | grok stringField "%{a}"', []); - testErrorsAndWarnings('from a | grok numberField "%{a}"', [ + testErrorsAndWarnings('from a | grok stringField "%{firstWord}"', []); + testErrorsAndWarnings('from a | grok numberField "%{firstWord}"', [ 'GROK only supports string type values, found [numberField] of type number', ]); + testErrorsAndWarnings('from a | grok stringField "%{firstWord}" | keep firstWord', []); // testErrorsAndWarnings('from a | grok s* "%{a}"', [ // 'Using wildcards (*) in grok is not allowed [s*]', // ]); @@ -1047,7 +1076,7 @@ describe('validation logic', () => { } for (const { name, alias, signatures, ...defRest } of evalFunctionsDefinitions) { - for (const { params, returnType } of signatures) { + for (const { params, returnType, infiniteParams, minParams } of signatures) { const fieldMapping = getFieldMapping(params); testErrorsAndWarnings( `from a | eval var = ${ @@ -1128,6 +1157,40 @@ describe('validation logic', () => { }`, expectedErrors ); + + if (!infiniteParams && !minParams) { + // test that additional args are spotted + const fieldMappingWithOneExtraArg = getFieldMapping(params).concat({ + name: 'extraArg', + type: 'number', + }); + // get the expected args from the first signature in case of errors + const expectedArgs = signatures[0].params.filter(({ optional }) => !optional).length; + const shouldBeExactly = signatures[0].params.length; + testErrorsAndWarnings( + `from a | eval ${ + getFunctionSignatures( + { + name, + ...defRest, + signatures: [{ params: fieldMappingWithOneExtraArg, returnType }], + }, + { withTypes: false } + )[0].declaration + }`, + [ + `Error building [${name}]: expects ${ + shouldBeExactly - expectedArgs === 0 ? 'exactly ' : '' + }${ + expectedArgs === 1 + ? 'one argument' + : expectedArgs === 0 + ? '0 arguments' + : `${expectedArgs} arguments` + }, passed ${fieldMappingWithOneExtraArg.length} instead.`, + ] + ); + } } // test that wildcard won't work as arg @@ -1151,6 +1214,37 @@ describe('validation logic', () => { } } } + testErrorsAndWarnings( + 'from a | eval log10(-1)', + [], + ['Log of a negative number results in null: -1'] + ); + testErrorsAndWarnings( + 'from a | eval log(-1)', + [], + ['Log of a negative number results in null: -1'] + ); + testErrorsAndWarnings( + 'from a | eval log(-1, 20)', + [], + ['Log of a negative number results in null: -1'] + ); + testErrorsAndWarnings( + 'from a | eval log(-1, -20)', + [], + [ + 'Log of a negative number results in null: -1', + 'Log of a negative number results in null: -20', + ] + ); + testErrorsAndWarnings( + 'from a | eval var0 = log(-1, -20)', + [], + [ + 'Log of a negative number results in null: -1', + 'Log of a negative number results in null: -20', + ] + ); for (const op of ['>', '>=', '<', '<=', '==']) { testErrorsAndWarnings(`from a | eval numberField ${op} 0`, []); testErrorsAndWarnings(`from a | eval NOT numberField ${op} 0`, []); @@ -1304,9 +1398,11 @@ describe('validation logic', () => { ]); testErrorsAndWarnings('from a | stats numberField=', [ 'SyntaxError: expected {STRING, INTEGER_LITERAL, DECIMAL_LITERAL, FALSE, LP, NOT, NULL, PARAM, TRUE, PLUS, MINUS, OPENING_BRACKET, UNQUOTED_IDENTIFIER, QUOTED_IDENTIFIER} but found "<EOF>"', + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [=] of type [void]", ]); testErrorsAndWarnings('from a | stats numberField=5 by ', [ 'SyntaxError: expected {STRING, INTEGER_LITERAL, DECIMAL_LITERAL, FALSE, LP, NOT, NULL, PARAM, TRUE, PLUS, MINUS, OPENING_BRACKET, UNQUOTED_IDENTIFIER, QUOTED_IDENTIFIER} but found "<EOF>"', + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [=] of type [void]", ]); testErrorsAndWarnings('from a | stats avg(numberField) by wrongField', [ 'Unknown column [wrongField]', @@ -1347,6 +1443,12 @@ describe('validation logic', () => { 'from a | stats avg(numberField), percentile(numberField, 50) BY ipField', [] ); + for (const op of ['+', '-', '*', '/', '%']) { + testErrorsAndWarnings( + `from a | stats avg(numberField) ${op} percentile(numberField, 50) BY ipField`, + [] + ); + } testErrorsAndWarnings('from a | stats count(* + 1) BY ipField', [ 'SyntaxError: expected {STRING, INTEGER_LITERAL, DECIMAL_LITERAL, FALSE, LP, NOT, NULL, PARAM, TRUE, PLUS, MINUS, OPENING_BRACKET, UNQUOTED_IDENTIFIER, QUOTED_IDENTIFIER} but found "+"', ]); @@ -1359,15 +1461,33 @@ describe('validation logic', () => { testErrorsAndWarnings('from a | stats count(count(*)) BY ipField', [ `Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [count(*)] of type [number]`, ]); - testErrorsAndWarnings('from a | stats numberField + 1', ['STATS does not support function +']); + testErrorsAndWarnings('from a | stats numberField + 1', [ + `Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [+] of type [number]`, + ]); + + for (const nesting of [1, 2, 3, 4]) { + const moreBuiltinWrapping = Array(nesting).fill('+ 1').join(''); + testErrorsAndWarnings(`from a | stats 5 + avg(numberField) ${moreBuiltinWrapping}`, []); + testErrorsAndWarnings(`from a | stats 5 ${moreBuiltinWrapping} + avg(numberField)`, []); + testErrorsAndWarnings(`from a | stats 5 ${moreBuiltinWrapping} + numberField`, [ + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [+] of type [number]", + ]); + testErrorsAndWarnings(`from a | stats 5 + numberField ${moreBuiltinWrapping}`, [ + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [+] of type [number]", + ]); + } + + testErrorsAndWarnings('from a | stats 5 + numberField + 1', [ + "Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [+] of type [number]", + ]); testErrorsAndWarnings('from a | stats numberField + 1 by ipField', [ - 'STATS does not support function +', + `Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [+] of type [number]`, ]); testErrorsAndWarnings( 'from a | stats avg(numberField), percentile(numberField, 50) + 1 by ipField', - ['STATS does not support function +'] + [] ); testErrorsAndWarnings('from a | stats count(*)', []); @@ -1400,6 +1520,52 @@ describe('validation logic', () => { }`, [] ); + testErrorsAndWarnings( + `from a | stats var = round(${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + })`, + [] + ); + testErrorsAndWarnings( + `from a | stats round(${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + })`, + [] + ); + testErrorsAndWarnings( + `from a | stats var = round(${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + }) + ${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + }`, + [] + ); + testErrorsAndWarnings( + `from a | stats round(${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + }) + ${ + getFunctionSignatures( + { name, ...defRest, signatures: [{ params: fieldMapping, returnType }] }, + { withTypes: false } + )[0].declaration + }`, + [] + ); if (alias) { for (const otherName of alias) { @@ -1623,55 +1789,50 @@ describe('validation logic', () => { describe('enrich', () => { testErrorsAndWarnings(`from a | enrich`, [ - 'SyntaxError: expected {OPENING_BRACKET, ENRICH_POLICY_NAME} but found "<EOF>"', + "SyntaxError: missing ENRICH_POLICY_NAME at '<EOF>'", ]); - testErrorsAndWarnings(`from a | enrich [`, [ - 'SyntaxError: expected {SETTING} but found "<EOF>"', + testErrorsAndWarnings(`from a | enrich _`, ['Unknown policy [_]']); + testErrorsAndWarnings(`from a | enrich _:`, [ + "SyntaxError: token recognition error at: ':'", + 'Unknown policy [_]', ]); - testErrorsAndWarnings(`from a | enrich [ccq.mode`, [ - 'SyntaxError: expected {COLON} but found "<EOF>"', + testErrorsAndWarnings(`from a | enrich _:policy`, [ + 'Unrecognized value [_] for ENRICH, mode needs to be one of [_ANY, _COORDINATOR, _REMOTE]', ]); - testErrorsAndWarnings(`from a | enrich [ccq.mode:`, [ - 'SyntaxError: expected {SETTING} but found "<EOF>"', + testErrorsAndWarnings(`from a | enrich :policy`, [ + "SyntaxError: token recognition error at: ':'", ]); - testErrorsAndWarnings(`from a | enrich [ccq.mode:any`, [ - 'SyntaxError: expected {CLOSING_BRACKET} but found "<EOF>"', + testErrorsAndWarnings(`from a | enrich any:`, [ + "SyntaxError: token recognition error at: ':'", + 'Unknown policy [any]', ]); - testErrorsAndWarnings(`from a | enrich [ccq.mode:any] `, [ - "SyntaxError: extraneous input '<EOF>' expecting {OPENING_BRACKET, ENRICH_POLICY_NAME}", + testErrorsAndWarnings(`from a | enrich _any:`, [ + "SyntaxError: token recognition error at: ':'", + 'Unknown policy [_any]', ]); - testErrorsAndWarnings(`from a | enrich policy `, []); - testErrorsAndWarnings(`from a | enrich [ccq.mode:value] policy `, [ - 'Unrecognized value [value], ENRICH [ccq.mode] needs to be one of [ANY, COORDINATOR, REMOTE]', + testErrorsAndWarnings(`from a | enrich any:policy`, [ + 'Unrecognized value [any] for ENRICH, mode needs to be one of [_ANY, _COORDINATOR, _REMOTE]', ]); + testErrorsAndWarnings(`from a | enrich policy `, []); for (const value of ['any', 'coordinator', 'remote']) { - testErrorsAndWarnings(`from a | enrich [ccq.mode:${value}] policy `, []); - testErrorsAndWarnings(`from a | enrich [ccq.mode:${value.toUpperCase()}] policy `, []); + testErrorsAndWarnings(`from a | enrich _${value}:policy `, []); + testErrorsAndWarnings(`from a | enrich _${value} : policy `, [ + "SyntaxError: token recognition error at: ':'", + "SyntaxError: extraneous input 'policy' expecting <EOF>", + `Unknown policy [_${value}]`, + ]); + testErrorsAndWarnings(`from a | enrich _${value}: policy `, [ + "SyntaxError: token recognition error at: ':'", + "SyntaxError: extraneous input 'policy' expecting <EOF>", + `Unknown policy [_${value}]`, + ]); + testErrorsAndWarnings(`from a | enrich _${camelCase(value)}:policy `, []); + testErrorsAndWarnings(`from a | enrich _${value.toUpperCase()}:policy `, []); } - testErrorsAndWarnings(`from a | enrich [setting:value policy`, [ - 'SyntaxError: expected {CLOSING_BRACKET} but found "policy"', - 'Unsupported setting [setting], expected [ccq.mode]', - ]); - - testErrorsAndWarnings(`from a | enrich [ccq.mode:any policy`, [ - 'SyntaxError: expected {CLOSING_BRACKET} but found "policy"', - ]); - - testErrorsAndWarnings(`from a | enrich [ccq.mode:any policy`, [ - 'SyntaxError: expected {CLOSING_BRACKET} but found "policy"', - ]); - - testErrorsAndWarnings(`from a | enrich [setting:value] policy`, [ - 'Unsupported setting [setting], expected [ccq.mode]', + testErrorsAndWarnings(`from a | enrich _unknown:policy`, [ + 'Unrecognized value [_unknown] for ENRICH, mode needs to be one of [_ANY, _COORDINATOR, _REMOTE]', ]); - testErrorsAndWarnings(`from a | enrich [ccq.mode:any] policy[]`, []); - - testErrorsAndWarnings( - `from a | enrich [ccq.mode:any][ccq.mode:coordinator] policy[]`, - [], - ['Multiple definition of setting [ccq.mode]. Only last one will be applied.'] - ); testErrorsAndWarnings(`from a | enrich missing-policy `, ['Unknown policy [missing-policy]']); testErrorsAndWarnings(`from a | enrich policy on `, [ "SyntaxError: missing {QUOTED_IDENTIFIER, UNQUOTED_ID_PATTERN} at '<EOF>'", @@ -1749,7 +1910,7 @@ describe('validation logic', () => { expect(callbackMocks.getSources).not.toHaveBeenCalled(); }); - it(`should fetch policies if no enrich command is found`, async () => { + it(`should not fetch policies if no enrich command is found`, async () => { const callbackMocks = getCallbackMocks(); await validateAst(`row a = 1 | eval a`, getAstAndErrors, callbackMocks); expect(callbackMocks.getPolicies).not.toHaveBeenCalled(); @@ -1794,5 +1955,33 @@ describe('validation logic', () => { query: `from enrichIndex1 | keep otherField, yetAnotherField`, }); }); + + it(`should not crash if no callbacks are available`, async () => { + try { + await validateAst( + `from a | eval b = a | enrich policy | dissect stringField "%{firstWord}"`, + getAstAndErrors, + { + getFieldsFor: undefined, + getSources: undefined, + getPolicies: undefined, + getMetaFields: undefined, + } + ); + } catch { + fail('Should not throw'); + } + }); + + it(`should not crash if no callbacks are passed`, async () => { + try { + await validateAst( + `from a | eval b = a | enrich policy | dissect stringField "%{firstWord}"`, + getAstAndErrors + ); + } catch { + fail('Should not throw'); + } + }); }); }); diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.ts index 67a31afd7fea9..1deae7be97b4e 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.ts @@ -10,6 +10,7 @@ import uniqBy from 'lodash/uniqBy'; import { CommandModeDefinition, CommandOptionsDefinition, + FunctionDefinition, SignatureArgType, } from '../definitions/types'; import { @@ -134,8 +135,9 @@ function validateNestedFunctionArg( ) { // The isSupported check ensure the definition exists const argFn = getFunctionDefinition(actualArg.name)!; - - if ('noNestingFunctions' in argDef && argDef.noNestingFunctions) { + const fnDef = getFunctionDefinition(astFunction.name)!; + // no nestying criteria should be enforced only for same type function + if ('noNestingFunctions' in argDef && argDef.noNestingFunctions && fnDef.type === argFn.type) { messages.push( getMessageFromId({ messageId: 'noNestedArgumentSupport', @@ -170,51 +172,53 @@ function validateFunctionColumnArg( parentCommand: string ) { const messages: ESQLMessage[] = []; - if (isColumnItem(actualArg) && actualArg.name) { - const { hit: columnCheck, nameHit } = columnExists(actualArg, references); - if (!columnCheck) { - messages.push( - getMessageFromId({ - messageId: 'unknownColumn', - values: { - name: actualArg.name, - }, - locations: actualArg.location, - }) - ); - } else { - if (actualArg.name === '*') { - // if function does not support wildcards return a specific error - if (!('supportsWildcard' in argDef) || !argDef.supportsWildcard) { - messages.push( - getMessageFromId({ - messageId: 'noWildcardSupportAsArg', - values: { - name: astFunction.name, - }, - locations: actualArg.location, - }) - ); - } - // do not validate any further for now, only count() accepts wildcard as args... + if (isColumnItem(actualArg)) { + if (actualArg.name) { + const { hit: columnCheck, nameHit } = columnExists(actualArg, references); + if (!columnCheck) { + messages.push( + getMessageFromId({ + messageId: 'unknownColumn', + values: { + name: actualArg.name, + }, + locations: actualArg.location, + }) + ); } else { - // guaranteed by the check above - const columnHit = getColumnHit(nameHit!, references); - // check the type of the column hit - const typeHit = columnHit!.type; - if (!isEqualType(actualArg, argDef, references, parentCommand)) { - messages.push( - getMessageFromId({ - messageId: 'wrongArgumentType', - values: { - name: astFunction.name, - argType: argDef.type, - value: actualArg.name, - givenType: typeHit, - }, - locations: actualArg.location, - }) - ); + if (actualArg.name === '*') { + // if function does not support wildcards return a specific error + if (!('supportsWildcard' in argDef) || !argDef.supportsWildcard) { + messages.push( + getMessageFromId({ + messageId: 'noWildcardSupportAsArg', + values: { + name: astFunction.name, + }, + locations: actualArg.location, + }) + ); + } + // do not validate any further for now, only count() accepts wildcard as args... + } else { + // guaranteed by the check above + const columnHit = getColumnHit(nameHit!, references); + // check the type of the column hit + const typeHit = columnHit!.type; + if (!isEqualType(actualArg, argDef, references, parentCommand)) { + messages.push( + getMessageFromId({ + messageId: 'wrongArgumentType', + values: { + name: astFunction.name, + argType: argDef.type, + value: actualArg.name, + givenType: typeHit, + }, + locations: actualArg.location, + }) + ); + } } } } @@ -222,6 +226,24 @@ function validateFunctionColumnArg( return messages; } +function extractCompatibleSignaturesForFunction( + fnDef: FunctionDefinition, + astFunction: ESQLFunction +) { + return fnDef.signatures.filter((def) => { + if (def.infiniteParams && astFunction.args.length > 0) { + return true; + } + if (def.minParams && astFunction.args.length >= def.minParams) { + return true; + } + if (astFunction.args.length === def.params.length) { + return true; + } + return astFunction.args.length === def.params.filter(({ optional }) => !optional).length; + }); +} + function validateFunction( astFunction: ESQLFunction, parentCommand: string, @@ -235,16 +257,8 @@ function validateFunction( return messages; } const fnDefinition = getFunctionDefinition(astFunction.name)!; - const supportNestedFunctions = - fnDefinition?.signatures.some(({ params }) => - params.some(({ noNestingFunctions }) => !noNestingFunctions) - ) || true; - const isFnSupported = isSupportedFunction( - astFunction.name, - isNested && !supportNestedFunctions ? 'eval' : parentCommand, - parentOption - ); + const isFnSupported = isSupportedFunction(astFunction.name, parentCommand, parentOption); if (!isFnSupported.supported) { if (isFnSupported.reason === 'unknownFunction') { @@ -282,18 +296,7 @@ function validateFunction( return messages; } } - const matchingSignatures = fnDefinition.signatures.filter((def) => { - if (def.infiniteParams && astFunction.args.length > 0) { - return true; - } - if (def.minParams && astFunction.args.length >= def.minParams) { - return true; - } - if (astFunction.args.length === def.params.length) { - return true; - } - return astFunction.args.length >= def.params.filter(({ optional }) => !optional).length; - }); + const matchingSignatures = extractCompatibleSignaturesForFunction(fnDefinition, astFunction); if (!matchingSignatures.length) { const numArgs = fnDefinition.signatures[0].params.filter(({ optional }) => !optional).length; messages.push( @@ -303,6 +306,7 @@ function validateFunction( fn: astFunction.name, numArgs, passedArgs: astFunction.args.length, + exactly: fnDefinition.signatures[0].params.length - numArgs, }, locations: astFunction.location, }) @@ -325,9 +329,9 @@ function validateFunction( } } } - // check if the definition has some warning to show: - if (fnDefinition.warning) { - const payloads = fnDefinition.warning(astFunction); + // check if the definition has some specific validation to apply: + if (fnDefinition.validate) { + const payloads = fnDefinition.validate(astFunction); if (payloads.length) { messages.push(...payloads); } @@ -399,6 +403,7 @@ function validateFunction( failingSignatures.push(failingSignature); } } + if (failingSignatures.length && failingSignatures.length === matchingSignatures.length) { const failingSignatureOrderedByErrorCount = failingSignatures .map((arr, index) => ({ index, count: arr.length })) @@ -435,27 +440,27 @@ function validateSetting( ); return messages; } - setting.args.forEach((arg, index) => { - if (!Array.isArray(arg)) { - const argDef = settingDef.signature.params[index]; - const value = 'value' in arg ? arg.value : arg.name; - if (argDef.values && !argDef.values?.includes(String(value).toLowerCase())) { - messages.push( - getMessageFromId({ - messageId: 'unsupportedSettingCommandValue', - values: { - setting: setting.name, - command: command.name.toUpperCase(), - value: String(value), - // for some reason all this enums are uppercase in ES - expected: (argDef.values?.join(', ') || argDef.type).toUpperCase(), - }, - locations: arg.location, - }) - ); - } - } - }); + if ( + settingDef.values.every(({ name }) => name !== setting.name) || + // enforce the check on the prefix if present + (settingDef.prefix && !setting.text.startsWith(settingDef.prefix)) + ) { + messages.push( + getMessageFromId({ + messageId: 'unsupportedSettingCommandValue', + values: { + command: command.name.toUpperCase(), + value: setting.text, + // for some reason all this enums are uppercase in ES + expected: settingDef.values + .map(({ name }) => `${settingDef.prefix || ''}${name}`) + .join(', ') + .toUpperCase(), + }, + locations: setting.location, + }) + ); + } return messages; } @@ -657,14 +662,7 @@ function validateCommand(command: ESQLCommand, references: ReferenceMaps): ESQLM } if (isSettingItem(arg)) { - messages.push( - ...validateSetting( - arg, - commandDef.modes?.find(({ name }) => name === arg.name), - command, - references - ) - ); + messages.push(...validateSetting(arg, commandDef.modes[0], command, references)); } if (isOptionItem(arg)) { @@ -790,7 +788,7 @@ export async function validateAst( retrieveMetadataFields(callbacks), ]); - if (availablePolicies.size && ast.filter(({ name }) => name === 'enrich')) { + if (availablePolicies.size) { const fieldsFromPoliciesMap = await retrievePoliciesFields(ast, availablePolicies, callbacks); fieldsFromPoliciesMap.forEach((value, key) => availableFields.set(key, value)); } From a500ad64e7387d1540e66c80660f4c834946716f Mon Sep 17 00:00:00 2001 From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:36:39 +0100 Subject: [PATCH 073/104] Make request timeout of updateByQuery in TM configurable (#176461) Resolves: https://github.com/elastic/kibana-team/issues/721 As we discovered by an issue, it's an anti pattern to timeout-and-retry requests part of the polling cycle because it's basically putting the requests back in the same queue that it once was ahead on. Therefore we would like to make TaskManager's update-by-query request timeout configurable. --- config/serverless.yml | 1 + .../task_manager/server/config.test.ts | 9 ++ x-pack/plugins/task_manager/server/config.ts | 7 ++ .../server/ephemeral_task_lifecycle.test.ts | 3 + .../managed_configuration.test.ts | 3 + .../task_state_validation.test.ts | 9 +- .../lib/calculate_health_status.test.ts | 3 + .../server/metrics/create_aggregator.test.ts | 3 + .../configuration_statistics.test.ts | 3 + .../monitoring_stats_stream.test.ts | 3 + .../task_manager/server/plugin.test.ts | 3 + x-pack/plugins/task_manager/server/plugin.ts | 1 + .../server/polling_lifecycle.test.ts | 3 + .../task_manager/server/task_store.test.ts | 83 +++++++++++++++++++ .../plugins/task_manager/server/task_store.ts | 27 +++--- 15 files changed, 145 insertions(+), 16 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index 1d98bcca216e7..5147b4961d282 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -136,6 +136,7 @@ uiSettings: # Task Manager xpack.task_manager.allow_reading_invalid_state: false +xpack.task_manager.request_timeouts.update_by_query: 60000 ## TaskManager requeue invalid tasks, supports ZDT xpack.task_manager.requeue_invalid_tasks.enabled: true diff --git a/x-pack/plugins/task_manager/server/config.test.ts b/x-pack/plugins/task_manager/server/config.test.ts index 9d85c216546f8..097dcb9b32199 100644 --- a/x-pack/plugins/task_manager/server/config.test.ts +++ b/x-pack/plugins/task_manager/server/config.test.ts @@ -42,6 +42,9 @@ describe('config validation', () => { }, "poll_interval": 3000, "request_capacity": 1000, + "request_timeouts": Object { + "update_by_query": 30000, + }, "requeue_invalid_tasks": Object { "delay": 3000, "enabled": false, @@ -102,6 +105,9 @@ describe('config validation', () => { }, "poll_interval": 3000, "request_capacity": 1000, + "request_timeouts": Object { + "update_by_query": 30000, + }, "requeue_invalid_tasks": Object { "delay": 3000, "enabled": false, @@ -165,6 +171,9 @@ describe('config validation', () => { }, "poll_interval": 3000, "request_capacity": 1000, + "request_timeouts": Object { + "update_by_query": 30000, + }, "requeue_invalid_tasks": Object { "delay": 3000, "enabled": false, diff --git a/x-pack/plugins/task_manager/server/config.ts b/x-pack/plugins/task_manager/server/config.ts index 3be8b341c939e..0e30dd16b8841 100644 --- a/x-pack/plugins/task_manager/server/config.ts +++ b/x-pack/plugins/task_manager/server/config.ts @@ -62,6 +62,11 @@ const requeueInvalidTasksConfig = schema.object({ max_attempts: schema.number({ defaultValue: 100, min: 1, max: 500 }), }); +const requestTimeoutsConfig = schema.object({ + /* The request timeout config for task manager's updateByQuery default:30s, min:10s, max:10m */ + update_by_query: schema.number({ defaultValue: 1000 * 30, min: 1000 * 10, max: 1000 * 60 * 10 }), +}); + export const configSchema = schema.object( { allow_reading_invalid_state: schema.boolean({ defaultValue: true }), @@ -156,6 +161,7 @@ export const configSchema = schema.object( min: 1, }), claim_strategy: schema.string({ defaultValue: CLAIM_STRATEGY_DEFAULT }), + request_timeouts: requestTimeoutsConfig, }, { validate: (config) => { @@ -179,3 +185,4 @@ export type RequeueInvalidTasksConfig = TypeOf<typeof requeueInvalidTasksConfig> export type TaskManagerConfig = TypeOf<typeof configSchema>; export type TaskExecutionFailureThreshold = TypeOf<typeof taskExecutionFailureThresholdSchema>; export type EventLoopDelayConfig = TypeOf<typeof eventLoopDelaySchema>; +export type RequestTimeoutsConfig = TypeOf<typeof requestTimeoutsConfig>; diff --git a/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts b/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts index 6ae1d00a62243..98465e88e5466 100644 --- a/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts @@ -86,6 +86,9 @@ describe('EphemeralTaskLifecycle', () => { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, ...config, }, elasticsearchAndSOAvailability$, diff --git a/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts b/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts index 2fd4ceb74ca74..408771d0a55a6 100644 --- a/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts +++ b/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts @@ -81,6 +81,9 @@ describe('managed configuration', () => { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }); logger = context.logger.get('taskManager'); diff --git a/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts b/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts index c7ee109d17b11..a4ffa7514e02c 100644 --- a/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts +++ b/x-pack/plugins/task_manager/server/integration_tests/task_state_validation.test.ts @@ -6,14 +6,11 @@ */ import { v4 as uuidV4 } from 'uuid'; -import { - type TestElasticsearchUtils, - type TestKibanaUtils, -} from '@kbn/core-test-helpers-kbn-server'; +import type { TestElasticsearchUtils, TestKibanaUtils } from '@kbn/core-test-helpers-kbn-server'; import { schema } from '@kbn/config-schema'; import { TaskStatus } from '../task'; -import { type TaskPollingLifecycleOpts } from '../polling_lifecycle'; -import { type TaskClaimingOpts } from '../queries/task_claiming'; +import type { TaskPollingLifecycleOpts } from '../polling_lifecycle'; +import type { TaskClaimingOpts } from '../queries/task_claiming'; import { TaskManagerPlugin, type TaskManagerStartContract } from '../plugin'; import { injectTask, setupTestServers, retry } from './lib'; diff --git a/x-pack/plugins/task_manager/server/lib/calculate_health_status.test.ts b/x-pack/plugins/task_manager/server/lib/calculate_health_status.test.ts index 228d94ed87daf..df3ffdcc75cfe 100644 --- a/x-pack/plugins/task_manager/server/lib/calculate_health_status.test.ts +++ b/x-pack/plugins/task_manager/server/lib/calculate_health_status.test.ts @@ -58,6 +58,9 @@ const config = { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }; const getStatsWithTimestamp = ({ diff --git a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts index afcd4884f7777..349f0f73a4215 100644 --- a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts +++ b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts @@ -74,6 +74,9 @@ const config: TaskManagerConfig = { version_conflict_threshold: 80, worker_utilization_running_average_window: 5, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }; describe('createAggregator', () => { diff --git a/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts b/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts index 543707bf940b2..25b6f604ce305 100644 --- a/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts @@ -54,6 +54,9 @@ describe('Configuration Statistics Aggregator', () => { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }; const managedConfig = { diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts index 7dc3460d98388..2b3ec904d52b6 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts @@ -59,6 +59,9 @@ describe('createMonitoringStatsStream', () => { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }; it('returns the initial config used to configure Task Manager', async () => { diff --git a/x-pack/plugins/task_manager/server/plugin.test.ts b/x-pack/plugins/task_manager/server/plugin.test.ts index 5e178db3b99ad..4905dc09fb5c2 100644 --- a/x-pack/plugins/task_manager/server/plugin.test.ts +++ b/x-pack/plugins/task_manager/server/plugin.test.ts @@ -79,6 +79,9 @@ const pluginInitializerContextParams = { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }; describe('TaskManagerPlugin', () => { diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index 2fbabc1fe4d67..0baedbaf2bf54 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -241,6 +241,7 @@ export class TaskManagerPlugin adHocTaskCounter: this.adHocTaskCounter, allowReadingInvalidState: this.config.allow_reading_invalid_state, logger: this.logger, + requestTimeouts: this.config.request_timeouts, }); const managedConfiguration = createManagedConfiguration({ diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts index 24898d3c99385..56675ac868195 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts @@ -84,6 +84,9 @@ describe('TaskPollingLifecycle', () => { }, metrics_reset_interval: 3000, claim_strategy: 'default', + request_timeouts: { + update_by_query: 1000, + }, }, taskStore: mockTaskStore, logger: taskManagerLogger, diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index 933410be29b0c..a712cc5814a7d 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -25,6 +25,7 @@ import { TaskTypeDictionary } from './task_type_dictionary'; import { mockLogger } from './test_utils'; import { AdHocTaskCounter } from './lib/adhoc_task_counter'; import { asErr } from './lib/result_type'; +import { UpdateByQueryResponse } from '@elastic/elasticsearch/lib/api/types'; const mockGetValidatedTaskInstanceFromReading = jest.fn(); const mockGetValidatedTaskInstanceForUpdating = jest.fn(); @@ -108,6 +109,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -280,6 +284,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -351,6 +358,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -459,6 +469,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -610,6 +623,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -693,6 +709,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -729,6 +748,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -768,6 +790,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -828,6 +853,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -923,6 +951,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); expect(await store.getLifecycle(task.id)).toEqual(status); @@ -945,6 +976,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); expect(await store.getLifecycle(randomId())).toEqual(TaskLifecycleResult.NotFound); @@ -965,6 +999,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); return expect(store.getLifecycle(randomId())).rejects.toThrow('Bad Request'); @@ -985,6 +1022,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); }); @@ -1155,6 +1195,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, }); expect(jest.requireMock('./task_validator').TaskValidator).toHaveBeenCalledWith({ @@ -1177,6 +1220,9 @@ describe('TaskStore', () => { savedObjectsRepository: savedObjectsClient, adHocTaskCounter, allowReadingInvalidState: true, + requestTimeouts: { + update_by_query: 1000, + }, }); expect(jest.requireMock('./task_validator').TaskValidator).toHaveBeenCalledWith({ @@ -1186,4 +1232,41 @@ describe('TaskStore', () => { }); }); }); + + describe('updateByQuery', () => { + let store: TaskStore; + let esClient: ReturnType<typeof elasticsearchServiceMock.createClusterClient>['asInternalUser']; + let childEsClient: ReturnType< + typeof elasticsearchServiceMock.createClusterClient + >['asInternalUser']; + + beforeAll(() => { + esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + childEsClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.child.mockReturnValue(childEsClient as unknown as Client); + store = new TaskStore({ + logger: mockLogger(), + index: 'tasky', + taskManagerId: '', + serializer, + esClient, + definitions: taskDefinitions, + savedObjectsRepository: savedObjectsClient, + adHocTaskCounter, + allowReadingInvalidState: false, + requestTimeouts: { + update_by_query: 1000, + }, + }); + }); + test('should pass requestTimeout', async () => { + childEsClient.updateByQuery.mockResponse({ + hits: { hits: [], total: 0, updated: 100, version_conflicts: 0 }, + } as UpdateByQueryResponse); + await store.updateByQuery({ script: '' }, { max_docs: 10 }); + expect(childEsClient.updateByQuery).toHaveBeenCalledWith(expect.any(Object), { + requestTimeout: 1000, + }); + }); + }); }); diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index dc3ce1459f760..45bcb6589ab26 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -24,6 +24,7 @@ import { ElasticsearchClient, } from '@kbn/core/server'; +import { RequestTimeoutsConfig } from './config'; import { asOk, asErr, Result } from './lib/result_type'; import { @@ -48,6 +49,7 @@ export interface StoreOpts { adHocTaskCounter: AdHocTaskCounter; allowReadingInvalidState: boolean; logger: Logger; + requestTimeouts: RequestTimeoutsConfig; } export interface SearchOpts { @@ -108,6 +110,7 @@ export class TaskStore { private savedObjectsRepository: ISavedObjectsRepository; private serializer: ISavedObjectsSerializer; private adHocTaskCounter: AdHocTaskCounter; + private requestTimeouts: RequestTimeoutsConfig; /** * Constructs a new TaskStore. @@ -136,6 +139,7 @@ export class TaskStore { // The poller doesn't need retry logic because it will try again at the next polling cycle maxRetries: 0, }); + this.requestTimeouts = opts.requestTimeouts; } /** @@ -492,17 +496,20 @@ export class TaskStore { const { query } = ensureQueryOnlyReturnsTaskObjects(opts); try { const // eslint-disable-next-line @typescript-eslint/naming-convention - { total, updated, version_conflicts } = await this.esClientWithoutRetries.updateByQuery({ - index: this.index, - ignore_unavailable: true, - refresh: true, - conflicts: 'proceed', - body: { - ...opts, - max_docs, - query, + { total, updated, version_conflicts } = await this.esClientWithoutRetries.updateByQuery( + { + index: this.index, + ignore_unavailable: true, + refresh: true, + conflicts: 'proceed', + body: { + ...opts, + max_docs, + query, + }, }, - }); + { requestTimeout: this.requestTimeouts.update_by_query } + ); const conflictsCorrectedForContinuation = correctVersionConflictsForContinuation( updated, From 0c1a70e8ada2b80a86167ac4c5a976f036f57967 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet <nicolas.chaulet@elastic.co> Date: Fri, 9 Feb 2024 08:43:26 -0500 Subject: [PATCH 074/104] [Fleet] Fix isPackageVersionOrLaterInstalled to check for installed package (#176532) --- .../epm/packages/bulk_install_packages.ts | 2 +- .../services/epm/packages/install.test.ts | 108 ++++++++++++++++++ .../server/services/epm/packages/install.ts | 61 +++++++--- 3 files changed, 154 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts b/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts index da5ee0bcc8e5c..74dc880477ff9 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts @@ -110,7 +110,7 @@ export async function bulkInstallPackages({ result: { assets: [...installedEs, ...installedKibana], status: 'already_installed', - installType: installedPackageResult.installType, + installType: 'unknown', } as InstallResult, }; } diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts index 2a5ae1346d6b3..97817b063b730 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts @@ -26,6 +26,7 @@ import { handleInstallPackageFailure, installAssetsForInputPackagePolicy, installPackage, + isPackageVersionOrLaterInstalled, } from './install'; import * as install from './_install_package'; import { getBundledPackageByPkgKey } from './bundled_packages'; @@ -715,3 +716,110 @@ describe('handleInstallPackageFailure', () => { ); }); }); + +describe('isPackageVersionOrLaterInstalled', () => { + beforeEach(() => { + jest.mocked(getInstallationObject).mockReset(); + }); + it('should return true if package is installed in the same version as expected', async () => { + const savedObjectsClient = savedObjectsClientMock.create(); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '1.0.0', install_status: 'installed' }, + } as any); + const res = await isPackageVersionOrLaterInstalled({ + savedObjectsClient, + pkgName: 'test', + pkgVersion: '1.0.0', + }); + + expect(res).toEqual( + expect.objectContaining({ + package: expect.objectContaining({ + name: 'test', + version: '1.0.0', + install_status: 'installed', + }), + }) + ); + }); + + it('should return true if package is installed in an higher version as expected', async () => { + const savedObjectsClient = savedObjectsClientMock.create(); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '1.2.0', install_status: 'installed' }, + } as any); + const res = await isPackageVersionOrLaterInstalled({ + savedObjectsClient, + pkgName: 'test', + pkgVersion: '1.0.0', + }); + + expect(res).toEqual( + expect.objectContaining({ + package: expect.objectContaining({ + name: 'test', + version: '1.2.0', + install_status: 'installed', + }), + }) + ); + }); + + it('should return false if package is installed in an lower version as expected', async () => { + const savedObjectsClient = savedObjectsClientMock.create(); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '0.9.0', install_status: 'installed' }, + } as any); + const res = await isPackageVersionOrLaterInstalled({ + savedObjectsClient, + pkgName: 'test', + pkgVersion: '1.0.0', + }); + + expect(res).toEqual(false); + }); + + it('should retry if package is currently installing', async () => { + const savedObjectsClient = savedObjectsClientMock.create(); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '1.0.0', install_status: 'installing' }, + } as any); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '1.0.0', install_status: 'installing' }, + } as any); + jest.mocked(getInstallationObject).mockResolvedValueOnce({ + attributes: { name: 'test', version: '1.0.0', install_status: 'installed' }, + } as any); + + const res = await isPackageVersionOrLaterInstalled({ + savedObjectsClient, + pkgName: 'test', + pkgVersion: '1.0.0', + }); + + expect(res).toEqual( + expect.objectContaining({ + package: expect.objectContaining({ + name: 'test', + version: '1.0.0', + install_status: 'installed', + }), + }) + ); + + expect(getInstallationObject).toBeCalledTimes(3); + }); + + it('should throw on unexpected error', async () => { + const savedObjectsClient = savedObjectsClientMock.create(); + jest.mocked(getInstallationObject).mockRejectedValueOnce(new Error('test unexpected error')); + + const res = isPackageVersionOrLaterInstalled({ + savedObjectsClient, + pkgName: 'test', + pkgVersion: '1.0.0', + }); + + await expect(res).rejects.toThrowError('test unexpected error'); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index 073f93be81d6c..43b0c9d68a04c 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -87,6 +87,8 @@ import { addErrorToLatestFailedAttempts } from './install_errors_helpers'; import { installIndexTemplatesAndPipelines } from './install_index_template_pipeline'; import { optimisticallyAddEsAssetReferences } from './es_assets_reference'; +const MAX_ENSURE_INSTALL_TIME = 60 * 1000; + export async function isPackageInstalled(options: { savedObjectsClient: SavedObjectsClientContract; pkgName: string; @@ -95,27 +97,53 @@ export async function isPackageInstalled(options: { return installedPackage !== undefined; } +// Error used to retry in isPackageVersionOrLaterInstalled +class CurrentlyInstallingError extends Error {} + +/** + * Check if a package is currently installed, + * if the package is currently installing it will retry until MAX_ENSURE_INSTALL_TIME is reached + */ export async function isPackageVersionOrLaterInstalled(options: { savedObjectsClient: SavedObjectsClientContract; pkgName: string; pkgVersion: string; -}): Promise<{ package: Installation; installType: InstallType } | false> { - const { savedObjectsClient, pkgName, pkgVersion } = options; - const installedPackageObject = await getInstallationObject({ savedObjectsClient, pkgName }); - const installedPackage = installedPackageObject?.attributes; - if ( - installedPackage && - (installedPackage.version === pkgVersion || semverLt(pkgVersion, installedPackage.version)) - ) { - let installType: InstallType; - try { - installType = getInstallType({ pkgVersion, installedPkg: installedPackageObject }); - } catch (e) { - installType = 'unknown'; +}): Promise<{ package: Installation } | false> { + return pRetry( + async () => { + const { savedObjectsClient, pkgName, pkgVersion } = options; + const installedPackageObject = await getInstallationObject({ savedObjectsClient, pkgName }); + const installedPackage = installedPackageObject?.attributes; + if ( + installedPackage && + (installedPackage.version === pkgVersion || semverLt(pkgVersion, installedPackage.version)) + ) { + if (installedPackage.install_status === 'installing') { + throw new CurrentlyInstallingError( + `Package ${pkgName}-${pkgVersion} is currently installing` + ); + } else if (installedPackage.install_status === 'install_failed') { + return false; + } + + return { package: installedPackage }; + } + return false; + }, + { + maxRetryTime: MAX_ENSURE_INSTALL_TIME, + onFailedAttempt: (error) => { + if (!(error instanceof CurrentlyInstallingError)) { + throw error; + } + }, } - return { package: installedPackage, installType }; - } - return false; + ).catch((err): false => { + if (err instanceof CurrentlyInstallingError) { + return false; + } + throw err; + }); } export async function ensureInstalledPackage(options: { @@ -147,6 +175,7 @@ export async function ensureInstalledPackage(options: { pkgName: pkgKeyProps.name, pkgVersion: pkgKeyProps.version, }); + if (installedPackageResult) { return installedPackageResult.package; } From c5819dc09e2af875dc8cec375120457b964c0e1b Mon Sep 17 00:00:00 2001 From: Drew Tate <drew.tate@elastic.co> Date: Fri, 9 Feb 2024 07:11:18 -0700 Subject: [PATCH 075/104] [Saved object] prevent deleting managed content from UI (#176443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Closes https://github.com/elastic/kibana/issues/172391 This change stops users from deleting managed content from the SO management page by - keeping the delete action disabled when the selection contains only managed content - excluding managed content from the list in the delete modal https://github.com/elastic/kibana/assets/315764/5bfa974e-823e-4c35-b6b9-71fcd08bf5e8 <img width="1673" alt="Screenshot 2024-02-07 at 12 53 29 PM" src="https://github.com/elastic/kibana/assets/315764/645238ec-dfe7-4f10-b468-df40e4fcb698"> ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials — will be done in https://github.com/elastic/kibana/issues/175150 - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../common/types/v1.ts | 1 + .../components/delete_confirm_modal.test.tsx | 31 +++++++ .../components/delete_confirm_modal.tsx | 44 +++++++--- .../objects_table/components/table.test.tsx | 80 ++++++++++++++++++- .../objects_table/components/table.tsx | 4 +- .../saved_objects_table.test.tsx | 1 + .../objects_table/saved_objects_table.tsx | 2 +- .../server/lib/to_saved_object_with_meta.ts | 1 + 8 files changed, 147 insertions(+), 17 deletions(-) diff --git a/src/plugins/saved_objects_management/common/types/v1.ts b/src/plugins/saved_objects_management/common/types/v1.ts index 241188d035a6e..1c44559ee07c4 100644 --- a/src/plugins/saved_objects_management/common/types/v1.ts +++ b/src/plugins/saved_objects_management/common/types/v1.ts @@ -46,6 +46,7 @@ export interface SavedObjectWithMetadata<T = unknown> { error?: SavedObjectError; created_at?: string; updated_at?: string; + managed?: boolean; attributes: T; namespaces?: string[]; references: SavedObjectReference[]; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.test.tsx index 8f3209c5fee1b..260ebfc5dc956 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.test.tsx @@ -15,17 +15,20 @@ import { DeleteConfirmModal } from './delete_confirm_modal'; interface CreateObjectOptions { namespaces?: string[]; hiddenType?: boolean; + managed?: boolean; } const createObject = ({ namespaces, hiddenType = false, + managed = false, }: CreateObjectOptions = {}): SavedObjectWithMetadata => ({ id: 'foo', type: 'bar', attributes: {}, references: [], namespaces, + managed, meta: { hiddenType, }, @@ -197,6 +200,34 @@ describe('DeleteConfirmModal', () => { }); }); + it('excludes the managed objects from the table and displays a callout', () => { + const objs = [ + createObject({ managed: true }), + createObject({ managed: false }), + createObject({ managed: true }), + createObject({ hiddenType: true }), + ]; + + const wrapper = mountWithIntl( + <DeleteConfirmModal + isDeleting={false} + onConfirm={onConfirm} + onCancel={onCancel} + selectedObjects={objs} + allowedTypes={allowedTypes} + /> + ); + + expect(wrapper.find('.euiTableRow')).toHaveLength(1); + + const callout = findTestSubject(wrapper, 'cannotDeleteObjectsConfirmWarning'); + expect(callout).toHaveLength(1); + + expect(callout.text()).toMatchInlineSnapshot( + `"Some objects have been excluded1 object is hidden and cannot be deleted.2 objects are managed by Elastic and cannot be deleted."` + ); + }); + describe('shared objects warning', () => { it('does not display a callout when no objects are shared', () => { const objs = [ diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.tsx index a422526c7afad..83adac8880aab 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/delete_confirm_modal.tsx @@ -28,6 +28,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { css } from '@emotion/react'; import type { SavedObjectWithMetadata, SavedObjectManagementTypeInfo } from '../../../../common'; import { getSavedObjectLabel } from '../../../lib'; @@ -48,12 +49,15 @@ export const DeleteConfirmModal: FC<DeleteConfirmModalProps> = ({ allowedTypes, showPlainSpinner, }) => { - const undeletableObjects = useMemo(() => { + const hiddenObjects = useMemo(() => { return selectedObjects.filter((obj) => obj.meta.hiddenType); }, [selectedObjects]); + const managedObjects = useMemo(() => { + return selectedObjects.filter((obj) => obj.managed); + }, [selectedObjects]); const deletableObjects = useMemo(() => { return selectedObjects - .filter((obj) => !obj.meta.hiddenType) + .filter((obj) => !obj.meta.hiddenType && !obj.managed) .map(({ type, id, meta, namespaces = [] }) => { const { title = '', icon = 'apps' } = meta; const isShared = namespaces.length > 1 || namespaces.includes('*'); @@ -84,26 +88,42 @@ export const DeleteConfirmModal: FC<DeleteConfirmModalProps> = ({ </EuiModalHeaderTitle> </EuiModalHeader> <EuiModalBody> - {undeletableObjects.length > 0 && ( + {hiddenObjects.length + managedObjects.length > 0 && ( <> <EuiCallOut data-test-subj="cannotDeleteObjectsConfirmWarning" title={ <FormattedMessage id="savedObjectsManagement.objectsTable.deleteConfirmModal.cannotDeleteCallout.title" - defaultMessage="Some objects cannot be deleted" + defaultMessage="Some objects have been excluded" /> } iconType="warning" color="warning" > - <p> - <FormattedMessage - id="savedObjectsManagement.objectsTable.deleteConfirmModal.cannotDeleteCallout.content" - defaultMessage="{objectCount, plural, one {# object is} other {# objects are}} hidden and cannot be deleted. {objectCount, plural, one {It was} other {They were}} excluded from the table summary." - values={{ objectCount: undeletableObjects.length }} - /> - </p> + {hiddenObjects.length > 0 && ( + <p + css={css` + margin-block-end: 0 !important; + `} + > + <FormattedMessage + id="savedObjectsManagement.objectsTable.deleteConfirmModal.cannotDeleteCallout.content" + defaultMessage="{objectCount, plural, one {# object is} other {# objects are}} hidden and cannot be deleted." + values={{ objectCount: hiddenObjects.length }} + /> + </p> + )} + + {managedObjects.length > 0 && ( + <p> + <FormattedMessage + id="savedObjectsManagement.objectsTable.deleteConfirmModal.cannotDeleteCallout.managedContent" + defaultMessage="{objectCount, plural, one {# object is} other {# objects are}} managed by Elastic and cannot be deleted." + values={{ objectCount: managedObjects.length }} + /> + </p> + )} </EuiCallOut> <EuiSpacer size="s" /> </> @@ -159,7 +179,7 @@ export const DeleteConfirmModal: FC<DeleteConfirmModalProps> = ({ field: 'id', name: i18n.translate( 'savedObjectsManagement.objectsTable.deleteSavedObjectsConfirmModal.idColumnName', - { defaultMessage: 'Id' } + { defaultMessage: 'ID' } ), }, { diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.test.tsx index 86f2b766002ac..4b72e11b0968e 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.test.tsx @@ -14,6 +14,8 @@ import { httpServiceMock } from '@kbn/core/public/mocks'; import { actionServiceMock } from '../../../services/action_service.mock'; import { columnServiceMock } from '../../../services/column_service.mock'; import { Table, TableProps } from './table'; +import { render, screen, waitFor } from '@testing-library/react'; +import { I18nProvider } from '@kbn/i18n-react'; const defaultProps: TableProps = { basePath: httpServiceMock.createSetupContract().basePath, @@ -112,9 +114,9 @@ describe('Table', () => { it(`prevents saved objects from being deleted`, () => { const selectedSavedObjects = [ - { type: 'visualization' }, - { type: 'search' }, - { type: 'index-pattern' }, + { type: 'visualization', meta: { hiddenType: false } }, + { type: 'search', meta: { hiddenType: false } }, + { type: 'index-pattern', meta: { hiddenType: false } }, ] as any; const customizedProps = { ...defaultProps, @@ -154,4 +156,76 @@ describe('Table', () => { someAction.onClick(); expect(onActionRefresh).toHaveBeenCalled(); }); + + describe('managed content', () => { + it('keeps the delete button disabled when the selection only contains managed and hidden SOs', async () => { + const managedSavedObjects = [ + { type: 'visualization', managed: true, meta: { hiddenType: false } }, + { type: 'search', managed: true, meta: { hiddenType: false } }, + { type: 'index-pattern', managed: true, meta: { hiddenType: false } }, + ] as any; + + const hiddenSavedObjects = [ + { type: 'visualization', managed: false, meta: { hiddenType: true } }, + { type: 'search', managed: false, meta: { hiddenType: true } }, + { type: 'index-pattern', managed: false, meta: { hiddenType: true } }, + ] as any; + + const { rerender } = render( + <I18nProvider> + <Table {...defaultProps} selectedSavedObjects={managedSavedObjects} /> + </I18nProvider> + ); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectsManagementDelete')).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Export' })).toBeEnabled(); + }); + + rerender( + <I18nProvider> + <Table {...defaultProps} selectedSavedObjects={hiddenSavedObjects} /> + </I18nProvider> + ); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectsManagementDelete')).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Export' })).toBeEnabled(); + }); + + rerender( + <I18nProvider> + <Table + {...defaultProps} + selectedSavedObjects={[...managedSavedObjects, ...hiddenSavedObjects]} + /> + </I18nProvider> + ); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectsManagementDelete')).toBeDisabled(); + expect(screen.getByRole('button', { name: 'Export' })).toBeEnabled(); + }); + }); + + it('enables the delete button when the selection contains at least one unmanaged, non-hidden SO', async () => { + const selectedSavedObjects = [ + { type: 'visualization', managed: true, meta: { hiddenType: false } }, + { type: 'search', managed: true, meta: { hiddenType: false } }, + { type: 'index-pattern', managed: false, meta: { hiddenType: true } }, + { type: 'lens', managed: false, meta: { hiddenType: false } }, // deletable! + ] as any; + + render( + <I18nProvider> + <Table {...defaultProps} selectedSavedObjects={selectedSavedObjects} /> + </I18nProvider> + ); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectsManagementDelete')).toBeEnabled(); + expect(screen.getByRole('button', { name: 'Export' })).toBeEnabled(); + }); + }); + }); }); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx index 79e4d32643108..8015bf11d0585 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx @@ -402,7 +402,9 @@ export class Table extends PureComponent<TableProps, TableState> { color="danger" onClick={onDelete} isDisabled={ - selectedSavedObjects.length === 0 || !capabilities.savedObjectsManagement.delete + selectedSavedObjects.filter( + ({ managed, meta: { hiddenType } }) => !managed && !hiddenType + ).length === 0 || !capabilities.savedObjectsManagement.delete } title={ capabilities.savedObjectsManagement.delete diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx index c4ec166799f3e..8b70c5ed2af66 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx @@ -538,6 +538,7 @@ describe('SavedObjectsTable', () => { { id: '1', type: 'index-pattern', meta: {} }, { id: '3', type: 'dashboard', meta: {} }, { id: '4', type: 'dashboard', meta: { hiddenType: false } }, + { id: '5', type: 'dashboard', managed: true, meta: {} }, ] as SavedObjectWithMetadata[]; const mockSavedObjects = mockSelectedSavedObjects.map((obj) => ({ diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx index e84d957f39239..e4daf584888c3 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx @@ -528,7 +528,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb const deleteStatus = await bulkDeleteObjects( http, selectedSavedObjects - .filter((object) => !object.meta.hiddenType) + .filter((object) => !object.meta.hiddenType && !object.managed) .map(({ id, type }) => ({ id, type })) ); diff --git a/src/plugins/saved_objects_management/server/lib/to_saved_object_with_meta.ts b/src/plugins/saved_objects_management/server/lib/to_saved_object_with_meta.ts index 03a900b0ddc97..792cd3ccd9086 100644 --- a/src/plugins/saved_objects_management/server/lib/to_saved_object_with_meta.ts +++ b/src/plugins/saved_objects_management/server/lib/to_saved_object_with_meta.ts @@ -16,6 +16,7 @@ export function toSavedObjectWithMeta(so: SavedObject): SavedObjectWithMetadata namespaces: so.namespaces, references: so.references, updated_at: so.updated_at, + managed: so.managed, attributes: so.attributes, created_at: so.created_at, error: so.error, From 2627f48d957c2757bbdb9bac2a1e75b85d9e755b Mon Sep 17 00:00:00 2001 From: Jeramy Soucy <jeramy.soucy@elastic.co> Date: Fri, 9 Feb 2024 09:13:52 -0500 Subject: [PATCH 076/104] Harden console functions (#171367) ## Summary This PR overrides console functions only in production, in order to sanitize input parameters for any potential calls made to the global console from Kibana's dependencies. This initial implementation overrides the `debug`, `error`, `info`, `log`, `trace`, and `warn` functions, and only sanitizes string inputs. Future updates may expand this to handle other types, or strings nested in objects. The unmodified console methods are now exposed internally in Kibana as `unsafeConsole`. Where needed for formatting (log appenders, core logger), calls to the global console have been replaced by `unsafeConsole`. This PR also adds a new es linting rule to disallow calls to `unsafeConsole` unless `eslint-disable-next-line @kbn/eslint/no_unsafe_console` is used. ### Testing Not sure how we could test this. The overrides are only enabled when running in a true production environment (e.g. docker) by checking `process.env.NODE_ENV`. I was able to manually test by adding additional console output denoting when the console functions were being overriden or not. Closes https://github.com/elastic/kibana-team/issues/664 Closes #176340 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + package.json | 1 + .../src/logger.test.ts | 13 +- .../src/logger.ts | 29 +++-- .../tsconfig.json | 3 +- .../src/appenders/console_appender.test.ts | 10 +- .../src/appenders/console_appender.ts | 5 +- .../src/logging_system.test.ts | 3 +- .../tsconfig.json | 3 +- .../console/console_appender.test.ts | 10 +- .../src/appenders/console/console_appender.ts | 5 +- .../src/logging_system.test.ts | 3 +- .../tsconfig.json | 1 + packages/kbn-eslint-config/.eslintrc.js | 1 + packages/kbn-eslint-plugin-eslint/README.mdx | 6 +- packages/kbn-eslint-plugin-eslint/index.js | 1 + .../rules/no_unsafe_console.js | 71 ++++++++++ .../rules/no_unsafe_console.test.js | 121 ++++++++++++++++++ packages/kbn-security-hardening/README.md | 7 + packages/kbn-security-hardening/console.ts | 69 ++++++++++ packages/kbn-security-hardening/index.ts | 9 ++ packages/kbn-security-hardening/kibana.jsonc | 5 + packages/kbn-security-hardening/package.json | 6 + packages/kbn-security-hardening/tsconfig.json | 16 +++ .../elasticsearch/error_logging.test.ts | 3 +- .../version_compatibility.test.ts | 3 +- .../integration_tests/http/logging.test.ts | 3 +- .../integration_tests/logging/logging.test.ts | 5 +- .../integration_tests/node/logging.test.ts | 3 +- src/core/tsconfig.json | 1 + src/setup_node_env/index.js | 2 + src/setup_node_env/tsconfig.json | 1 + tsconfig.base.json | 2 + yarn.lock | 4 + 34 files changed, 379 insertions(+), 47 deletions(-) create mode 100644 packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.js create mode 100644 packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.test.js create mode 100644 packages/kbn-security-hardening/README.md create mode 100644 packages/kbn-security-hardening/console.ts create mode 100644 packages/kbn-security-hardening/index.ts create mode 100644 packages/kbn-security-hardening/kibana.jsonc create mode 100644 packages/kbn-security-hardening/package.json create mode 100644 packages/kbn-security-hardening/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dcfce13388c7a..8f40c55a2bea3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -674,6 +674,7 @@ packages/kbn-search-index-documents @elastic/enterprise-search-frontend packages/kbn-search-response-warnings @elastic/kibana-data-discovery x-pack/plugins/searchprofiler @elastic/platform-deployment-management x-pack/test/security_api_integration/packages/helpers @elastic/kibana-security +packages/kbn-security-hardening @elastic/kibana-security x-pack/plugins/security @elastic/kibana-security x-pack/packages/security/plugin_types_common @elastic/kibana-security x-pack/packages/security/plugin_types_public @elastic/kibana-security diff --git a/package.json b/package.json index c11b0b349099f..6485d9c840817 100644 --- a/package.json +++ b/package.json @@ -676,6 +676,7 @@ "@kbn/search-index-documents": "link:packages/kbn-search-index-documents", "@kbn/search-response-warnings": "link:packages/kbn-search-response-warnings", "@kbn/searchprofiler-plugin": "link:x-pack/plugins/searchprofiler", + "@kbn/security-hardening": "link:packages/kbn-security-hardening", "@kbn/security-plugin": "link:x-pack/plugins/security", "@kbn/security-plugin-types-common": "link:x-pack/packages/security/plugin_types_common", "@kbn/security-plugin-types-public": "link:x-pack/packages/security/plugin_types_public", diff --git a/packages/core/analytics/core-analytics-browser-internal/src/logger.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/logger.test.ts index 2fbe17e3f7d22..429ddcbcd0e35 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/logger.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/logger.test.ts @@ -7,16 +7,17 @@ */ import type { LogRecord } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; import { createLogger } from './logger'; describe('createLogger', () => { // Calling `.mockImplementation` on all of them to avoid jest logging the console usage - const logErrorSpy = jest.spyOn(console, 'error').mockImplementation(); - const logWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - const logInfoSpy = jest.spyOn(console, 'info').mockImplementation(); - const logDebugSpy = jest.spyOn(console, 'debug').mockImplementation(); - const logTraceSpy = jest.spyOn(console, 'trace').mockImplementation(); - const logLogSpy = jest.spyOn(console, 'log').mockImplementation(); + const logErrorSpy = jest.spyOn(unsafeConsole, 'error').mockImplementation(); + const logWarnSpy = jest.spyOn(unsafeConsole, 'warn').mockImplementation(); + const logInfoSpy = jest.spyOn(unsafeConsole, 'info').mockImplementation(); + const logDebugSpy = jest.spyOn(unsafeConsole, 'debug').mockImplementation(); + const logTraceSpy = jest.spyOn(unsafeConsole, 'trace').mockImplementation(); + const logLogSpy = jest.spyOn(unsafeConsole, 'log').mockImplementation(); beforeEach(() => { jest.clearAllMocks(); diff --git a/packages/core/analytics/core-analytics-browser-internal/src/logger.ts b/packages/core/analytics/core-analytics-browser-internal/src/logger.ts index ff403a7d46d2c..7ec3a56da6ed1 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/logger.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/logger.ts @@ -7,6 +7,7 @@ */ import type { Logger } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; /** * Create custom logger until we have a proper logging solution: https://github.com/elastic/kibana/issues/33796 @@ -16,20 +17,20 @@ export function createLogger(isDev: boolean): Logger { // TODO: Replace with a core logger once we implement it in https://github.com/elastic/kibana/issues/33796 // For now, it logs only in dev mode const logger: Logger = { - // eslint-disable-next-line no-console - fatal: (...args) => (isDev ? console.error(...args) : void 0), - // eslint-disable-next-line no-console - error: (...args) => (isDev ? console.error(...args) : void 0), - // eslint-disable-next-line no-console - warn: (...args) => (isDev ? console.warn(...args) : void 0), - // eslint-disable-next-line no-console - info: (...args) => (isDev ? console.info(...args) : void 0), - // eslint-disable-next-line no-console - debug: (...args) => (isDev ? console.debug(...args) : void 0), - // eslint-disable-next-line no-console - trace: (...args) => (isDev ? console.trace(...args) : void 0), - // eslint-disable-next-line no-console - log: (...args) => (isDev ? console.log(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + fatal: (...args) => (isDev ? unsafeConsole.error(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + error: (...args) => (isDev ? unsafeConsole.error(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + warn: (...args) => (isDev ? unsafeConsole.warn(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + info: (...args) => (isDev ? unsafeConsole.info(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + debug: (...args) => (isDev ? unsafeConsole.debug(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + trace: (...args) => (isDev ? unsafeConsole.trace(...args) : void 0), + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + log: (...args) => (isDev ? unsafeConsole.log(...args) : void 0), isLevelEnabled: () => true, get: () => logger, }; diff --git a/packages/core/analytics/core-analytics-browser-internal/tsconfig.json b/packages/core/analytics/core-analytics-browser-internal/tsconfig.json index c6efe4287effc..f2f9d3837719e 100644 --- a/packages/core/analytics/core-analytics-browser-internal/tsconfig.json +++ b/packages/core/analytics/core-analytics-browser-internal/tsconfig.json @@ -13,7 +13,8 @@ "@kbn/core-injected-metadata-browser-internal", "@kbn/core-analytics-browser", "@kbn/core-base-browser-mocks", - "@kbn/core-injected-metadata-browser-mocks" + "@kbn/core-injected-metadata-browser-mocks", + "@kbn/security-hardening" ], "exclude": ["target/**/*"] } diff --git a/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.test.ts b/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.test.ts index 8b8900be8e035..886d100eda6de 100644 --- a/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.test.ts +++ b/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.test.ts @@ -7,10 +7,11 @@ */ import { LogRecord, LogLevel } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; import { ConsoleAppender } from './console_appender'; test('`append()` correctly formats records and pushes them to console.', () => { - jest.spyOn(global.console, 'log').mockImplementation(() => { + jest.spyOn(unsafeConsole, 'log').mockImplementation(() => { // noop }); @@ -47,10 +48,7 @@ test('`append()` correctly formats records and pushes them to console.', () => { for (const record of records) { appender.append(record); - // eslint-disable-next-line no-console - expect(console.log).toHaveBeenCalledWith(`mock-${JSON.stringify(record)}`); + expect(unsafeConsole.log).toHaveBeenCalledWith(`mock-${JSON.stringify(record)}`); } - - // eslint-disable-next-line no-console - expect(console.log).toHaveBeenCalledTimes(records.length); + expect(unsafeConsole.log).toHaveBeenCalledTimes(records.length); }); diff --git a/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.ts b/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.ts index 4d35f3150b421..44228d602e417 100644 --- a/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.ts +++ b/packages/core/logging/core-logging-browser-internal/src/appenders/console_appender.ts @@ -7,6 +7,7 @@ */ import type { Layout, LogRecord, DisposableAppender } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; /** * @@ -25,8 +26,8 @@ export class ConsoleAppender implements DisposableAppender { * @param record `LogRecord` instance to be logged. */ public append(record: LogRecord) { - // eslint-disable-next-line no-console - console.log(this.layout.format(record)); + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + unsafeConsole.log(this.layout.format(record)); } /** diff --git a/packages/core/logging/core-logging-browser-internal/src/logging_system.test.ts b/packages/core/logging/core-logging-browser-internal/src/logging_system.test.ts index 61b32002e7ae5..75071169eef5f 100644 --- a/packages/core/logging/core-logging-browser-internal/src/logging_system.test.ts +++ b/packages/core/logging/core-logging-browser-internal/src/logging_system.test.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { unsafeConsole } from '@kbn/security-hardening'; import { BrowserLoggingSystem } from './logging_system'; describe('', () => { @@ -15,7 +16,7 @@ describe('', () => { let loggingSystem: BrowserLoggingSystem; beforeEach(() => { - mockConsoleLog = jest.spyOn(global.console, 'log').mockReturnValue(undefined); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log').mockReturnValue(undefined); jest.spyOn<any, any>(global, 'Date').mockImplementation(() => timestamp); loggingSystem = new BrowserLoggingSystem({ logLevel: 'warn' }); }); diff --git a/packages/core/logging/core-logging-browser-internal/tsconfig.json b/packages/core/logging/core-logging-browser-internal/tsconfig.json index d0d9f725a4ee0..89c06b251c39b 100644 --- a/packages/core/logging/core-logging-browser-internal/tsconfig.json +++ b/packages/core/logging/core-logging-browser-internal/tsconfig.json @@ -12,7 +12,8 @@ ], "kbn_references": [ "@kbn/logging", - "@kbn/core-logging-common-internal" + "@kbn/core-logging-common-internal", + "@kbn/security-hardening" ], "exclude": [ "target/**/*", diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.test.ts b/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.test.ts index 1e8f742c1ecda..17379cd6d5553 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.test.ts @@ -19,6 +19,7 @@ jest.mock('../../layouts/layouts', () => { }); import { LogRecord, LogLevel } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; import { ConsoleAppender } from './console_appender'; test('`configSchema` creates correct schema.', () => { @@ -37,7 +38,7 @@ test('`configSchema` creates correct schema.', () => { }); test('`append()` correctly formats records and pushes them to console.', () => { - jest.spyOn(global.console, 'log').mockImplementation(() => { + jest.spyOn(unsafeConsole, 'log').mockImplementation(() => { // noop }); @@ -74,10 +75,7 @@ test('`append()` correctly formats records and pushes them to console.', () => { for (const record of records) { appender.append(record); - // eslint-disable-next-line no-console - expect(console.log).toHaveBeenCalledWith(`mock-${JSON.stringify(record)}`); + expect(unsafeConsole.log).toHaveBeenCalledWith(`mock-${JSON.stringify(record)}`); } - - // eslint-disable-next-line no-console - expect(console.log).toHaveBeenCalledTimes(records.length); + expect(unsafeConsole.log).toHaveBeenCalledTimes(records.length); }); diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.ts b/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.ts index 0602ea81289af..45ad47fb062f0 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/console/console_appender.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import type { Layout, LogRecord, DisposableAppender } from '@kbn/logging'; +import { unsafeConsole } from '@kbn/security-hardening'; import { Layouts } from '../../layouts/layouts'; const { literal, object } = schema; @@ -34,8 +35,8 @@ export class ConsoleAppender implements DisposableAppender { * @param record `LogRecord` instance to be logged. */ public append(record: LogRecord) { - // eslint-disable-next-line no-console - console.log(this.layout.format(record)); + // eslint-disable-next-line @kbn/eslint/no_unsafe_console + unsafeConsole.log(this.layout.format(record)); } /** diff --git a/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts b/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts index 76fe93d1e614a..4d3b4d73916ef 100644 --- a/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts @@ -18,10 +18,11 @@ const mockCreateWriteStream = createWriteStream as unknown as jest.Mock<typeof c import { LoggingSystem, config } from '..'; import { EcsVersion } from '@kbn/ecs'; +import { unsafeConsole } from '@kbn/security-hardening'; let system: LoggingSystem; beforeEach(() => { - mockConsoleLog = jest.spyOn(global.console, 'log').mockReturnValue(undefined); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log').mockReturnValue(undefined); jest.spyOn<any, any>(global, 'Date').mockImplementation(() => timestamp); jest.spyOn(process, 'uptime').mockReturnValue(10); system = new LoggingSystem(); diff --git a/packages/core/logging/core-logging-server-internal/tsconfig.json b/packages/core/logging/core-logging-server-internal/tsconfig.json index 43c80b0fcdcd5..de25a6b65bc5a 100644 --- a/packages/core/logging/core-logging-server-internal/tsconfig.json +++ b/packages/core/logging/core-logging-server-internal/tsconfig.json @@ -22,6 +22,7 @@ "@kbn/utility-types-jest", "@kbn/utility-types", "@kbn/ecs", + "@kbn/security-hardening", ], "exclude": [ "target/**/*", diff --git a/packages/kbn-eslint-config/.eslintrc.js b/packages/kbn-eslint-config/.eslintrc.js index e9fae3fd1b290..73ae2f6e75b62 100644 --- a/packages/kbn-eslint-config/.eslintrc.js +++ b/packages/kbn-eslint-config/.eslintrc.js @@ -273,6 +273,7 @@ module.exports = { '@kbn/eslint/no_trailing_import_slash': 'error', '@kbn/eslint/no_constructor_args_in_property_initializers': 'error', '@kbn/eslint/no_this_in_property_initializers': 'error', + '@kbn/eslint/no_unsafe_console': 'error', '@kbn/imports/no_unresolvable_imports': 'error', '@kbn/imports/uniform_imports': 'error', '@kbn/imports/no_unused_imports': 'error', diff --git a/packages/kbn-eslint-plugin-eslint/README.mdx b/packages/kbn-eslint-plugin-eslint/README.mdx index 0cbe16599f2c6..2601c5ace4259 100644 --- a/packages/kbn-eslint-plugin-eslint/README.mdx +++ b/packages/kbn-eslint-plugin-eslint/README.mdx @@ -103,4 +103,8 @@ module.exports = { } ] } -``` \ No newline at end of file +``` + +## no_unsafe_console + +Disables the usage of kbn-security-hardening/console/unsafeConsole. \ No newline at end of file diff --git a/packages/kbn-eslint-plugin-eslint/index.js b/packages/kbn-eslint-plugin-eslint/index.js index f099adedabbbe..3d161ec33dda1 100644 --- a/packages/kbn-eslint-plugin-eslint/index.js +++ b/packages/kbn-eslint-plugin-eslint/index.js @@ -17,5 +17,6 @@ module.exports = { no_trailing_import_slash: require('./rules/no_trailing_import_slash'), no_constructor_args_in_property_initializers: require('./rules/no_constructor_args_in_property_initializers'), no_this_in_property_initializers: require('./rules/no_this_in_property_initializers'), + no_unsafe_console: require('./rules/no_unsafe_console'), }, }; diff --git a/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.js b/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.js new file mode 100644 index 0000000000000..0a7024099594c --- /dev/null +++ b/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.js @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const tsEstree = require('@typescript-eslint/typescript-estree'); +const esTypes = tsEstree.AST_NODE_TYPES; + +/** @typedef {import("eslint").Rule.RuleModule} Rule */ +/** @typedef {import("@typescript-eslint/typescript-estree").TSESTree.Node} Node */ +/** @typedef {import("@typescript-eslint/typescript-estree").TSESTree.CallExpression} CallExpression */ +/** @typedef {import("@typescript-eslint/typescript-estree").TSESTree.CallExpression} VariableDeclarator */ + +const ERROR_MSG = 'Unexpected unsafeConsole statement.'; + +/** + * @param {CallExpression} node + */ +const isUnsafeConsoleCall = (node) => { + return ( + node.callee.type === esTypes.MemberExpression && + node.callee.property.type === esTypes.Identifier && + node.callee.object.name === 'unsafeConsole' && + node.callee.property.name + ); +}; + +/** + * @param {VariableDeclarator} node + */ +const isUnsafeConsoleObjectPatternDeclarator = (node) => { + return ( + node.id.type === esTypes.ObjectPattern && + node.init && + node.init.type === esTypes.Identifier && + node.init.name === 'unsafeConsole' + ); +}; + +/** @type {Rule} */ +module.exports = { + meta: { + fixable: 'code', + schema: [], + }, + create: (context) => ({ + CallExpression(_) { + const node = /** @type {CallExpression} */ (_); + + if (isUnsafeConsoleCall(node)) { + context.report({ + message: ERROR_MSG, + loc: node.callee.loc, + }); + } + }, + VariableDeclarator(_) { + const node = /** @type {VariableDeclarator} */ (_); + + if (isUnsafeConsoleObjectPatternDeclarator(node)) { + context.report({ + message: ERROR_MSG, + loc: node.init.loc, + }); + } + }, + }), +}; diff --git a/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.test.js b/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.test.js new file mode 100644 index 0000000000000..95e5250cec3a9 --- /dev/null +++ b/packages/kbn-eslint-plugin-eslint/rules/no_unsafe_console.test.js @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { RuleTester } = require('eslint'); +const rule = require('./no_unsafe_console'); +const dedent = require('dedent'); + +const ruleTester = new RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018, + }, +}); + +ruleTester.run('@kbn/eslint/no_unsafe_console', rule, { + valid: [ + { + code: dedent` + unsafeConsole + `, + }, + ], + + invalid: [ + { + code: dedent` + unsafeConsole.debug('something to debug') + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.error() + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.info('some info') + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.log('something to log') + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.trace() + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.warn('something to warn') + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + unsafeConsole.anyOtherMethodName() + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + { + code: dedent` + const { debug } = unsafeConsole + debug('something to debug') + `, + errors: [ + { + line: 1, + message: 'Unexpected unsafeConsole statement.', + }, + ], + }, + ], +}); diff --git a/packages/kbn-security-hardening/README.md b/packages/kbn-security-hardening/README.md new file mode 100644 index 0000000000000..5f040d006bbf0 --- /dev/null +++ b/packages/kbn-security-hardening/README.md @@ -0,0 +1,7 @@ +# @kbn/security-hardening + +A package counterpart of `src/setup_node_env/harden` - containing overrides, utilities, and tools to reduce potential vulnerability. + +## console + +When running in production mode (`process.env.NODE_ENV === 'production'`), global console methods `debug`, `error`, `info`, `log`, `trace`, and `warn` are overridden to implement input sanitization. The export `unsafeConsole` provides access to the unmodified global console methods. \ No newline at end of file diff --git a/packages/kbn-security-hardening/console.ts b/packages/kbn-security-hardening/console.ts new file mode 100644 index 0000000000000..e6865cc2992f6 --- /dev/null +++ b/packages/kbn-security-hardening/console.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable no-console */ + +// From https://www.ascii-code.com/characters/control-characters, +// but explicitly allowing the range \u0008-\u000F (line breaks, tabs, etc.) +const CONTROL_CHAR_REGEXP = new RegExp('[\\u0000-\\u0007\\u0010-\\u001F]', 'g'); + +export const unsafeConsole = { + debug: console.debug.bind(console), + error: console.error.bind(console), + info: console.info.bind(console), + log: console.log.bind(console), + trace: console.trace.bind(console), + warn: console.warn.bind(console), +}; + +function callWithSanitizedArgs(func: Function, ...args: any[]) { + const cleanedArgs = args.map(function (arg) { + if (typeof arg !== 'string') return arg; + return escapeControlChars(arg); + }); + func.apply(console, cleanedArgs); +} + +if (process.env.NODE_ENV === 'production') { + console.log('Native global console methods have been overridden in production environment.'); + + console.debug = function (...args) { + callWithSanitizedArgs(unsafeConsole.debug, ...args); + }; + + console.error = function (...args) { + callWithSanitizedArgs(unsafeConsole.error, ...args); + }; + + console.info = function (...args) { + callWithSanitizedArgs(unsafeConsole.info, ...args); + }; + + console.log = function (...args) { + callWithSanitizedArgs(unsafeConsole.log, ...args); + }; + + console.trace = function (...args) { + callWithSanitizedArgs(unsafeConsole.trace, ...args); + }; + + console.warn = function (...args) { + callWithSanitizedArgs(unsafeConsole.warn, ...args); + }; +} + +function escapeControlChars(input: string) { + return input.replace( + CONTROL_CHAR_REGEXP, + // Escaping control chars via JSON.stringify to maintain consistency with `meta` and the JSON layout. + // This way, post analysis of the logs is easier as we can search the same patterns. + // Our benchmark didn't show a big difference in performance between custom-escaping vs. JSON.stringify one. + // The slice is removing the double-quotes. + (substr) => JSON.stringify(substr).slice(1, -1) + ); +} diff --git a/packages/kbn-security-hardening/index.ts b/packages/kbn-security-hardening/index.ts new file mode 100644 index 0000000000000..14c740887c21c --- /dev/null +++ b/packages/kbn-security-hardening/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { unsafeConsole } from './console'; diff --git a/packages/kbn-security-hardening/kibana.jsonc b/packages/kbn-security-hardening/kibana.jsonc new file mode 100644 index 0000000000000..42b778b24fcc6 --- /dev/null +++ b/packages/kbn-security-hardening/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/security-hardening", + "owner": "@elastic/kibana-security" +} diff --git a/packages/kbn-security-hardening/package.json b/packages/kbn-security-hardening/package.json new file mode 100644 index 0000000000000..9fa800115404d --- /dev/null +++ b/packages/kbn-security-hardening/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/security-hardening", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/kbn-security-hardening/tsconfig.json b/packages/kbn-security-hardening/tsconfig.json new file mode 100644 index 0000000000000..33dcb5e36274e --- /dev/null +++ b/packages/kbn-security-hardening/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "node" + ] + }, + "include": [ + "**/*.ts", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [] +} diff --git a/src/core/server/integration_tests/elasticsearch/error_logging.test.ts b/src/core/server/integration_tests/elasticsearch/error_logging.test.ts index f8deaa41ee862..8201851530e30 100644 --- a/src/core/server/integration_tests/elasticsearch/error_logging.test.ts +++ b/src/core/server/integration_tests/elasticsearch/error_logging.test.ts @@ -11,6 +11,7 @@ import { type TestElasticsearchUtils, type TestKibanaUtils, } from '@kbn/core-test-helpers-kbn-server'; +import { unsafeConsole } from '@kbn/security-hardening'; describe('Error logging', () => { describe('ES client errors', () => { @@ -19,7 +20,7 @@ describe('Error logging', () => { let kibanaServer: TestKibanaUtils; beforeAll(async () => { - mockConsoleLog = jest.spyOn(global.console, 'log'); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log'); const { startES, startKibana } = createTestServers({ adjustTimeout: jest.setTimeout, diff --git a/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts b/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts index 54bd5c0fc4a9b..eb6cc767d5817 100644 --- a/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts +++ b/src/core/server/integration_tests/elasticsearch/version_compatibility.test.ts @@ -15,6 +15,7 @@ import { esTestConfig } from '@kbn/test'; import { firstValueFrom, Subject } from 'rxjs'; import { CliArgs } from '@kbn/config'; import Semver from 'semver'; +import { unsafeConsole } from '@kbn/security-hardening'; function nextMinor() { return Semver.inc(esTestConfig.getVersion(), 'minor') || '10.0.0'; @@ -36,7 +37,7 @@ describe('Version Compatibility', () => { let consoleSpy: jest.SpyInstance; beforeEach(() => { - consoleSpy = jest.spyOn(console, 'log'); + consoleSpy = jest.spyOn(unsafeConsole, 'log'); }); afterEach(async () => { diff --git a/src/core/server/integration_tests/http/logging.test.ts b/src/core/server/integration_tests/http/logging.test.ts index dfd29256b4b3e..c00c3ac9825a9 100644 --- a/src/core/server/integration_tests/http/logging.test.ts +++ b/src/core/server/integration_tests/http/logging.test.ts @@ -8,12 +8,13 @@ import { schema } from '@kbn/config-schema'; import { createRoot, request } from '@kbn/core-test-helpers-kbn-server'; +import { unsafeConsole } from '@kbn/security-hardening'; describe('request logging', () => { let mockConsoleLog: jest.SpyInstance; beforeAll(() => { - mockConsoleLog = jest.spyOn(global.console, 'log'); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log'); }); afterEach(() => { diff --git a/src/core/server/integration_tests/logging/logging.test.ts b/src/core/server/integration_tests/logging/logging.test.ts index ffae94adc624f..b7b972b6f3530 100644 --- a/src/core/server/integration_tests/logging/logging.test.ts +++ b/src/core/server/integration_tests/logging/logging.test.ts @@ -10,6 +10,7 @@ import type { LoggerContextConfigInput } from '@kbn/core-logging-server'; import { createRoot as createkbnTestServerRoot } from '@kbn/core-test-helpers-kbn-server'; import { InternalCoreSetup } from '@kbn/core-lifecycle-server-internal'; import { Subject } from 'rxjs'; +import { unsafeConsole } from '@kbn/security-hardening'; function createRoot() { return createkbnTestServerRoot({ @@ -45,7 +46,7 @@ describe('logging service', () => { let root: ReturnType<typeof createRoot>; let mockConsoleLog: jest.SpyInstance; beforeAll(async () => { - mockConsoleLog = jest.spyOn(global.console, 'log'); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log'); root = createRoot(); await root.preboot(); @@ -148,7 +149,7 @@ describe('logging service', () => { }; beforeAll(async () => { - mockConsoleLog = jest.spyOn(global.console, 'log'); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log'); root = createRoot(); await root.preboot(); diff --git a/src/core/server/integration_tests/node/logging.test.ts b/src/core/server/integration_tests/node/logging.test.ts index e5158e6d2d8c4..2041688652dbf 100644 --- a/src/core/server/integration_tests/node/logging.test.ts +++ b/src/core/server/integration_tests/node/logging.test.ts @@ -7,6 +7,7 @@ */ import { createRoot as createkbnTestServerRoot } from '@kbn/core-test-helpers-kbn-server'; +import { unsafeConsole } from '@kbn/security-hardening'; function createRootWithRoles(roles: string[]) { return createkbnTestServerRoot({ @@ -39,7 +40,7 @@ describe('node service global context', () => { let mockConsoleLog: jest.SpyInstance; beforeAll(async () => { - mockConsoleLog = jest.spyOn(global.console, 'log'); + mockConsoleLog = jest.spyOn(unsafeConsole, 'log'); root = createRootWithRoles(roles); await root.preboot(); diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json index 06e6cf68d3a94..67aeaa971d102 100644 --- a/src/core/tsconfig.json +++ b/src/core/tsconfig.json @@ -157,6 +157,7 @@ "@kbn/core-plugins-contracts-server", "@kbn/dev-utils", "@kbn/server-http-tools", + "@kbn/security-hardening", "@kbn/core-base-server-mocks", ], "exclude": [ diff --git a/src/setup_node_env/index.js b/src/setup_node_env/index.js index 176785e10246a..3efbab18ea3b4 100644 --- a/src/setup_node_env/index.js +++ b/src/setup_node_env/index.js @@ -14,3 +14,5 @@ require('./dns_ipv4_first'); require('@kbn/babel-register').install(); require('./polyfill'); + +require('@kbn/security-hardening'); diff --git a/src/setup_node_env/tsconfig.json b/src/setup_node_env/tsconfig.json index 931afbdfaf0a3..694f5928bc94c 100644 --- a/src/setup_node_env/tsconfig.json +++ b/src/setup_node_env/tsconfig.json @@ -13,6 +13,7 @@ "kbn_references": [ { "path": "../../tsconfig.json" }, "@kbn/babel-register", + "@kbn/security-hardening", ], "exclude": [ "target/**/*", diff --git a/tsconfig.base.json b/tsconfig.base.json index bb1f7b7877026..e496444be723e 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1342,6 +1342,8 @@ "@kbn/searchprofiler-plugin/*": ["x-pack/plugins/searchprofiler/*"], "@kbn/security-api-integration-helpers": ["x-pack/test/security_api_integration/packages/helpers"], "@kbn/security-api-integration-helpers/*": ["x-pack/test/security_api_integration/packages/helpers/*"], + "@kbn/security-hardening": ["packages/kbn-security-hardening"], + "@kbn/security-hardening/*": ["packages/kbn-security-hardening/*"], "@kbn/security-plugin": ["x-pack/plugins/security"], "@kbn/security-plugin/*": ["x-pack/plugins/security/*"], "@kbn/security-plugin-types-common": ["x-pack/packages/security/plugin_types_common"], diff --git a/yarn.lock b/yarn.lock index 42e12233631a3..eb678a777ab9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5748,6 +5748,10 @@ version "0.0.0" uid "" +"@kbn/security-hardening@link:packages/kbn-security-hardening": + version "0.0.0" + uid "" + "@kbn/security-plugin-types-common@link:x-pack/packages/security/plugin_types_common": version "0.0.0" uid "" From 421c9376307da0edf471a6e2c3be3335f52d4e0f Mon Sep 17 00:00:00 2001 From: Marco Vettorello <marco.vettorello@elastic.co> Date: Fri, 9 Feb 2024 15:26:30 +0100 Subject: [PATCH 077/104] [Lens][color mapping] hide single color picker in loop mode (#176564) ## Summary This PR hides the single color picker when the color palette is selected in the button group as agreed with @MichaelMarcialis and @stratoula (initial conversation here https://github.com/elastic/kibana/pull/175144 followed by an offline one) From this: <img width="362" alt="Screenshot 2024-02-09 at 09 20 37" src="https://github.com/elastic/kibana/assets/1421091/5f68fc57-627b-45b7-90e8-1aa78ee4b5b2"> To this: <img width="376" alt="Screenshot 2024-02-09 at 09 19 51" src="https://github.com/elastic/kibana/assets/1421091/fbefee5b-74e2-48e0-937b-c9e8e4699dce"> <img width="371" alt="Screenshot 2024-02-09 at 09 19 48" src="https://github.com/elastic/kibana/assets/1421091/677c1f7f-c02f-4d77-a18f-ea2ffd22f874"> --- .../container/unassigned_terms_config.tsx | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx index 8e90bcc38d119..405437a34e35b 100644 --- a/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx +++ b/packages/kbn-coloring/src/shared_components/color_mapping/components/container/unassigned_terms_config.tsx @@ -11,7 +11,6 @@ import React from 'react'; import { EuiButtonGroup, EuiButtonGroupOptionProps, - EuiColorPickerSwatch, EuiFlexGroup, EuiFlexItem, EuiFormRow, @@ -110,39 +109,24 @@ export function UnassignedTermsConfig({ </EuiFlexItem> <EuiFlexItem grow={0}> - {data.type === 'categories' && otherAssignment.color.type !== 'loop' ? ( - <SpecialAssignment - index={0} - palette={palette} - isDarkMode={isDarkMode} - getPaletteFn={getPaletteFn} - assignmentColor={otherAssignment.color} - total={specialAssignments.length} - /> - ) : ( - <EuiColorPickerSwatch - color={'gray'} - disabled - style={{ - // the color swatch can't pickup colors written in rgb/css standard - backgroundColor: '#EFF2F6', - cursor: 'not-allowed', - width: 32, - height: 32, - }} - css={css` - &::after { - content: ''; - width: 43px; - height: 43px; - border-bottom: 1px solid #d9ddea; - transform: rotate(-45deg) translateY(-51.5px) translateX(0px); - margin: 0; - position: absolute; - } - `} - /> - )} + <div + css={css` + visibility: ${otherAssignment.color.type === 'loop' ? 'hidden' : 'visible'}; + width: 32px; + height: 32px; + `} + > + {data.type === 'categories' && otherAssignment.color.type !== 'loop' && ( + <SpecialAssignment + index={0} + palette={palette} + isDarkMode={isDarkMode} + getPaletteFn={getPaletteFn} + assignmentColor={otherAssignment.color} + total={specialAssignments.length} + /> + )} + </div> </EuiFlexItem> </EuiFlexGroup> </EuiFormRow> From 54c772a6209121774607725922764cbafed0cc98 Mon Sep 17 00:00:00 2001 From: Adam Demjen <demjened@gmail.com> Date: Fri, 9 Feb 2024 09:47:02 -0500 Subject: [PATCH 078/104] [Search] Extract pipeline select logic from ML inference logic (#176550) ## Summary This PR extracts the inference pipeline selection logic from `ml_inference_logic.ts` into a more cohesive logic file. There are no functional changes. Referenced values and actions (like pipeline and index data, config update action) are pulled in from `ml_inference_logic.ts`. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../ml_inference/ml_inference_logic.test.ts | 154 ---------- .../ml_inference/ml_inference_logic.ts | 86 +----- .../ml_inference/pipeline_select.tsx | 12 +- .../pipeline_select_logic.test.ts | 278 ++++++++++++++++++ .../ml_inference/pipeline_select_logic.ts | 137 +++++++++ .../pipeline_select_option.test.tsx | 2 +- .../ml_inference/pipeline_select_option.tsx | 2 +- 7 files changed, 424 insertions(+), 247 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index ae3cc237c67a5..e067b89a7887e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -11,7 +11,6 @@ import { HttpResponse } from '@kbn/core/public'; import { ErrorResponse, Status } from '../../../../../../../common/types/api'; import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml'; -import { TrainedModelState } from '../../../../../../../common/types/pipelines'; import { GetDocumentsApiLogic } from '../../../../api/documents/get_document_logic'; import { MappingsApiLogic } from '../../../../api/mappings/mappings_logic'; @@ -41,7 +40,6 @@ const DEFAULT_VALUES: MLInferenceProcessorsValues = { }, createErrors: [], existingPipeline: undefined, - existingInferencePipelines: [], formErrors: { fieldMappings: 'Field is required.', modelID: 'Field is required.', @@ -210,158 +208,6 @@ describe('MlInferenceLogic', () => { }); describe('selectors', () => { - describe('existingInferencePipelines', () => { - beforeEach(() => { - CachedFetchModelsApiLogic.actions.apiSuccess(MODELS); - MappingsApiLogic.actions.apiSuccess({ - mappings: { - properties: { - body: { - type: 'text', - }, - }, - }, - }); - }); - it('returns empty list when there is not existing pipelines available', () => { - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([]); - }); - it('returns existing pipeline option', () => { - FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ - 'unit-test': { - processors: [ - { - inference: { - field_map: { - body: 'text_field', - }, - model_id: MODELS[0].modelId, - target_field: 'ml.inference.test-field', - }, - }, - ], - version: 1, - }, - }); - - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([ - { - disabled: false, - modelId: MODELS[0].modelId, - modelType: 'ner', - pipelineName: 'unit-test', - sourceFields: ['body'], - indexFields: ['body'], - }, - ]); - }); - it('returns disabled pipeline option if missing source fields', () => { - FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ - 'unit-test': { - processors: [ - { - inference: { - field_map: { - title: 'text_field', // Does not exist in index - }, - model_id: MODELS[0].modelId, - target_field: 'ml.inference.title', - }, - }, - { - inference: { - field_map: { - body: 'text_field', // Exists in index - }, - model_id: MODELS[0].modelId, - target_field: 'ml.inference.body', - }, - }, - { - inference: { - field_map: { - body_content: 'text_field', // Does not exist in index - }, - model_id: MODELS[0].modelId, - target_field: 'ml.inference.body_content', - }, - }, - ], - version: 1, - }, - }); - - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([ - { - disabled: true, - disabledReason: expect.stringContaining('title, body_content'), - modelId: MODELS[0].modelId, - modelType: 'ner', - pipelineName: 'unit-test', - sourceFields: ['title', 'body', 'body_content'], - indexFields: ['body'], - }, - ]); - }); - it('returns enabled pipeline option if model is redacted', () => { - FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ - 'unit-test': { - processors: [ - { - inference: { - field_map: { - body: 'text_field', - }, - model_id: '', - target_field: 'ml.inference.test-field', - }, - }, - ], - version: 1, - }, - }); - - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([ - { - disabled: false, - pipelineName: 'unit-test', - modelType: '', - modelId: '', - sourceFields: ['body'], - indexFields: ['body'], - }, - ]); - }); - it('filters pipeline if pipeline already attached', () => { - FetchMlInferencePipelineProcessorsApiLogic.actions.apiSuccess([ - { - modelId: MODELS[0].modelId, - modelState: TrainedModelState.Started, - pipelineName: 'unit-test', - pipelineReferences: ['test@ml-inference'], - types: ['ner', 'pytorch'], - }, - ]); - FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ - 'unit-test': { - processors: [ - { - inference: { - field_map: { - body: 'text_field', - }, - model_id: MODELS[0].modelId, - target_field: 'ml.inference.test-field', - }, - }, - ], - version: 1, - }, - }); - - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([]); - }); - }); describe('formErrors', () => { it('has errors when configuration is empty', () => { expect(MLInferenceLogic.values.formErrors).toEqual({ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index 3383a8772f3ce..478b51dc1d7b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -15,7 +15,6 @@ import { generateMlInferencePipelineBody, getMlInferencePrefixedFieldName, ML_INFERENCE_PREFIX, - parseMlInferenceParametersFromPipeline, } from '../../../../../../../common/ml_inference_pipeline'; import { Status } from '../../../../../../../common/types/api'; import { MlModel } from '../../../../../../../common/types/ml'; @@ -68,7 +67,7 @@ import { } from '../../../../api/pipelines/fetch_pipeline'; import { isConnectorIndex } from '../../../../utils/indices'; -import { getMLType, sortSourceFields } from '../../../shared/ml_inference/utils'; +import { sortSourceFields } from '../../../shared/ml_inference/utils'; import { PipelinesLogic } from '../pipelines_logic'; import { @@ -78,7 +77,6 @@ import { } from './types'; import { - EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS, validateInferencePipelineConfiguration, validateInferencePipelineFields, validatePipelineNameIsAvailable, @@ -104,16 +102,6 @@ const getFullTargetFieldName = ( return getMlInferencePrefixedFieldName(suffixedTargetField); }; -export interface MLInferencePipelineOption { - disabled: boolean; - disabledReason?: string; - modelId: string; - modelType: string; - pipelineName: string; - sourceFields: string[]; - indexFields: string[]; -} - export interface MLInferenceProcessorsActions { addSelectedFieldsToMapping: (isTextExpansionModelSelected: boolean) => { isTextExpansionModelSelected: boolean; @@ -163,9 +151,6 @@ export interface MLInferenceProcessorsActions { step: AddInferencePipelineSteps; }; removeFieldFromMapping: (fieldName: string) => { fieldName: string }; - selectExistingPipeline: (pipelineName: string) => { - pipelineName: string; - }; selectFields: (fieldNames: string[]) => { fieldNames: string[] }; setAddInferencePipelineStep: (step: AddInferencePipelineSteps) => { step: AddInferencePipelineSteps; @@ -190,7 +175,6 @@ export interface MLInferenceProcessorsValues { addInferencePipelineModal: AddInferencePipelineModal; createErrors: string[]; existingPipeline: FetchPipelineResponse | undefined; - existingInferencePipelines: MLInferencePipelineOption[]; formErrors: AddInferencePipelineFormErrors; index: CachedFetchIndexApiLogicValues['indexData']; isConfigureStepValid: boolean; @@ -223,7 +207,6 @@ export const MLInferenceLogic = kea< createPipeline: true, onAddInferencePipelineStepChange: (step: AddInferencePipelineSteps) => ({ step }), removeFieldFromMapping: (fieldName: string) => ({ fieldName }), - selectExistingPipeline: (pipelineName: string) => ({ pipelineName }), selectFields: (fieldNames: string[]) => ({ fieldNames }), setAddInferencePipelineStep: (step: AddInferencePipelineSteps) => ({ step }), setIndexName: (indexName: string) => ({ indexName }), @@ -322,19 +305,6 @@ export const MLInferenceLogic = kea< pipelineName: configuration.pipelineName, }); }, - selectExistingPipeline: ({ pipelineName }) => { - const pipeline = values.mlInferencePipelinesData?.[pipelineName]; - if (!pipeline) return; - const params = parseMlInferenceParametersFromPipeline(pipelineName, pipeline); - if (params === null) return; - actions.setInferencePipelineConfiguration({ - existingPipeline: true, - modelID: params.model_id, - pipelineName, - fieldMappings: params.field_mappings, - targetField: '', - }); - }, mlInferencePipelinesSuccess: (data) => { if ( (data?.length ?? 0) === 0 && @@ -580,59 +550,5 @@ export const MLInferenceLogic = kea< addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal'] ) => models.find((m) => m.modelId === addInferencePipelineModal.configuration.modelID), ], - existingInferencePipelines: [ - () => [ - selectors.mlInferencePipelinesData, - selectors.sourceFields, - selectors.selectableModels, - selectors.mlInferencePipelineProcessors, - ], - ( - mlInferencePipelinesData: MLInferenceProcessorsValues['mlInferencePipelinesData'], - indexFields: MLInferenceProcessorsValues['sourceFields'], - selectableModels: MLInferenceProcessorsValues['selectableModels'], - mlInferencePipelineProcessors: MLInferenceProcessorsValues['mlInferencePipelineProcessors'] - ) => { - if (!mlInferencePipelinesData) { - return []; - } - const indexProcessorNames = - mlInferencePipelineProcessors?.map((processor) => processor.pipelineName) ?? []; - - const existingPipelines: MLInferencePipelineOption[] = Object.entries( - mlInferencePipelinesData - ) - .map(([pipelineName, pipeline]): MLInferencePipelineOption | undefined => { - if (!pipeline || indexProcessorNames.includes(pipelineName)) return undefined; - - // Parse configuration from pipeline definition - const pipelineParams = parseMlInferenceParametersFromPipeline(pipelineName, pipeline); - if (!pipelineParams) return undefined; - const { model_id: modelId, field_mappings: fieldMappings } = pipelineParams; - - const sourceFields = fieldMappings?.map((m) => m.sourceField) ?? []; - const missingSourceFields = sourceFields.filter((f) => !indexFields?.includes(f)) ?? []; - const mlModel = selectableModels.find((model) => model.modelId === modelId); - const modelType = mlModel ? getMLType(mlModel.types) : ''; - const disabledReason = - missingSourceFields.length > 0 - ? EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS(missingSourceFields.join(', ')) - : undefined; - - return { - disabled: disabledReason !== undefined, - disabledReason, - modelId, - modelType, - pipelineName, - sourceFields, - indexFields: indexFields ?? [], - }; - }) - .filter((p): p is MLInferencePipelineOption => p !== undefined); - - return existingPipelines; - }, - ], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select.tsx index 9295c5440a054..39b354237a5c7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select.tsx @@ -11,17 +11,17 @@ import { useActions, useValues } from 'kea'; import { EuiSelectable, useEuiTheme, useIsWithinMaxBreakpoint } from '@elastic/eui'; -import { MLInferenceLogic, MLInferencePipelineOption } from './ml_inference_logic'; +import { MLInferencePipelineOption, PipelineSelectLogic } from './pipeline_select_logic'; import { PipelineSelectOption, PipelineSelectOptionProps } from './pipeline_select_option'; export const PipelineSelect: React.FC = () => { const { - addInferencePipelineModal: { configuration }, + addInferencePipelineModal: { + configuration: { pipelineName }, + }, existingInferencePipelines, - } = useValues(MLInferenceLogic); - const { selectExistingPipeline } = useActions(MLInferenceLogic); - - const { pipelineName } = configuration; + } = useValues(PipelineSelectLogic); + const { selectExistingPipeline } = useActions(PipelineSelectLogic); const { euiTheme } = useEuiTheme(); const largeScreenRowHeight = euiTheme.base * 6; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.test.ts new file mode 100644 index 0000000000000..362abeb9a6625 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.test.ts @@ -0,0 +1,278 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogicMounter } from '../../../../../__mocks__/kea_logic'; + +import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml'; +import { TrainedModelState } from '../../../../../../../common/types/pipelines'; + +import { MappingsApiLogic } from '../../../../api/mappings/mappings_logic'; +import { CachedFetchModelsApiLogic } from '../../../../api/ml_models/cached_fetch_models_api_logic'; +import { FetchMlInferencePipelineProcessorsApiLogic } from '../../../../api/pipelines/fetch_ml_inference_pipeline_processors'; +import { + FetchMlInferencePipelinesApiLogic, + FetchMlInferencePipelinesResponse, +} from '../../../../api/pipelines/fetch_ml_inference_pipelines'; + +import { PipelineSelectLogic, PipelineSelectValues } from './pipeline_select_logic'; +import { AddInferencePipelineSteps } from './types'; + +const DEFAULT_VALUES: PipelineSelectValues = { + addInferencePipelineModal: { + configuration: { + modelID: '', + pipelineName: '', + targetField: '', + }, + indexName: '', + step: AddInferencePipelineSteps.Configuration, + }, + existingInferencePipelines: [], + mlInferencePipelineProcessors: undefined, + mlInferencePipelinesData: undefined, + selectableModels: [], + sourceFields: undefined, +}; + +const DEFAULT_MODELS: MlModel[] = [ + { + modelId: 'model_1', + type: 'ner', + title: 'Model 1', + description: 'Model 1 description', + licenseType: 'elastic', + modelDetailsPageUrl: 'https://my-model.ai', + deploymentState: MlModelDeploymentState.NotDeployed, + startTime: 0, + targetAllocationCount: 0, + nodeAllocationCount: 0, + threadsPerAllocation: 0, + isPlaceholder: false, + hasStats: false, + types: ['pytorch', 'ner'], + inputFieldNames: ['title'], + version: '1', + }, +]; + +const DEFAULT_PIPELINES: FetchMlInferencePipelinesResponse = { + 'my-pipeline': { + processors: [ + { + inference: { + field_map: { + body: 'text_field', + }, + model_id: DEFAULT_MODELS[0].modelId, + target_field: 'ml.inference.body', + }, + }, + ], + version: 1, + }, +}; + +describe('PipelineSelectLogic', () => { + const { mount } = new LogicMounter(PipelineSelectLogic); + const { mount: mountFetchMlInferencePipelineProcessorsApiLogic } = new LogicMounter( + FetchMlInferencePipelineProcessorsApiLogic + ); + const { mount: mountFetchMlInferencePipelinesApiLogic } = new LogicMounter( + FetchMlInferencePipelinesApiLogic + ); + + beforeEach(() => { + jest.clearAllMocks(); + mountFetchMlInferencePipelineProcessorsApiLogic(); + mountFetchMlInferencePipelinesApiLogic(); + mount(); + }); + + describe('actions', () => { + describe('selectExistingPipeline', () => { + it('updates inference pipeline configuration', () => { + mount(DEFAULT_VALUES); + jest.spyOn(PipelineSelectLogic.actions, 'setInferencePipelineConfiguration'); + + FetchMlInferencePipelinesApiLogic.actions.apiSuccess(DEFAULT_PIPELINES); + PipelineSelectLogic.actions.selectExistingPipeline('my-pipeline'); + + expect(PipelineSelectLogic.actions.setInferencePipelineConfiguration).toHaveBeenCalledWith({ + existingPipeline: true, + modelID: DEFAULT_MODELS[0].modelId, + pipelineName: 'my-pipeline', + fieldMappings: [ + { + sourceField: 'body', + targetField: 'ml.inference.body', + }, + ], + targetField: '', + }); + }); + it('does not update inference pipeline configuration if pipeline name is not in list of fetched pipelines', () => { + mount(DEFAULT_VALUES); + jest.spyOn(PipelineSelectLogic.actions, 'setInferencePipelineConfiguration'); + + FetchMlInferencePipelinesApiLogic.actions.apiSuccess(DEFAULT_PIPELINES); + PipelineSelectLogic.actions.selectExistingPipeline('nonexistent-pipeline'); + + expect( + PipelineSelectLogic.actions.setInferencePipelineConfiguration + ).not.toHaveBeenCalled(); + }); + it('does not update inference pipeline configuration if inference processor cannot be parsed from fetched pipeline', () => { + mount(DEFAULT_VALUES); + jest.spyOn(PipelineSelectLogic.actions, 'setInferencePipelineConfiguration'); + + FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ + 'my-pipeline': { + processors: [ + { + set: { + // No inference processor + field: 'some-field', + }, + }, + ], + version: 1, + }, + }); + PipelineSelectLogic.actions.selectExistingPipeline('my-pipeline'); + + expect( + PipelineSelectLogic.actions.setInferencePipelineConfiguration + ).not.toHaveBeenCalled(); + }); + }); + }); + + describe('selectors', () => { + describe('existingInferencePipelines', () => { + beforeEach(() => { + CachedFetchModelsApiLogic.actions.apiSuccess(DEFAULT_MODELS); + MappingsApiLogic.actions.apiSuccess({ + mappings: { + properties: { + body: { + type: 'text', + }, + }, + }, + }); + }); + it('returns empty list when there are no existing pipelines available', () => { + expect(PipelineSelectLogic.values.existingInferencePipelines).toEqual([]); + }); + it('returns existing pipeline option', () => { + FetchMlInferencePipelinesApiLogic.actions.apiSuccess(DEFAULT_PIPELINES); + + expect(PipelineSelectLogic.values.existingInferencePipelines).toEqual([ + { + disabled: false, + modelId: DEFAULT_MODELS[0].modelId, + modelType: 'ner', + pipelineName: 'my-pipeline', + sourceFields: ['body'], + indexFields: ['body'], + }, + ]); + }); + it('returns disabled pipeline option if missing source fields', () => { + FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ + 'my-pipeline': { + processors: [ + { + inference: { + field_map: { + title: 'text_field', // Does not exist in index + }, + model_id: DEFAULT_MODELS[0].modelId, + target_field: 'ml.inference.title', + }, + }, + { + inference: { + field_map: { + body: 'text_field', // Exists in index + }, + model_id: DEFAULT_MODELS[0].modelId, + target_field: 'ml.inference.body', + }, + }, + { + inference: { + field_map: { + body_content: 'text_field', // Does not exist in index + }, + model_id: DEFAULT_MODELS[0].modelId, + target_field: 'ml.inference.body_content', + }, + }, + ], + version: 1, + }, + }); + + expect(PipelineSelectLogic.values.existingInferencePipelines).toEqual([ + { + disabled: true, + disabledReason: expect.stringContaining('title, body_content'), + modelId: DEFAULT_MODELS[0].modelId, + modelType: 'ner', + pipelineName: 'my-pipeline', + sourceFields: ['title', 'body', 'body_content'], + indexFields: ['body'], + }, + ]); + }); + it('returns enabled pipeline option if model is redacted', () => { + FetchMlInferencePipelinesApiLogic.actions.apiSuccess({ + 'my-pipeline': { + processors: [ + { + inference: { + field_map: { + body: 'text_field', + }, + model_id: '', // Redacted + target_field: 'ml.inference.body', + }, + }, + ], + version: 1, + }, + }); + + expect(PipelineSelectLogic.values.existingInferencePipelines).toEqual([ + { + disabled: false, + pipelineName: 'my-pipeline', + modelType: '', + modelId: '', + sourceFields: ['body'], + indexFields: ['body'], + }, + ]); + }); + it('filters pipeline if pipeline already attached', () => { + FetchMlInferencePipelineProcessorsApiLogic.actions.apiSuccess([ + { + modelId: DEFAULT_MODELS[0].modelId, + modelState: TrainedModelState.Started, + pipelineName: 'my-pipeline', + pipelineReferences: ['test@ml-inference'], + types: ['ner', 'pytorch'], + }, + ]); + FetchMlInferencePipelinesApiLogic.actions.apiSuccess(DEFAULT_PIPELINES); + + expect(PipelineSelectLogic.values.existingInferencePipelines).toEqual([]); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.ts new file mode 100644 index 0000000000000..1c294ab4f3aad --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_logic.ts @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { parseMlInferenceParametersFromPipeline } from '../../../../../../../common/ml_inference_pipeline'; + +import { getMLType } from '../../../shared/ml_inference/utils'; + +import { + MLInferenceLogic, + MLInferenceProcessorsActions, + MLInferenceProcessorsValues, +} from './ml_inference_logic'; +import { EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS } from './utils'; + +export interface MLInferencePipelineOption { + disabled: boolean; + disabledReason?: string; + modelId: string; + modelType: string; + pipelineName: string; + sourceFields: string[]; + indexFields: string[]; +} + +export interface PipelineSelectActions { + selectExistingPipeline: (pipelineName: string) => { + pipelineName: string; + }; + setInferencePipelineConfiguration: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; +} + +export interface PipelineSelectValues { + addInferencePipelineModal: MLInferenceProcessorsValues['addInferencePipelineModal']; + existingInferencePipelines: MLInferencePipelineOption[]; + mlInferencePipelineProcessors: MLInferenceProcessorsValues['mlInferencePipelineProcessors']; + mlInferencePipelinesData: MLInferenceProcessorsValues['mlInferencePipelinesData']; + selectableModels: MLInferenceProcessorsValues['selectableModels']; + sourceFields: MLInferenceProcessorsValues['sourceFields']; +} + +export const PipelineSelectLogic = kea<MakeLogicType<PipelineSelectValues, PipelineSelectActions>>({ + actions: { + selectExistingPipeline: (pipelineName: string) => ({ pipelineName }), + }, + connect: { + actions: [MLInferenceLogic, ['setInferencePipelineConfiguration']], + values: [ + MLInferenceLogic, + [ + 'addInferencePipelineModal', + 'mlInferencePipelineProcessors', + 'mlInferencePipelinesData', + 'selectableModels', + 'selectedModel', + 'sourceFields', + ], + ], + }, + path: ['enterprise_search', 'content', 'pipeline_select_logic'], + listeners: ({ actions, values }) => ({ + selectExistingPipeline: ({ pipelineName }) => { + const pipeline = values.mlInferencePipelinesData?.[pipelineName]; + if (!pipeline) return; + const params = parseMlInferenceParametersFromPipeline(pipelineName, pipeline); + if (params === null) return; + actions.setInferencePipelineConfiguration({ + existingPipeline: true, + modelID: params.model_id, + pipelineName, + fieldMappings: params.field_mappings, + targetField: '', + }); + }, + }), + selectors: ({ selectors }) => ({ + existingInferencePipelines: [ + () => [ + selectors.mlInferencePipelinesData, + selectors.sourceFields, + selectors.selectableModels, + selectors.mlInferencePipelineProcessors, + ], + ( + mlInferencePipelinesData: MLInferenceProcessorsValues['mlInferencePipelinesData'], + indexFields: MLInferenceProcessorsValues['sourceFields'], + selectableModels: MLInferenceProcessorsValues['selectableModels'], + mlInferencePipelineProcessors: MLInferenceProcessorsValues['mlInferencePipelineProcessors'] + ) => { + if (!mlInferencePipelinesData) { + return []; + } + const indexProcessorNames = + mlInferencePipelineProcessors?.map((processor) => processor.pipelineName) ?? []; + + const existingPipelines: MLInferencePipelineOption[] = Object.entries( + mlInferencePipelinesData + ) + .map(([pipelineName, pipeline]): MLInferencePipelineOption | undefined => { + if (!pipeline || indexProcessorNames.includes(pipelineName)) return undefined; + + // Parse configuration from pipeline definition + const pipelineParams = parseMlInferenceParametersFromPipeline(pipelineName, pipeline); + if (!pipelineParams) return undefined; + const { model_id: modelId, field_mappings: fieldMappings } = pipelineParams; + + const sourceFields = fieldMappings?.map((m) => m.sourceField) ?? []; + const missingSourceFields = sourceFields.filter((f) => !indexFields?.includes(f)) ?? []; + const mlModel = selectableModels.find((model) => model.modelId === modelId); + const modelType = mlModel ? getMLType(mlModel.types) : ''; + const disabledReason = + missingSourceFields.length > 0 + ? EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS(missingSourceFields.join(', ')) + : undefined; + + return { + disabled: disabledReason !== undefined, + disabledReason, + modelId, + modelType, + pipelineName, + sourceFields, + indexFields: indexFields ?? [], + }; + }) + .filter((p): p is MLInferencePipelineOption => p !== undefined); + + return existingPipelines; + }, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.test.tsx index fdf7da391fba6..66412779c9878 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.test.tsx @@ -13,7 +13,7 @@ import { EuiText, EuiTitle } from '@elastic/eui'; import { MLModelTypeBadge } from '../ml_model_type_badge'; -import { MLInferencePipelineOption } from './ml_inference_logic'; +import { MLInferencePipelineOption } from './pipeline_select_logic'; import { PipelineSelectOption, PipelineSelectOptionDisabled } from './pipeline_select_option'; import { MODEL_REDACTED_VALUE } from './utils'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.tsx index 49e00f30c12d4..f5fec5f54ac76 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/pipeline_select_option.tsx @@ -11,7 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiTextColor, EuiTitle } f import { MLModelTypeBadge } from '../ml_model_type_badge'; -import { MLInferencePipelineOption } from './ml_inference_logic'; +import { MLInferencePipelineOption } from './pipeline_select_logic'; import { EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS, MODEL_REDACTED_VALUE } from './utils'; export interface PipelineSelectOptionProps { From 786d3167f90ab6246c3424daab37d8495547d5bb Mon Sep 17 00:00:00 2001 From: Brad White <Ikuni17@users.noreply.github.com> Date: Fri, 9 Feb 2024 08:06:20 -0700 Subject: [PATCH 079/104] [build] Add FIPS image annotation / comments (#176555) The user has to download and dig through build logs to find out the tag for a FIPS image. This makes it available as a build annotation and in a PR comment. --- .buildkite/scripts/steps/fips/build.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.buildkite/scripts/steps/fips/build.sh b/.buildkite/scripts/steps/fips/build.sh index dcd3cc3b0bb2f..c54e16053b038 100644 --- a/.buildkite/scripts/steps/fips/build.sh +++ b/.buildkite/scripts/steps/fips/build.sh @@ -33,3 +33,14 @@ docker logout docker.elastic.co # Moving to `target/` first will keep `buildkite-agent` from including directories in the artifact name cd "$KIBANA_DIR/target" buildkite-agent artifact upload "./*docker-image*.tar.gz" + +KIBANA_UBI_FIPS_IMAGE="docker.elastic.co/kibana-ci/kibana-ubi-fips:$FULL_VERSION-$BUILDKITE_COMMIT" + +cat <<EOF | buildkite-agent annotate --style "info" --context fips + ### Kibana FIPS Image + + UBI image: \`$KIBANA_UBI_FIPS_IMAGE\` +EOF + +buildkite-agent meta-data set pr_comment:build_fips:head "* Kibana UBI FIPS Image: \`$KIBANA_UBI_FIPS_IMAGE\`" +buildkite-agent meta-data set pr_comment:early_comment_job_id "$BUILDKITE_JOB_ID" From 982a5bedb9178c9aa9905bac4b4c684779fe6869 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli <efstratia.kalafateli@elastic.co> Date: Fri, 9 Feb 2024 17:15:49 +0200 Subject: [PATCH 080/104] [Dashboard] Make the ES|QL panel more prominent (#176576) ## Summary ES|QL panel was not so prominent so I was asked to move it higher in the hierarchy. ![image (18)](https://github.com/elastic/kibana/assets/17003240/53ceb80a-0c8b-4b64-888e-da2fc74f8385) --- .../dashboard/public/dashboard_app/top_nav/editor_menu.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx index 7df2dec31ae90..7fe5c9343aa64 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx @@ -255,6 +255,7 @@ export const EditorMenu = ({ const getEditorMenuPanels = (closePopover: () => void) => { const initialPanelItems = [ ...visTypeAliases.map(getVisTypeAliasMenuItem), + ...getAddPanelActionMenuItems(api, addPanelActions, closePopover), ...toolVisTypes.map(getVisTypeMenuItem), ...ungroupedFactories.map((factory) => { return getEmbeddableFactoryMenuItem(factory, closePopover); @@ -265,9 +266,7 @@ export const EditorMenu = ({ panel: panelId, 'data-test-subj': `dashboardEditorMenu-${id}Group`, })), - ...promotedVisTypes.map(getVisTypeMenuItem), - ...getAddPanelActionMenuItems(api, addPanelActions, closePopover), ]; if (aggsBasedVisTypes.length > 0) { initialPanelItems.push({ From 429afa19ede8a9ad2a435f80959ee6f0be6ce965 Mon Sep 17 00:00:00 2001 From: Tiago Vila Verde <tiago.vilaverde@elastic.co> Date: Fri, 9 Feb 2024 16:33:34 +0100 Subject: [PATCH 081/104] [Security Solution][Entity Analytics] Change display labels for Asset criticality (#176571) This PR changes the labels in the asset criticality selector from ![image](https://github.com/elastic/security-team/assets/147995946/299de79b-cee4-4d9e-ba2c-08286d8f8512) to ![Screenshot 2024-02-09 at 10 49 28](https://github.com/elastic/kibana/assets/2423976/8ae0910f-44ab-4dda-ab6f-bdf12ec66ed4) --- .../components/asset_criticality/asset_criticality_badge.tsx | 2 +- .../asset_criticality/asset_criticality_selector.tsx | 2 +- .../tabs/risk_inputs/contexts_table.test.tsx | 2 +- .../cypress/e2e/entity_analytics/new_entity_flyout.cy.ts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx index 2fa32b82b8767..a28e0e9e4df8a 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_badge.tsx @@ -73,7 +73,7 @@ export const AssetCriticalityBadgeAllowMissing: React.FC<{ <EuiHealth color="subdued" data-test-subj={dataTestSubj}> <FormattedMessage id="xpack.securitySolution.entityAnalytics.assetCriticality.noCriticality" - defaultMessage="No criticality assigned" + defaultMessage="Criticality Unassigned" /> </EuiHealth> ); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx index c23fe47e9f4ff..f6a0da49197c8 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality/asset_criticality_selector.tsx @@ -104,7 +104,7 @@ const AssetCriticalityComponent: React.FC<Props> = ({ entity }) => { ) : ( <FormattedMessage id="xpack.securitySolution.entityAnalytics.assetCriticality.createButton" - defaultMessage="Create" + defaultMessage="Assign" /> )} </EuiButtonEmpty> diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs/contexts_table.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs/contexts_table.test.tsx index 14c8f466cede9..cabe9c68a36e6 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs/contexts_table.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs/contexts_table.test.tsx @@ -74,6 +74,6 @@ describe('ContextsTable', () => { expect(screen.getByText('Asset Criticality Level')).toBeInTheDocument(); expect(screen.getByTestId('risk-inputs-asset-criticality-badge')).toBeInTheDocument(); - expect(screen.getByText('No criticality assigned')).toBeInTheDocument(); + expect(screen.getByText('Criticality Unassigned')).toBeInTheDocument(); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/new_entity_flyout.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/new_entity_flyout.cy.ts index ad0b8b9c06b64..5817d338627ff 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/new_entity_flyout.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/new_entity_flyout.cy.ts @@ -112,7 +112,7 @@ describe( 'Asset Criticality' ); - cy.get(ENTITY_DETAILS_FLYOUT_ASSET_CRITICALITY_BUTTON).should('have.text', 'Create'); + cy.get(ENTITY_DETAILS_FLYOUT_ASSET_CRITICALITY_BUTTON).should('have.text', 'Assign'); }); it('should display asset criticality modal', () => { @@ -193,7 +193,7 @@ describe( 'Asset Criticality' ); - cy.get(ENTITY_DETAILS_FLYOUT_ASSET_CRITICALITY_BUTTON).should('have.text', 'Create'); + cy.get(ENTITY_DETAILS_FLYOUT_ASSET_CRITICALITY_BUTTON).should('have.text', 'Assign'); }); it('should display asset criticality modal', () => { From 20ed95d082af60c4c4ebeeeafb0bcac01b5ae1db Mon Sep 17 00:00:00 2001 From: Drew Tate <drew.tate@elastic.co> Date: Fri, 9 Feb 2024 08:53:37 -0700 Subject: [PATCH 082/104] [Managed content] Stabilize managed content test (#176549) Close https://github.com/elastic/kibana/issues/176545 --- .../test/functional/apps/managed_content/managed_content.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/managed_content/managed_content.ts b/x-pack/test/functional/apps/managed_content/managed_content.ts index c50a0c4d27571..959bddb9f8268 100644 --- a/x-pack/test/functional/apps/managed_content/managed_content.ts +++ b/x-pack/test/functional/apps/managed_content/managed_content.ts @@ -167,7 +167,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('inlines panels when managed dashboard cloned', async () => { await PageObjects.common.navigateToActualUrl( 'dashboard', - 'view/c44c86f9-b105-4a9c-9a24-449a58a827f3' + 'view/c44c86f9-b105-4a9c-9a24-449a58a827f3', + // for some reason the URL didn't always match the expected, so I turned off this check + // URL doesn't matter as long as we get the dashboard app + { ensureCurrentUrl: false } ); await PageObjects.dashboard.waitForRenderComplete(); From 5d833360f68862346389b87a33deb93260aa7ee5 Mon Sep 17 00:00:00 2001 From: Lola <omolola.akinleye@elastic.co> Date: Fri, 9 Feb 2024 10:58:28 -0500 Subject: [PATCH 083/104] [Cloud Security] add vulnerability subgrouping (#176351) ## Summary This feature adds subgrouping to the Vulnerabilities tab. * Enable subgrouping for three levels * Pagination between grouping levels * Group Selector can show up three data fields https://github.com/elastic/kibana/assets/17135495/73f69768-27cf-408e-bbb3-1a1d17a43838 --- .../use_latest_vulnerabilities_grouping.tsx | 25 ++- .../latest_vulnerabilities_container.tsx | 172 +++++++++++++----- .../pages/vulnerabilities_grouping.ts | 16 +- 3 files changed, 157 insertions(+), 56 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities_grouping.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities_grouping.tsx index f70da5fa27740..b83844416c076 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities_grouping.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/hooks/use_latest_vulnerabilities_grouping.tsx @@ -14,6 +14,7 @@ import { parseGroupingQuery, } from '@kbn/securitysolution-grouping/src'; import { useMemo } from 'react'; +import { buildEsQuery, Filter } from '@kbn/es-query'; import { LOCAL_STORAGE_VULNERABILITIES_GROUPING_KEY } from '../../../common/constants'; import { useDataViewContext } from '../../../common/contexts/data_view_context'; import { @@ -110,9 +111,15 @@ export const isVulnerabilitiesRootGroupingAggregation = ( export const useLatestVulnerabilitiesGrouping = ({ groupPanelRenderer, groupStatsRenderer, + groupingLevel = 0, + groupFilters = [], + selectedGroup, }: { groupPanelRenderer?: GroupPanelRenderer<VulnerabilitiesGroupingAggregation>; groupStatsRenderer?: GroupStatsRenderer<VulnerabilitiesGroupingAggregation>; + groupingLevel?: number; + groupFilters?: Filter[]; + selectedGroup?: string; }) => { const { dataView } = useDataViewContext(); @@ -121,7 +128,6 @@ export const useLatestVulnerabilitiesGrouping = ({ grouping, pageSize, query, - selectedGroup, onChangeGroupsItemsPerPage, onChangeGroupsPage, setUrlQuery, @@ -130,6 +136,7 @@ export const useLatestVulnerabilitiesGrouping = ({ onResetFilters, error, filters, + setActivePageIndex, } = useCloudSecurityGrouping({ dataView, groupingTitle, @@ -139,19 +146,22 @@ export const useLatestVulnerabilitiesGrouping = ({ groupPanelRenderer, groupStatsRenderer, groupingLocalStorageKey: LOCAL_STORAGE_VULNERABILITIES_GROUPING_KEY, - maxGroupingLevels: 1, + groupingLevel, }); + const additionalFilters = buildEsQuery(dataView, [], groupFilters); + const currentSelectedGroup = selectedGroup || grouping.selectedGroups[0]; + const groupingQuery = getGroupingQuery({ - additionalFilters: query ? [query] : [], - groupByField: selectedGroup, + additionalFilters: query ? [query, additionalFilters] : [additionalFilters], + groupByField: currentSelectedGroup, uniqueValue, from: `now-${LATEST_VULNERABILITIES_RETENTION_POLICY}`, to: 'now', pageNumber: activePageIndex * pageSize, size: pageSize, sort: [{ groupByField: { order: 'desc' } }], - statsAggregations: getAggregationsByGroupField(selectedGroup), + statsAggregations: getAggregationsByGroupField(currentSelectedGroup), }); const { data, isFetching } = useGroupedVulnerabilities({ @@ -162,11 +172,11 @@ export const useLatestVulnerabilitiesGrouping = ({ const groupData = useMemo( () => parseGroupingQuery( - selectedGroup, + currentSelectedGroup, uniqueValue, data as GroupingAggregation<VulnerabilitiesGroupingAggregation> ), - [data, selectedGroup, uniqueValue] + [data, currentSelectedGroup, uniqueValue] ); const isEmptyResults = @@ -179,6 +189,7 @@ export const useLatestVulnerabilitiesGrouping = ({ grouping, isFetching, activePageIndex, + setActivePageIndex, pageSize, selectedGroup, onChangeGroupsItemsPerPage, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_container.tsx index 8ba50c3aac4f1..6af307b79ad85 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_container.tsx @@ -5,7 +5,7 @@ * 2.0. */ import { Filter } from '@kbn/es-query'; -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { useLatestVulnerabilitiesGrouping } from './hooks/use_latest_vulnerabilities_grouping'; import { LatestVulnerabilitiesTable } from './latest_vulnerabilities_table'; @@ -17,31 +17,129 @@ import { CloudSecurityGrouping } from '../../components/cloud_security_grouping' import { DEFAULT_GROUPING_TABLE_HEIGHT } from '../../common/constants'; export const LatestVulnerabilitiesContainer = () => { - const renderChildComponent = (groupFilters: Filter[]) => { + const SubGrouping = ({ + renderChildComponent, + groupingLevel, + parentGroupFilters, + selectedGroup, + groupSelectorComponent, + }: { + renderChildComponent: (groupFilters: Filter[]) => JSX.Element; + groupingLevel: number; + parentGroupFilters?: string; + selectedGroup: string; + groupSelectorComponent?: JSX.Element; + }) => { + const { + groupData, + grouping, + isFetching, + activePageIndex, + pageSize, + onChangeGroupsItemsPerPage, + onChangeGroupsPage, + isGroupLoading, + setActivePageIndex, + } = useLatestVulnerabilitiesGrouping({ + groupPanelRenderer, + groupStatsRenderer, + groupingLevel, + selectedGroup, + groupFilters: parentGroupFilters ? JSON.parse(parentGroupFilters) : [], + }); + + /** + * This is used to reset the active page index when the selected group changes + * It is needed because the grouping number of pages can change according to the selected group + */ + useEffect(() => { + setActivePageIndex(0); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedGroup]); + return ( - <LatestVulnerabilitiesTable - nonPersistedFilters={groupFilters} - height={DEFAULT_GROUPING_TABLE_HEIGHT} + <CloudSecurityGrouping + data={groupData} + grouping={grouping} + renderChildComponent={renderChildComponent} + onChangeGroupsItemsPerPage={onChangeGroupsItemsPerPage} + onChangeGroupsPage={onChangeGroupsPage} + activePageIndex={activePageIndex} + isFetching={isFetching} + pageSize={pageSize} + selectedGroup={selectedGroup} + isGroupLoading={isGroupLoading} + groupingLevel={groupingLevel} + groupSelectorComponent={groupSelectorComponent} /> ); }; - const { - isGroupSelected, - groupData, - grouping, - isFetching, - activePageIndex, - pageSize, - selectedGroup, - onChangeGroupsItemsPerPage, - onChangeGroupsPage, - setUrlQuery, - isGroupLoading, - onResetFilters, - error, - isEmptyResults, - } = useLatestVulnerabilitiesGrouping({ groupPanelRenderer, groupStatsRenderer }); + const renderChildComponent = ({ + level, + currentSelectedGroup, + selectedGroupOptions, + parentGroupFilters, + groupSelectorComponent, + }: { + level: number; + currentSelectedGroup: string; + selectedGroupOptions: string[]; + parentGroupFilters?: string; + groupSelectorComponent?: JSX.Element; + }) => { + let getChildComponent; + + if (currentSelectedGroup === 'none') { + return ( + <LatestVulnerabilitiesTable + groupSelectorComponent={groupSelectorComponent} + nonPersistedFilters={[...(parentGroupFilters ? JSON.parse(parentGroupFilters) : [])]} + height={DEFAULT_GROUPING_TABLE_HEIGHT} + /> + ); + } + + if (level < selectedGroupOptions.length - 1 && !selectedGroupOptions.includes('none')) { + getChildComponent = (currentGroupFilters: Filter[]) => { + const nextGroupingLevel = level + 1; + return renderChildComponent({ + level: nextGroupingLevel, + currentSelectedGroup: selectedGroupOptions[nextGroupingLevel], + selectedGroupOptions, + parentGroupFilters: JSON.stringify([ + ...currentGroupFilters, + ...(parentGroupFilters ? JSON.parse(parentGroupFilters) : []), + ]), + groupSelectorComponent, + }); + }; + } else { + getChildComponent = (currentGroupFilters: Filter[]) => { + return ( + <LatestVulnerabilitiesTable + nonPersistedFilters={[ + ...currentGroupFilters, + ...(parentGroupFilters ? JSON.parse(parentGroupFilters) : []), + ]} + height={DEFAULT_GROUPING_TABLE_HEIGHT} + /> + ); + }; + } + return ( + <SubGrouping + renderChildComponent={getChildComponent} + selectedGroup={selectedGroupOptions[level]} + groupingLevel={level} + parentGroupFilters={parentGroupFilters} + groupSelectorComponent={groupSelectorComponent} + /> + ); + }; + + const { grouping, isFetching, setUrlQuery, onResetFilters, error, isEmptyResults } = + useLatestVulnerabilitiesGrouping({ groupPanelRenderer, groupStatsRenderer }); if (error || isEmptyResults) { return ( @@ -53,34 +151,18 @@ export const LatestVulnerabilitiesContainer = () => { </> ); } - if (isGroupSelected) { - return ( - <> - <FindingsSearchBar setQuery={setUrlQuery} loading={isFetching} /> - <div> - <EuiSpacer size="m" /> - <CloudSecurityGrouping - data={groupData} - grouping={grouping} - renderChildComponent={renderChildComponent} - onChangeGroupsItemsPerPage={onChangeGroupsItemsPerPage} - onChangeGroupsPage={onChangeGroupsPage} - activePageIndex={activePageIndex} - isFetching={isFetching} - pageSize={pageSize} - selectedGroup={selectedGroup} - isGroupLoading={isGroupLoading} - /> - </div> - </> - ); - } - return ( <> <FindingsSearchBar setQuery={setUrlQuery} loading={isFetching} /> <EuiSpacer size="m" /> - <LatestVulnerabilitiesTable groupSelectorComponent={grouping.groupSelector} /> + <div> + {renderChildComponent({ + level: 0, + currentSelectedGroup: grouping.selectedGroups[0], + selectedGroupOptions: grouping.selectedGroups, + groupSelectorComponent: grouping.groupSelector, + })} + </div> </> ); }; diff --git a/x-pack/test/cloud_security_posture_functional/pages/vulnerabilities_grouping.ts b/x-pack/test/cloud_security_posture_functional/pages/vulnerabilities_grouping.ts index b0eacf3ff7297..aa9ece3bbf9af 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/vulnerabilities_grouping.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/vulnerabilities_grouping.ts @@ -5,8 +5,8 @@ * 2.0. */ -import expect from '@kbn/expect'; import { asyncForEach } from '@kbn/std'; +import expect from '@kbn/expect'; import type { FtrProviderContext } from '../ftr_provider_context'; import { vulnerabilitiesLatestMock } from '../mocks/vulnerabilities_latest_mock'; @@ -44,9 +44,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); after(async () => { - const groupSelector = await findings.groupSelector(); - await groupSelector.openDropDown(); - await groupSelector.setValue('None'); await findings.vulnerabilitiesIndex.remove(); }); @@ -95,6 +92,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('groups vulnerabilities by CVE and sort by number of vulnerabilities desc', async () => { const groupSelector = findings.groupSelector(); await groupSelector.openDropDown(); + await groupSelector.setValue('None'); + await groupSelector.openDropDown(); await groupSelector.setValue('CVE'); const grouping = await findings.findingsGrouping(); @@ -133,6 +132,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('groups vulnerabilities by resource and sort by number of vulnerabilities desc', async () => { const groupSelector = findings.groupSelector(); await groupSelector.openDropDown(); + await groupSelector.setValue('None'); + await groupSelector.openDropDown(); await groupSelector.setValue('Resource'); const grouping = await findings.findingsGrouping(); @@ -172,7 +173,14 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); describe('SearchBar', () => { it('add filter', async () => { + const groupSelector = await findings.groupSelector(); + await groupSelector.openDropDown(); + await groupSelector.setValue('None'); + await groupSelector.openDropDown(); + await groupSelector.setValue('Resource'); + // Filter bar uses the field's customLabel in the DataView + await filterBar.addFilter({ field: 'Resource Name', operation: 'is', From fd8a9f07fd70acec29abd09c4d13bb9fce6f78ce Mon Sep 17 00:00:00 2001 From: Achyut Jhunjhunwala <achyut.jhunjhunwala@elastic.co> Date: Fri, 9 Feb 2024 17:46:48 +0100 Subject: [PATCH 084/104] [Logs Explorer] Add actions column (#175872) ## Summary Closes - https://github.com/elastic/kibana/issues/171728 ## What this PR does ? 1. Add customisation point for handling Leading and Trailing columns via a single customisation point. Currently the `Data Grid` exposes 2 separate customisation point for handling this - - `externalControlColumns` to add extension to `LeadingControlColumn` - `trailingControlColumns` to add extension to `TrailingControlColumns` But both of these extension point creates certain problems(Discover team can help in here) which this new extension point solves. 1. There exists a React Bug (may be because the way we bundle Kibana, not 100% sure) due to which when customControlColumns when passed to the above props like `externalControlColumns` or `trailingControlColumns`, even though they render inside the `<UnifiedDataTableContext.Provider value={unifiedDataTableContextValue}>` provider, they actually cannot access the context. For example when i tried to import the `ExpandButton` from the table directly and pass as it is to `trailingControlColumn` somehow 2 different context were getting created and the ExpandButton present in the LeadingColumn was getting access to context with data in it, where as the ExpandButton present in the Trailing Column which was passed via prop was ending up in different context and hence not receiving data. 2. Access to the `rows` data is very important. If context cannot be accessed, then accessing the row data becomes trickier. Hence this new Customisation Point solves the above problem by passing in both the control columns with reference and data and the consumer can then modify it accordingly. 2. Using the Customisation point described in point 1, 3 additional columns were added to the newly added Marker Control column - Expand Action. (Moved from 1st to last) - Malformed Document (In future this will be linked to a Fix IT flow) - Stacktraces available (In future this will be linked to the Flyout Tab, 4th Tab which will be Stacktrace) ## Demo <img width="2178" alt="image" src="https://github.com/elastic/kibana/assets/7416358/781eaaa3-d354-43ff-a570-aeee4dc6e80c"> ## What's pending - [x] Add E2E tests for the Control Column new icons - [x] Check for Memoisation probability in customControlColumns --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/lib/logs/index.ts | 3 + .../src/scenarios/simple_logs.ts | 39 ++++ packages/kbn-optimizer/limits.yml | 2 +- packages/kbn-unified-data-table/index.ts | 2 + .../src/components/data_table.test.tsx | 68 ++++++- .../src/components/data_table.tsx | 29 ++- .../src/components/data_table_columns.tsx | 16 +- .../components/data_table_expand_button.tsx | 5 +- .../src/components/data_table_row_control.tsx | 13 ++ packages/kbn-unified-data-table/src/types.ts | 15 ++ .../layout/discover_documents.test.tsx | 9 + .../components/layout/discover_documents.tsx | 9 +- .../data_table_customisation.ts | 7 +- src/plugins/discover/public/index.ts | 1 + test/functional/services/data_grid.ts | 25 ++- .../logs_explorer/common/constants.ts | 10 +- .../logs_explorer/common/document.ts | 10 + .../public/components/common/log_level.tsx | 6 +- .../public/components/common/popover_chip.tsx | 2 +- .../{translations.ts => translations.tsx} | 90 ++++++++- .../actions_column_tooltip.tsx | 99 +++++++++ .../resource_column_tooltip.tsx | 2 +- .../customizations/custom_control_column.tsx | 151 ++++++++++++++ .../customizations/logs_explorer_profile.tsx | 3 + .../logs_explorer_controller/src/defaults.ts | 1 + .../src/services/discover_service.ts | 31 ++- .../src/state_machine.ts | 9 + .../logs_explorer_controller/src/types.ts | 26 ++- .../utils/get_field_from_flattened_doc.ts | 15 ++ .../public/utils/get_stack_trace.ts | 22 ++ .../logs_explorer/public/utils/resource.ts | 8 +- .../columns_selection.ts | 24 +-- .../custom_control_columns.ts | 189 +++++++++++++++++ .../observability_logs_explorer/flyout.ts | 12 +- .../flyout_highlights.ts | 16 +- .../apps/observability_logs_explorer/index.ts | 1 + .../columns_selection.ts | 24 +-- .../custom_control_columns.ts | 191 ++++++++++++++++++ .../observability_logs_explorer/flyout.ts | 12 +- .../flyout_highlights.ts | 16 +- .../observability_logs_explorer/index.ts | 1 + 41 files changed, 1119 insertions(+), 95 deletions(-) create mode 100644 packages/kbn-unified-data-table/src/components/data_table_row_control.tsx rename x-pack/plugins/observability_solution/logs_explorer/public/components/common/{translations.ts => translations.tsx} (69%) create mode 100644 x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/actions_column_tooltip.tsx create mode 100644 x-pack/plugins/observability_solution/logs_explorer/public/customizations/custom_control_column.tsx create mode 100644 x-pack/plugins/observability_solution/logs_explorer/public/utils/get_field_from_flattened_doc.ts create mode 100644 x-pack/plugins/observability_solution/logs_explorer/public/utils/get_stack_trace.ts create mode 100644 x-pack/test/functional/apps/observability_logs_explorer/custom_control_columns.ts create mode 100644 x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/custom_control_columns.ts diff --git a/packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts index 7fdfa8cd9d8ba..3ba3e3a20bb96 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts @@ -36,6 +36,9 @@ export type LogDocument = Fields & 'cloud.availability_zone'?: string; 'cloud.project.id'?: string; 'cloud.instance.id'?: string; + 'error.stack_trace'?: string; + 'error.exception.stacktrace'?: string; + 'error.log.stacktrace'?: string; }>; class Log extends Serializable<LogDocument> { diff --git a/packages/kbn-apm-synthtrace/src/scenarios/simple_logs.ts b/packages/kbn-apm-synthtrace/src/scenarios/simple_logs.ts index f6eb4d11c80fc..16e9f6c3be405 100644 --- a/packages/kbn-apm-synthtrace/src/scenarios/simple_logs.ts +++ b/packages/kbn-apm-synthtrace/src/scenarios/simple_logs.ts @@ -9,6 +9,9 @@ import { LogDocument, log, generateShortId, generateLongId } from '@kbn/apm-synt import { Scenario } from '../cli/scenario'; import { withClient } from '../lib/utils/with_client'; +const MORE_THAN_1024_CHARS = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?'; + const scenario: Scenario<LogDocument> = async (runOptions) => { return { generate: ({ range, clients: { logsEsClient } }) => { @@ -111,6 +114,7 @@ const scenario: Scenario<LogDocument> = async (runOptions) => { .defaults({ 'trace.id': generateShortId(), 'error.message': MESSAGE_LOG_LEVELS[index].message, + 'error.exception.stacktrace': 'Error message in error.exception.stacktrace', 'agent.name': 'nodejs', 'orchestrator.cluster.name': CLUSTER[index].clusterName, 'orchestrator.cluster.id': CLUSTER[index].clusterId, @@ -143,6 +147,7 @@ const scenario: Scenario<LogDocument> = async (runOptions) => { .defaults({ 'trace.id': generateShortId(), 'event.original': MESSAGE_LOG_LEVELS[index].message, + 'error.log.stacktrace': 'Error message in error.log.stacktrace', 'agent.name': 'nodejs', 'orchestrator.cluster.name': CLUSTER[index].clusterName, 'orchestrator.cluster.id': CLUSTER[index].clusterId, @@ -186,6 +191,39 @@ const scenario: Scenario<LogDocument> = async (runOptions) => { 'cloud.project.id': generateShortId(), 'cloud.instance.id': generateShortId(), 'log.file.path': `/logs/${generateLongId()}/error.txt`, + 'error.stack_trace': 'Error message in error.stack_trace', + }) + .timestamp(timestamp); + }); + }); + + const malformedDocs = range + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(3) + .fill(0) + .map(() => { + const index = Math.floor(Math.random() * 3); + return log + .create() + .message(MESSAGE_LOG_LEVELS[index].message) + .logLevel(MORE_THAN_1024_CHARS) + .service(SERVICE_NAMES[index]) + .defaults({ + 'trace.id': generateShortId(), + 'agent.name': 'nodejs', + 'orchestrator.cluster.name': CLUSTER[index].clusterName, + 'orchestrator.cluster.id': CLUSTER[index].clusterId, + 'orchestrator.namespace': CLUSTER[index].namespace, + 'container.name': `${SERVICE_NAMES[index]}-${generateShortId()}`, + 'orchestrator.resource.id': generateShortId(), + 'cloud.provider': CLOUD_PROVIDERS[Math.floor(Math.random() * 3)], + 'cloud.region': CLOUD_REGION[index], + 'cloud.availability_zone': MORE_THAN_1024_CHARS, + 'cloud.project.id': generateShortId(), + 'cloud.instance.id': generateShortId(), + 'log.file.path': `/logs/${generateLongId()}/error.txt`, }) .timestamp(timestamp); }); @@ -199,6 +237,7 @@ const scenario: Scenario<LogDocument> = async (runOptions) => { logsWithErrorMessage, logsWithEventMessage, logsWithNoMessage, + malformedDocs, ]) ); }, diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 7910a362f5274..8b90dcbbe1a08 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -90,7 +90,7 @@ pageLoadAssetSize: licensing: 29004 links: 44490 lists: 22900 - logsExplorer: 50000 + logsExplorer: 55000 logsShared: 281060 logstash: 53548 management: 46112 diff --git a/packages/kbn-unified-data-table/index.ts b/packages/kbn-unified-data-table/index.ts index 823520884f63e..ce166f212e2ae 100644 --- a/packages/kbn-unified-data-table/index.ts +++ b/packages/kbn-unified-data-table/index.ts @@ -25,3 +25,5 @@ export { getRowsPerPageOptions } from './src/utils/rows_per_page'; export { popularizeField } from './src/utils/popularize_field'; export { useColumns } from './src/hooks/use_data_grid_columns'; +export { OPEN_DETAILS, SELECT_ROW } from './src/components/data_table_columns'; +export { DataTableRowControl } from './src/components/data_table_row_control'; diff --git a/packages/kbn-unified-data-table/src/components/data_table.test.tsx b/packages/kbn-unified-data-table/src/components/data_table.test.tsx index e69d1a88200ba..506cd046e9f1c 100644 --- a/packages/kbn-unified-data-table/src/components/data_table.test.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table.test.tsx @@ -24,7 +24,10 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { servicesMock } from '../../__mocks__/services'; import { buildDataTableRecord, getDocId } from '@kbn/discover-utils'; import type { DataTableRecord, EsHitRecord } from '@kbn/discover-utils/types'; -import { testLeadingControlColumn } from '../../__mocks__/external_control_columns'; +import { + testLeadingControlColumn, + testTrailingControlColumns, +} from '../../__mocks__/external_control_columns'; const mockUseDataGridColumnsCellActions = jest.fn((prop: unknown) => []); jest.mock('@kbn/cell-actions', () => ({ @@ -418,6 +421,69 @@ describe('UnifiedDataTable', () => { }); }); + describe('customControlColumnsConfiguration', () => { + const customControlColumnsConfiguration = jest.fn(); + it('should be able to customise the leading control column', async () => { + const component = await getComponent({ + ...getProps(), + expandedDoc: { + id: 'test', + raw: { + _index: 'test_i', + _id: 'test', + }, + flattened: { test: jest.fn() }, + }, + setExpandedDoc: jest.fn(), + renderDocumentView: jest.fn(), + externalControlColumns: [testLeadingControlColumn], + customControlColumnsConfiguration: customControlColumnsConfiguration.mockImplementation( + () => { + return { + leadingControlColumns: [testLeadingControlColumn, testTrailingControlColumns[0]], + trailingControlColumns: [], + }; + } + ), + }); + + expect(findTestSubject(component, 'test-body-control-column-cell').exists()).toBeTruthy(); + expect( + findTestSubject(component, 'test-trailing-column-popover-button').exists() + ).toBeTruthy(); + }); + + it('should be able to customise the trailing control column', async () => { + const component = await getComponent({ + ...getProps(), + expandedDoc: { + id: 'test', + raw: { + _index: 'test_i', + _id: 'test', + }, + flattened: { test: jest.fn() }, + }, + setExpandedDoc: jest.fn(), + renderDocumentView: jest.fn(), + externalControlColumns: [testLeadingControlColumn], + customControlColumnsConfiguration: customControlColumnsConfiguration.mockImplementation( + () => { + return { + leadingControlColumns: [], + trailingControlColumns: [testLeadingControlColumn, testTrailingControlColumns[0]], + }; + } + ), + }); + + expect(findTestSubject(component, 'test-body-control-column-cell').exists()).toBeTruthy(); + expect( + findTestSubject(component, 'test-trailing-column-popover-button').exists() + ).toBeTruthy(); + }); + }); + describe('externalControlColumns', () => { it('should render external leading control columns', async () => { const component = await getComponent({ diff --git a/packages/kbn-unified-data-table/src/components/data_table.tsx b/packages/kbn-unified-data-table/src/components/data_table.tsx index 33ff451adc972..7df0488b904c9 100644 --- a/packages/kbn-unified-data-table/src/components/data_table.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table.tsx @@ -52,12 +52,14 @@ import { DataTableColumnTypes, CustomCellRenderer, CustomGridColumnsConfiguration, + CustomControlColumnConfiguration, } from '../types'; import { getDisplayedColumns } from '../utils/columns'; import { convertValueToString } from '../utils/convert_value_to_string'; import { getRowsPerPageOptions } from '../utils/rows_per_page'; import { getRenderCellValueFn } from '../utils/get_render_cell_value'; import { + getAllControlColumns, getEuiGridColumns, getLeadControlColumns, getVisibleColumns, @@ -334,6 +336,10 @@ export interface UnifiedDataTableProps { * An optional settings for customising the column */ customGridColumnsConfiguration?: CustomGridColumnsConfiguration; + /** + * An optional settings to control which columns to render as trailing and leading control columns + */ + customControlColumnsConfiguration?: CustomControlColumnConfiguration; /** * Name of the UnifiedDataTable consumer component or application */ @@ -412,6 +418,7 @@ export const UnifiedDataTable = ({ gridStyleOverride, rowLineHeightOverride, customGridColumnsConfiguration, + customControlColumnsConfiguration, }: UnifiedDataTableProps) => { const { fieldFormats, toastNotifications, dataViewFieldEditor, uiSettings, storage, data } = services; @@ -746,19 +753,31 @@ export const UnifiedDataTable = ({ onSort: onTableSort, }; } - return { columns: sortingColumns, onSort: () => {} }; + return { + columns: sortingColumns, + onSort: () => {}, + }; }, [isSortEnabled, sortingColumns, isPlainRecord, inmemorySortingColumns, onTableSort]); const canSetExpandedDoc = Boolean(setExpandedDoc && !!renderDocumentView); - const leadingControlColumns = useMemo(() => { + const leadingControlColumns: EuiDataGridControlColumn[] = useMemo(() => { const internalControlColumns = getLeadControlColumns(canSetExpandedDoc).filter(({ id }) => controlColumnIds.includes(id) ); return externalControlColumns ? [...internalControlColumns, ...externalControlColumns] : internalControlColumns; - }, [canSetExpandedDoc, externalControlColumns, controlColumnIds]); + }, [canSetExpandedDoc, controlColumnIds, externalControlColumns]); + + const controlColumnsConfig = customControlColumnsConfiguration?.({ + controlColumns: getAllControlColumns(), + }); + + const customLeadingControlColumn = + controlColumnsConfig?.leadingControlColumns ?? leadingControlColumns; + const customTrailingControlColumn = + controlColumnsConfig?.trailingControlColumns ?? trailingControlColumns; const additionalControls = useMemo(() => { if (!externalAdditionalControls && !usedSelectedDocs.length) { @@ -907,7 +926,7 @@ export const UnifiedDataTable = ({ columns={euiGridColumns} columnVisibility={columnsVisibility} data-test-subj="docTable" - leadingControlColumns={leadingControlColumns} + leadingControlColumns={customLeadingControlColumn} onColumnResize={onResize} pagination={paginationObj} renderCellValue={renderCellValue} @@ -921,7 +940,7 @@ export const UnifiedDataTable = ({ gridStyle={gridStyleOverride ?? GRID_STYLE} renderCustomGridBody={renderCustomGridBody} renderCustomToolbar={renderCustomToolbarFn} - trailingControlColumns={trailingControlColumns} + trailingControlColumns={customTrailingControlColumn} /> </div> {loadingState !== DataLoadingState.loading && diff --git a/packages/kbn-unified-data-table/src/components/data_table_columns.tsx b/packages/kbn-unified-data-table/src/components/data_table_columns.tsx index 7393d3c034fa3..4c4208e30ec14 100644 --- a/packages/kbn-unified-data-table/src/components/data_table_columns.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table_columns.tsx @@ -17,7 +17,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import { ToastsStart, IUiSettingsClient } from '@kbn/core/public'; import { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; import { ExpandButton } from './data_table_expand_button'; -import { CustomGridColumnsConfiguration, UnifiedDataTableSettings } from '../types'; +import { ControlColumns, CustomGridColumnsConfiguration, UnifiedDataTableSettings } from '../types'; import type { ValueToStringConverter, DataTableColumnTypes } from '../types'; import { buildCellActions } from './default_cell_actions'; import { getSchemaByKbnType } from './data_table_schema'; @@ -30,8 +30,11 @@ import { DataTableColumnHeader, DataTableTimeColumnHeader } from './data_table_c const DataTableColumnHeaderMemoized = React.memo(DataTableColumnHeader); const DataTableTimeColumnHeaderMemoized = React.memo(DataTableTimeColumnHeader); +export const OPEN_DETAILS = 'openDetails'; +export const SELECT_ROW = 'select'; + const openDetails = { - id: 'openDetails', + id: OPEN_DETAILS, width: 26, headerCellRender: () => ( <EuiScreenReaderOnly> @@ -46,7 +49,7 @@ const openDetails = { }; const select = { - id: 'select', + id: SELECT_ROW, width: 24, rowCellRender: SelectButton, headerCellRender: () => ( @@ -60,6 +63,13 @@ const select = { ), }; +export function getAllControlColumns(): ControlColumns { + return { + [SELECT_ROW]: select, + [OPEN_DETAILS]: openDetails, + }; +} + export function getLeadControlColumns(canSetExpandedDoc: boolean) { if (!canSetExpandedDoc) { return [select]; diff --git a/packages/kbn-unified-data-table/src/components/data_table_expand_button.tsx b/packages/kbn-unified-data-table/src/components/data_table_expand_button.tsx index c44ea74791b33..9538df4d3da03 100644 --- a/packages/kbn-unified-data-table/src/components/data_table_expand_button.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table_expand_button.tsx @@ -11,6 +11,7 @@ import { EuiButtonIcon, EuiDataGridCellValueElementProps, EuiToolTip } from '@el import { euiLightVars as themeLight, euiDarkVars as themeDark } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; import { UnifiedDataTableContext } from '../table_context'; +import { DataTableRowControl } from './data_table_row_control'; /** * Button to expand a given row @@ -62,7 +63,7 @@ export const ExpandButton = ({ rowIndex, setCellProps }: EuiDataGridCellValueEle } return ( - <div className="unifiedDataTable__rowControl"> + <DataTableRowControl> <EuiToolTip content={buttonLabel} delay="long" ref={toolTipRef}> <EuiButtonIcon id={rowIndex === 0 ? tourStep : undefined} @@ -81,6 +82,6 @@ export const ExpandButton = ({ rowIndex, setCellProps }: EuiDataGridCellValueEle isSelected={isCurrentRowExpanded} /> </EuiToolTip> - </div> + </DataTableRowControl> ); }; diff --git a/packages/kbn-unified-data-table/src/components/data_table_row_control.tsx b/packages/kbn-unified-data-table/src/components/data_table_row_control.tsx new file mode 100644 index 0000000000000..4ceadea549dce --- /dev/null +++ b/packages/kbn-unified-data-table/src/components/data_table_row_control.tsx @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +export const DataTableRowControl = ({ children }: { children: React.ReactNode }) => { + return <span className="unifiedDataTable__rowControl">{children}</span>; +}; diff --git a/packages/kbn-unified-data-table/src/types.ts b/packages/kbn-unified-data-table/src/types.ts index a27f1db510cbe..38d305d0c6177 100644 --- a/packages/kbn-unified-data-table/src/types.ts +++ b/packages/kbn-unified-data-table/src/types.ts @@ -11,6 +11,7 @@ import { EuiDataGridCellValueElementProps, type EuiDataGridColumn } from '@elast import type { DataTableRecord } from '@kbn/discover-utils/src/types'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { EuiDataGridControlColumn } from '@elastic/eui/src/components/datagrid/data_grid_types'; /** * User configurable state of data grid, persisted in saved search @@ -55,3 +56,17 @@ export type CustomGridColumnsConfiguration = Record< string, (props: CustomGridColumnProps) => EuiDataGridColumn >; + +export interface ControlColumns { + select: EuiDataGridControlColumn; + openDetails: EuiDataGridControlColumn; +} + +export interface ControlColumnsProps { + controlColumns: ControlColumns; +} + +export type CustomControlColumnConfiguration = (props: ControlColumnsProps) => { + leadingControlColumns: EuiDataGridControlColumn[]; + trailingControlColumns?: EuiDataGridControlColumn[]; +}; diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx index 524c01be98a5e..62c38fe43a3b7 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.test.tsx @@ -120,10 +120,16 @@ describe('Discover documents layout', () => { }), }; + const customControlColumnsConfiguration = () => ({ + leadingControlColumns: [], + trailingControlColumns: [], + }); + const customization: DiscoverCustomization = { id: 'data_table', customCellRenderer, customGridColumnsConfiguration, + customControlColumnsConfiguration, }; customisationService.set(customization); @@ -135,5 +141,8 @@ describe('Discover documents layout', () => { expect(discoverGridComponent.prop('customGridColumnsConfiguration')).toEqual( customGridColumnsConfiguration ); + expect(discoverGridComponent.prop('customControlColumnsConfiguration')).toEqual( + customControlColumnsConfiguration + ); }); }); diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 636748a44123b..604d2b0a27d53 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -255,9 +255,11 @@ function DiscoverDocumentsComponent({ [dataView, onAddColumn, onAddFilter, onRemoveColumn, query, savedSearch.id, setExpandedDoc] ); - const externalCustomRenderers = useDiscoverCustomization('data_table')?.customCellRenderer; - const customGridColumnsConfiguration = - useDiscoverCustomization('data_table')?.customGridColumnsConfiguration; + const { + customCellRenderer: externalCustomRenderers, + customGridColumnsConfiguration, + customControlColumnsConfiguration, + } = useDiscoverCustomization('data_table') || {}; const documents = useObservable(stateContainer.dataState.data$.documents$); @@ -427,6 +429,7 @@ function DiscoverDocumentsComponent({ headerRowHeight={3} externalCustomRenderers={externalCustomRenderers} customGridColumnsConfiguration={customGridColumnsConfiguration} + customControlColumnsConfiguration={customControlColumnsConfiguration} /> </CellActionsProvider> </div> diff --git a/src/plugins/discover/public/customizations/customization_types/data_table_customisation.ts b/src/plugins/discover/public/customizations/customization_types/data_table_customisation.ts index 4e783a832f0b8..2ed371fd2109e 100644 --- a/src/plugins/discover/public/customizations/customization_types/data_table_customisation.ts +++ b/src/plugins/discover/public/customizations/customization_types/data_table_customisation.ts @@ -6,10 +6,15 @@ * Side Public License, v 1. */ -import { CustomCellRenderer, CustomGridColumnsConfiguration } from '@kbn/unified-data-table'; +import { + CustomCellRenderer, + CustomControlColumnConfiguration, + CustomGridColumnsConfiguration, +} from '@kbn/unified-data-table'; export interface DataTableCustomization { id: 'data_table'; customCellRenderer?: CustomCellRenderer; customGridColumnsConfiguration?: CustomGridColumnsConfiguration; + customControlColumnsConfiguration?: CustomControlColumnConfiguration; } diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 5fff8866e7fbc..b21a76fe9e596 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -17,6 +17,7 @@ export function plugin(initializerContext: PluginInitializerContext) { export type { ISearchEmbeddable, SearchInput } from './embeddable'; export type { DiscoverAppState } from './application/main/services/discover_app_state_container'; export type { DiscoverStateContainer } from './application/main/services/discover_state'; +export type { DataDocumentsMsg } from './application/main/services/discover_data_state_container'; export type { DiscoverContainerProps } from './components/discover_container'; export type { CustomizationCallback, diff --git a/test/functional/services/data_grid.ts b/test/functional/services/data_grid.ts index 88b95fc8a4ab6..b139392c0f5c9 100644 --- a/test/functional/services/data_grid.ts +++ b/test/functional/services/data_grid.ts @@ -15,9 +15,11 @@ export interface TabbedGridData { columns: string[]; rows: string[][]; } + interface SelectOptions { isAnchorRow?: boolean; rowIndex?: number; + columnIndex?: number; renderMoreRows?: boolean; } @@ -242,13 +244,14 @@ export class DataGridService extends FtrService { } public async clickRowToggle( - options: SelectOptions = { isAnchorRow: false, rowIndex: 0 } + options: SelectOptions = { isAnchorRow: false, rowIndex: 0, columnIndex: 0 } ): Promise<void> { - const row = await this.getRow(options); + const rowColumns = await this.getRow(options); const testSubj = options.isAnchorRow ? '~docTableExpandToggleColumnAnchor' : '~docTableExpandToggleColumn'; - const toggle = await row[0].findByTestSubject(testSubj); + + const toggle = await rowColumns[options.columnIndex ?? 0].findByTestSubject(testSubj); await toggle.scrollIntoViewIfNecessary(); await toggle.click(); @@ -272,7 +275,20 @@ export class DataGridService extends FtrService { const cellText = await cell.getVisibleText(); textArr.push(cellText.trim()); } - return Promise.resolve(textArr); + return textArr; + } + + public async getControlColumnHeaderFields(): Promise<string[]> { + const result = await this.find.allByCssSelector( + '.euiDataGridHeaderCell--controlColumn > .euiDataGridHeaderCell__content' + ); + + const textArr = []; + for (const cell of result) { + const cellText = await cell.getVisibleText(); + textArr.push(cellText.trim()); + } + return textArr; } public async getRowActions( @@ -393,6 +409,7 @@ export class DataGridService extends FtrService { const detailRows = await this.getDetailsRows(); return detailRows[0]; } + public async addInclusiveFilter(detailsRow: WebElementWrapper, fieldName: string): Promise<void> { const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName); const addInclusiveFilterButton = await this.getAddInclusiveFilterButton(tableDocViewRow); diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts b/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts index 37182444b8894..7e546e9863446 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts @@ -34,6 +34,14 @@ export const ORCHESTRATOR_NAMESPACE_FIELD = 'orchestrator.namespace'; export const CONTAINER_NAME_FIELD = 'container.name'; export const CONTAINER_ID_FIELD = 'container.id'; +// Malformed Docs +export const MALFORMED_DOCS_FIELD = 'ignored_field_values'; + +// Error Stacktrace +export const ERROR_STACK_TRACE = 'error.stack_trace'; +export const ERROR_EXCEPTION_STACKTRACE = 'error.exception.stacktrace'; +export const ERROR_LOG_STACKTRACE = 'error.log.stacktrace'; + // Virtual column fields export const CONTENT_FIELD = 'content'; export const RESOURCE_FIELD = 'resource'; @@ -41,7 +49,7 @@ export const RESOURCE_FIELD = 'resource'; // Sizing export const DATA_GRID_COLUMN_WIDTH_SMALL = 240; export const DATA_GRID_COLUMN_WIDTH_MEDIUM = 320; - +export const ACTIONS_COLUMN_WIDTH = 80; // UI preferences export const DEFAULT_COLUMNS = [ { diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/document.ts b/x-pack/plugins/observability_solution/logs_explorer/common/document.ts index e9b97f1671f1e..778d8546c2d1c 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/document.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/document.ts @@ -33,6 +33,10 @@ export interface LogDocument extends DataTableRecord { 'log.file.path'?: string; 'data_stream.namespace': string; 'data_stream.dataset': string; + + 'error.stack_trace'?: string; + 'error.exception.stacktrace'?: string; + 'error.log.stacktrace'?: string; }; } @@ -74,3 +78,9 @@ export interface ResourceFields { 'container.id'?: string; 'cloud.instance.id'?: string; } + +export interface StackTraceFields { + 'error.stack_trace'?: string; + 'error.exception.stacktrace'?: string; + 'error.log.stacktrace'?: string; +} diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/log_level.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/log_level.tsx index 5cc883b1f40b4..9f5dfef23ce0d 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/log_level.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/log_level.tsx @@ -31,11 +31,13 @@ export function LogLevel({ level, dataTestSubj, renderInFlyout = false }: LogLev ? euiTheme.colors[LEVEL_DICT[level as keyof typeof LEVEL_DICT]] : null; + const truncatedLogLevel = level.length > 10 ? level.substring(0, 10) + '...' : level; + if (renderInFlyout) { return ( <ChipWithPopover property={constants.LOG_LEVEL_FIELD} - text={level} + text={truncatedLogLevel} borderColor={levelColor} style={{ width: 'none' }} dataTestSubj={dataTestSubj} @@ -50,7 +52,7 @@ export function LogLevel({ level, dataTestSubj, renderInFlyout = false }: LogLev text={level} rightSideIcon="arrowDown" borderColor={levelColor} - style={{ width: '80px' }} + style={{ width: '80px', marginTop: '-3px' }} /> ); } diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx index 953c75bc480cc..bb5d4a5ed85d7 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx @@ -78,7 +78,7 @@ export function ChipWithPopover({ font-size: ${xsFontSize}; display: flex; justify-content: center; - margin-top: -3px; + cursor: pointer; `} style={style} > diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.ts b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.tsx similarity index 69% rename from x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.ts rename to x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.tsx index 168ea6e2995cb..5debc38c3f25f 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/translations.tsx @@ -5,7 +5,10 @@ * 2.0. */ +import React from 'react'; import { i18n } from '@kbn/i18n'; +import { EuiCode } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; export const flyoutContentLabel = i18n.translate('xpack.logsExplorer.flyoutDetail.label.message', { defaultMessage: 'Content breakdown', @@ -22,6 +25,17 @@ export const resourceLabel = i18n.translate( } ); +export const actionsLabel = i18n.translate('xpack.logsExplorer.dataTable.header.popover.actions', { + defaultMessage: 'Actions', +}); + +export const actionsLabelLowerCase = i18n.translate( + 'xpack.logsExplorer.dataTable.header.popover.actions.lowercase', + { + defaultMessage: 'actions', + } +); + export const flyoutServiceLabel = i18n.translate('xpack.logsExplorer.flyoutDetail.label.service', { defaultMessage: 'Service', }); @@ -208,17 +222,21 @@ export const closeCellActionPopoverText = i18n.translate( } ); -export const contentHeaderTooltipParagraph1 = i18n.translate( - 'xpack.logsExplorer.dataTable.header.content.tooltip.paragraph1', - { - defaultMessage: "Fields that provide information on the document's source, such as:", - } +export const contentHeaderTooltipParagraph1 = ( + <FormattedMessage + id="xpack.logsExplorer.dataTable.header.content.tooltip.paragraph1" + defaultMessage="Displays the document's {logLevel} and {message} fields." + values={{ + logLevel: <strong>log.level</strong>, + message: <strong>message</strong>, + }} + /> ); export const contentHeaderTooltipParagraph2 = i18n.translate( 'xpack.logsExplorer.dataTable.header.content.tooltip.paragraph2', { - defaultMessage: 'When the message field is empty, one of the following is displayed', + defaultMessage: 'When the message field is empty, one of the following is displayed:', } ); @@ -228,3 +246,63 @@ export const resourceHeaderTooltipParagraph = i18n.translate( defaultMessage: "Fields that provide information on the document's source, such as:", } ); + +export const actionsHeaderTooltipParagraph = i18n.translate( + 'xpack.logsExplorer.dataTable.header.actions.tooltip.paragraph', + { + defaultMessage: 'Fields that provide actionable information, such as:', + } +); + +export const actionsHeaderTooltipExpandAction = i18n.translate( + 'xpack.logsExplorer.dataTable.header.actions.tooltip.expand', + { defaultMessage: 'Expand log details' } +); + +export const actionsHeaderTooltipMalformedAction = ( + <FormattedMessage + id="xpack.logsExplorer.dataTable.controlColumn.actions.button.malformedDoc" + defaultMessage="Access to malformed doc with {ignoredProperty} field" + values={{ + ignoredProperty: ( + <EuiCode language="json" transparentBackground> + _ignored + </EuiCode> + ), + }} + /> +); + +export const actionsHeaderTooltipStacktraceAction = i18n.translate( + 'xpack.logsExplorer.dataTable.header.actions.tooltip.stacktrace', + { defaultMessage: 'Access to available stacktraces based on:' } +); + +export const malformedDocButtonLabelWhenPresent = i18n.translate( + 'xpack.logsExplorer.dataTable.controlColumn.actions.button.malformedDocPresent', + { + defaultMessage: + "This document couldn't be parsed correctly. Not all fields are properly populated", + } +); + +export const malformedDocButtonLabelWhenNotPresent = i18n.translate( + 'xpack.logsExplorer.dataTable.controlColumn.actions.button.malformedDocNotPresent', + { + defaultMessage: 'All fields in this document were parsed correctly', + } +); + +export const stacktraceAvailableControlButton = i18n.translate( + 'xpack.logsExplorer.dataTable.controlColumn.actions.button.stacktrace.available', + { + defaultMessage: 'Stacktraces available', + } +); + +export const stacktraceNotAvailableControlButton = i18n.translate( + 'xpack.logsExplorer.dataTable.controlColumn.actions.button.stacktrace.notAvailable', + { + defaultMessage: 'Stacktraces not available', + } +); diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/actions_column_tooltip.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/actions_column_tooltip.tsx new file mode 100644 index 0000000000000..95c7a7b4c9468 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/actions_column_tooltip.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { css } from '@emotion/react'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { + actionsHeaderTooltipExpandAction, + actionsHeaderTooltipMalformedAction, + actionsHeaderTooltipParagraph, + actionsHeaderTooltipStacktraceAction, + actionsLabel, + actionsLabelLowerCase, +} from '../../common/translations'; +import { HoverPopover } from '../../common/hover_popover'; +import { TooltipButtonComponent } from './tooltip_button'; +import * as constants from '../../../../common/constants'; +import { FieldWithToken } from './field_with_token'; + +const spacingCSS = css` + margin-bottom: ${euiThemeVars.euiSizeS}; +`; + +export const ActionsColumnTooltip = () => { + return ( + <HoverPopover + button={<TooltipButtonComponent displayText={actionsLabelLowerCase} />} + title={actionsLabel} + > + <div style={{ width: '230px' }}> + <EuiText size="s" css={spacingCSS}> + <p>{actionsHeaderTooltipParagraph}</p> + </EuiText> + <EuiFlexGroup + responsive={false} + alignItems="baseline" + justifyContent="flexStart" + gutterSize="s" + css={spacingCSS} + > + <EuiFlexItem grow={false}> + <EuiIcon type="expand" size="s" /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiText size="s"> + <p>{actionsHeaderTooltipExpandAction}</p> + </EuiText> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup + responsive={false} + alignItems="baseline" + justifyContent="flexStart" + gutterSize="s" + css={spacingCSS} + > + <EuiFlexItem grow={false}> + <EuiIcon type="indexClose" size="s" color="danger" /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiText size="s"> + <p>{actionsHeaderTooltipMalformedAction}</p> + </EuiText> + </EuiFlexItem> + </EuiFlexGroup> + <EuiFlexGroup + responsive={false} + alignItems="baseline" + justifyContent="flexStart" + gutterSize="s" + css={spacingCSS} + > + <EuiFlexItem grow={false}> + <EuiIcon type="apmTrace" size="s" /> + </EuiFlexItem> + <EuiFlexItem grow={false}> + <EuiText size="s"> + <p>{actionsHeaderTooltipStacktraceAction}</p> + </EuiText> + </EuiFlexItem> + </EuiFlexGroup> + <div style={{ marginLeft: '15px' }}> + {[ + constants.ERROR_STACK_TRACE, + constants.ERROR_EXCEPTION_STACKTRACE, + constants.ERROR_LOG_STACKTRACE, + ].map((field) => ( + <FieldWithToken field={field} key={field} /> + ))} + </div> + </div> + </HoverPopover> + ); +}; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/resource_column_tooltip.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/resource_column_tooltip.tsx index 6e6f62e274a9f..57e51097e391a 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/resource_column_tooltip.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/column_tooltips/resource_column_tooltip.tsx @@ -42,7 +42,7 @@ export const ResourceColumnTooltip = ({ column, headerRowHeight }: CustomGridCol constants.HOST_NAME_FIELD, constants.CLOUD_INSTANCE_ID_FIELD, ].map((field) => ( - <FieldWithToken field={field} /> + <FieldWithToken field={field} key={field} /> ))} </div> </HoverPopover> diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/customizations/custom_control_column.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/custom_control_column.tsx new file mode 100644 index 0000000000000..5caee8b6e82e1 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/custom_control_column.tsx @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, { ComponentClass } from 'react'; +import { + OPEN_DETAILS, + SELECT_ROW, + type ControlColumnsProps, + DataTableRowControl, +} from '@kbn/unified-data-table'; +import { EuiButtonIcon, EuiDataGridCellValueElementProps, EuiToolTip } from '@elastic/eui'; +import type { DataTableRecord } from '@kbn/discover-utils/src/types'; +import { useActor } from '@xstate/react'; +import { LogsExplorerControllerStateService } from '../state_machines/logs_explorer_controller'; +import { + malformedDocButtonLabelWhenNotPresent, + malformedDocButtonLabelWhenPresent, + stacktraceAvailableControlButton, + stacktraceNotAvailableControlButton, +} from '../components/common/translations'; +import * as constants from '../../common/constants'; +import { getStacktraceFields } from '../utils/get_stack_trace'; +import { LogDocument } from '../../common/document'; +import { ActionsColumnTooltip } from '../components/virtual_columns/column_tooltips/actions_column_tooltip'; + +const ConnectedMalformedDocs = ({ + rowIndex, + service, +}: { + rowIndex: number; + service: LogsExplorerControllerStateService; +}) => { + const [state] = useActor(service); + + if (state.matches('initialized') && state.context.rows) { + const row = state.context.rows[rowIndex]; + return <MalformedDocs row={row} rowIndex={rowIndex} />; + } + + return null; +}; + +const ConnectedStacktraceDocs = ({ + rowIndex, + service, +}: { + rowIndex: number; + service: LogsExplorerControllerStateService; +}) => { + const [state] = useActor(service); + + if (state.matches('initialized') && state.context.rows) { + const row = state.context.rows[rowIndex]; + return <Stacktrace row={row} rowIndex={rowIndex} />; + } + + return null; +}; + +const MalformedDocs = ({ row, rowIndex }: { row: DataTableRecord; rowIndex: number }) => { + const isMalformedDocumentExists = !!row.raw[constants.MALFORMED_DOCS_FIELD]; + + return isMalformedDocumentExists ? ( + <DataTableRowControl> + <EuiToolTip content={malformedDocButtonLabelWhenPresent} delay="long"> + <EuiButtonIcon + id={`malformedDocExists_${rowIndex}`} + size="xs" + iconSize="s" + data-test-subj={'docTableMalformedDocExist'} + color={'danger'} + aria-label={malformedDocButtonLabelWhenPresent} + iconType={'indexClose'} + /> + </EuiToolTip> + </DataTableRowControl> + ) : ( + <DataTableRowControl> + <EuiToolTip content={malformedDocButtonLabelWhenNotPresent} delay="long"> + <EuiButtonIcon + id={`malformedDocExists_${rowIndex}`} + size="xs" + iconSize="s" + data-test-subj={'docTableMalformedDocDoesNotExist'} + color={'text'} + iconType={'pagesSelect'} + aria-label={malformedDocButtonLabelWhenNotPresent} + /> + </EuiToolTip> + </DataTableRowControl> + ); +}; + +const Stacktrace = ({ row, rowIndex }: { row: DataTableRecord; rowIndex: number }) => { + const stacktrace = getStacktraceFields(row as LogDocument); + const hasValue = Object.values(stacktrace).some((value) => value); + + return ( + <DataTableRowControl> + <EuiToolTip + content={hasValue ? stacktraceAvailableControlButton : stacktraceNotAvailableControlButton} + delay="long" + > + <EuiButtonIcon + id={`stacktrace_${rowIndex}`} + size="xs" + iconSize="s" + data-test-subj={hasValue ? 'docTableStacktraceExist' : 'docTableStacktraceDoesNotExist'} + color={'text'} + iconType={'apmTrace'} + aria-label={ + hasValue ? stacktraceAvailableControlButton : stacktraceNotAvailableControlButton + } + disabled={!hasValue} + /> + </EuiToolTip> + </DataTableRowControl> + ); +}; + +export const createCustomControlColumnsConfiguration = + (service: LogsExplorerControllerStateService) => + ({ controlColumns }: ControlColumnsProps) => { + const checkBoxColumn = controlColumns[SELECT_ROW]; + const openDetails = controlColumns[OPEN_DETAILS]; + const ExpandButton = + openDetails.rowCellRender as ComponentClass<EuiDataGridCellValueElementProps>; + const actionsColumn = { + id: 'actionsColumn', + width: constants.ACTIONS_COLUMN_WIDTH, + headerCellRender: ActionsColumnTooltip, + rowCellRender: ({ rowIndex, setCellProps, ...rest }: EuiDataGridCellValueElementProps) => { + return ( + <span> + <ExpandButton rowIndex={rowIndex} setCellProps={setCellProps} {...rest} /> + <ConnectedMalformedDocs rowIndex={rowIndex} service={service} /> + <ConnectedStacktraceDocs rowIndex={rowIndex} service={service} /> + </span> + ); + }, + }; + + return { + leadingControlColumns: [checkBoxColumn], + trailingControlColumns: [actionsColumn], + }; + }; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx index 54147baf4a221..faa8c8d4a51ee 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx @@ -87,6 +87,9 @@ export const createLogsExplorerProfileCustomizations = id: 'data_table', customCellRenderer: createCustomCellRenderer({ data }), customGridColumnsConfiguration: createCustomGridColumnsConfiguration(), + customControlColumnsConfiguration: await import('./custom_control_column').then((module) => + module.createCustomControlColumnsConfiguration(service) + ), }); /** diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/defaults.ts b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/defaults.ts index 0030f45c638d1..a097d23ac7349 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/defaults.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/defaults.ts @@ -40,4 +40,5 @@ export const DEFAULT_CONTEXT: DefaultLogsExplorerControllerState = { from: 'now-15m/m', to: 'now', }, + rows: [], }; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/services/discover_service.ts b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/services/discover_service.ts index 4abc91ca47d8d..b4644cb635d4a 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/services/discover_service.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/services/discover_service.ts @@ -26,9 +26,9 @@ export const subscribeToDiscoverState = throw new Error('Failed to subscribe to the Discover state: no state container in context.'); } - const { appState } = context.discoverStateContainer; + const { appState, dataState } = context.discoverStateContainer; - const subscription = appState.state$.subscribe({ + const appStateSubscription = appState.state$.subscribe({ next: (newAppState) => { if (isEmpty(newAppState)) { return; @@ -41,8 +41,20 @@ export const subscribeToDiscoverState = }, }); + const dataStateSubscription = dataState.data$.documents$.subscribe({ + next: (newDataState) => { + if (!isEmpty(newDataState?.result)) { + send({ + type: 'RECEIVE_DISCOVER_DATA_STATE', + dataState: newDataState.result, + }); + } + }, + }); + return () => { - subscription.unsubscribe(); + appStateSubscription.unsubscribe(); + dataStateSubscription.unsubscribe(); }; }; @@ -71,6 +83,19 @@ export const updateContextFromDiscoverAppState = actions.assign< return {}; }); +export const updateContextFromDiscoverDataState = actions.assign< + LogsExplorerControllerContext, + LogsExplorerControllerEvent +>((context, event) => { + if ('dataState' in event && event.type === 'RECEIVE_DISCOVER_DATA_STATE') { + return { + rows: event.dataState, + }; + } + + return {}; +}); + export const updateDiscoverAppStateFromContext: ActionFunction< LogsExplorerControllerContext, LogsExplorerControllerEvent diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/state_machine.ts b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/state_machine.ts index b1cba428d4c4e..3c244a73bbd5b 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/state_machine.ts @@ -25,6 +25,7 @@ import { createAndSetDataView } from './services/data_view_service'; import { subscribeToDiscoverState, updateContextFromDiscoverAppState, + updateContextFromDiscoverDataState, updateDiscoverAppStateFromContext, } from './services/discover_service'; import { validateSelection } from './services/selection_service'; @@ -103,6 +104,7 @@ export const createPureLogsExplorerControllerStateMachine = ( id: 'timefilterService', }, ], + entry: ['resetRows'], states: { datasetSelection: { initial: 'validatingSelection', @@ -196,6 +198,9 @@ export const createPureLogsExplorerControllerStateMachine = ( RECEIVE_DISCOVER_APP_STATE: { actions: ['updateContextFromDiscoverAppState'], }, + RECEIVE_DISCOVER_DATA_STATE: { + actions: ['updateContextFromDiscoverDataState'], + }, RECEIVE_QUERY_STATE: { actions: ['updateQueryStateFromQueryServiceState'], }, @@ -239,8 +244,12 @@ export const createPureLogsExplorerControllerStateMachine = ( } : {} ), + resetRows: actions.assign((_context, event) => ({ + rows: [], + })), notifyDataViewUpdate: raise('DATA_VIEW_UPDATED'), updateContextFromDiscoverAppState, + updateContextFromDiscoverDataState, updateDiscoverAppStateFromContext, updateContextFromTimefilter, }, diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/types.ts b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/types.ts index f5a5abd964482..5e7d617a1cd4e 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/types.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/state_machines/logs_explorer_controller/src/types.ts @@ -7,8 +7,13 @@ import { ControlGroupAPI } from '@kbn/controls-plugin/public'; import { QueryState, RefreshInterval, TimeRange } from '@kbn/data-plugin/common'; -import { DiscoverAppState, DiscoverStateContainer } from '@kbn/discover-plugin/public'; +import type { + DiscoverAppState, + DiscoverStateContainer, + DataDocumentsMsg, +} from '@kbn/discover-plugin/public'; import { DoneInvokeEvent } from 'xstate'; +import type { DataTableRecord } from '@kbn/discover-utils/src/types'; import { ControlPanels, DisplayOptions } from '../../../../common'; import type { DatasetEncodingError, DatasetSelection } from '../../../../common/dataset_selection'; @@ -32,9 +37,14 @@ export interface WithDiscoverStateContainer { discoverStateContainer: DiscoverStateContainer; } +export interface WithDataTableRecord { + rows: DataTableRecord[]; +} + export type DefaultLogsExplorerControllerState = WithDatasetSelection & WithQueryState & - WithDisplayOptions; + WithDisplayOptions & + WithDataTableRecord; export type LogsExplorerControllerTypeState = | { @@ -59,6 +69,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -67,6 +78,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -75,6 +87,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -83,6 +96,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -91,6 +105,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -99,6 +114,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -108,6 +124,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; } | { @@ -117,6 +134,7 @@ export type LogsExplorerControllerTypeState = WithControlPanels & WithQueryState & WithDisplayOptions & + WithDataTableRecord & WithDiscoverStateContainer; }; @@ -151,6 +169,10 @@ export type LogsExplorerControllerEvent = type: 'RECEIVE_DISCOVER_APP_STATE'; appState: DiscoverAppState; } + | { + type: 'RECEIVE_DISCOVER_DATA_STATE'; + dataState: DataDocumentsMsg['result']; + } | { type: 'RECEIVE_TIMEFILTER_TIME'; time: TimeRange; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_field_from_flattened_doc.ts b/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_field_from_flattened_doc.ts new file mode 100644 index 0000000000000..7d05d9ab61583 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_field_from_flattened_doc.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 { LogDocument } from '../../common/document'; + +type Field = keyof LogDocument['flattened']; + +export const getFieldFromDoc = <T extends Field>(doc: LogDocument, field: T) => { + const fieldValueArray = doc.flattened[field]; + return fieldValueArray && fieldValueArray.length ? fieldValueArray[0] : undefined; +}; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_stack_trace.ts b/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_stack_trace.ts new file mode 100644 index 0000000000000..58eb44a7744c9 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_explorer/public/utils/get_stack_trace.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogDocument, StackTraceFields } from '../../common/document'; +import * as constants from '../../common/constants'; +import { getFieldFromDoc } from './get_field_from_flattened_doc'; + +export const getStacktraceFields = (doc: LogDocument): StackTraceFields => { + const errorStackTrace = getFieldFromDoc(doc, constants.ERROR_STACK_TRACE); + const errorExceptionStackTrace = getFieldFromDoc(doc, constants.ERROR_EXCEPTION_STACKTRACE); + const errorLogStackTrace = getFieldFromDoc(doc, constants.ERROR_LOG_STACKTRACE); + + return { + [constants.ERROR_STACK_TRACE]: errorStackTrace, + [constants.ERROR_EXCEPTION_STACKTRACE]: errorExceptionStackTrace, + [constants.ERROR_LOG_STACKTRACE]: errorLogStackTrace, + }; +}; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/utils/resource.ts b/x-pack/plugins/observability_solution/logs_explorer/public/utils/resource.ts index 11123d8030481..1b1f3dd078008 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/utils/resource.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/utils/resource.ts @@ -7,13 +7,7 @@ import { LogDocument, ResourceFields } from '../../common/document'; import * as constants from '../../common/constants'; - -type Field = keyof LogDocument['flattened']; - -const getFieldFromDoc = <T extends Field>(doc: LogDocument, field: T) => { - const fieldValueArray = doc.flattened[field]; - return fieldValueArray && fieldValueArray.length ? fieldValueArray[0] : undefined; -}; +import { getFieldFromDoc } from './get_field_from_flattened_doc'; export const getUnformattedResourceFields = (doc: LogDocument): ResourceFields => { const serviceName = getFieldFromDoc(doc, constants.SERVICE_NAME_FIELD); diff --git a/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts index e6291e4d8fc01..fae1ecc59c5fe 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts @@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('render content virtual column properly', async () => { it('should render log level and log message when present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('A sample log')).to.be(true); @@ -86,7 +86,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render log message when present and skip log level when missing', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(1, 4); + const cellElement = await dataGrid.getCellElement(1, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(false); expect(cellValue.includes('A sample log')).to.be(true); @@ -95,7 +95,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render message from error object when top level message not present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(2, 4); + const cellElement = await dataGrid.getCellElement(2, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('error.message')).to.be(true); @@ -105,7 +105,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render message from event.original when top level message and error.message not present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(3, 4); + const cellElement = await dataGrid.getCellElement(3, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('event.original')).to.be(true); @@ -115,7 +115,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the whole JSON when neither message, error.message and event.original are present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(4, 4); + const cellElement = await dataGrid.getCellElement(4, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); @@ -131,7 +131,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('on cell expansion with no message field should open JSON Viewer', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - await dataGrid.clickCellExpandButton(4, 4); + await dataGrid.clickCellExpandButton(4, 3); await testSubjects.existOrFail('dataTableExpandCellActionJsonPopover'); }); }); @@ -139,7 +139,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('on cell expansion with message field should open regular popover', async () => { await navigateToLogsExplorer(); await retry.tryForTime(TEST_TIMEOUT, async () => { - await dataGrid.clickCellExpandButton(3, 4); + await dataGrid.clickCellExpandButton(3, 3); await testSubjects.existOrFail('euiDataGridExpansionPopover'); }); }); @@ -148,7 +148,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('render resource virtual column properly', async () => { it('should render service name and host name when present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 3); + const cellElement = await dataGrid.getCellElement(0, 2); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('synth-service')).to.be(true); expect(cellValue.includes('synth-host')).to.be(true); @@ -162,7 +162,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should render a popover with cell actions when a chip on content column is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -178,7 +178,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where log.level value is info when filter in action is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -198,7 +198,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where log.level value is not info when filter out action is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -216,7 +216,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where service.name value is selected', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 3); + const cellElement = await dataGrid.getCellElement(0, 2); const serviceNameChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_service.name' ); diff --git a/x-pack/test/functional/apps/observability_logs_explorer/custom_control_columns.ts b/x-pack/test/functional/apps/observability_logs_explorer/custom_control_columns.ts new file mode 100644 index 0000000000000..94bb7a4552c77 --- /dev/null +++ b/x-pack/test/functional/apps/observability_logs_explorer/custom_control_columns.ts @@ -0,0 +1,189 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { log, timerange } from '@kbn/apm-synthtrace-client'; +import expect from '@kbn/expect'; +import moment from 'moment'; +import { FtrProviderContext } from './config'; + +const MORE_THAN_1024_CHARS = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); + const PageObjects = getPageObjects(['discover', 'observabilityLogsExplorer']); + const synthtrace = getService('logSynthtraceEsClient'); + const dataGrid = getService('dataGrid'); + const from = '2024-02-06T10:24:14.035Z'; + const to = '2024-02-06T10:25:14.091Z'; + const TEST_TIMEOUT = 10 * 1000; // 10 secs + + const navigateToLogsExplorer = () => + PageObjects.observabilityLogsExplorer.navigateTo({ + pageState: { + time: { + from, + to, + mode: 'absolute', + }, + }, + }); + + describe('When the logs explorer loads', () => { + before(async () => { + await synthtrace.index(generateLogsData({ to })); + await navigateToLogsExplorer(); + }); + + after(async () => { + await synthtrace.clean(); + }); + + describe('should render custom control columns properly', async () => { + it('should render control column with proper header', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + // First control column has no title, so empty string, last control column has title + expect(await dataGrid.getControlColumnHeaderFields()).to.eql(['', 'actions']); + }); + }); + + it('should render the expand icon in the last control column', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(0, 4); + const expandButton = await cellElement.findByTestSubject('docTableExpandToggleColumn'); + expect(expandButton).to.not.be.empty(); + }); + }); + + it('should render the malformed icon in the last control column if malformed doc exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(1, 4); + const malformedButton = await cellElement.findByTestSubject('docTableMalformedDocExist'); + expect(malformedButton).to.not.be.empty(); + }); + }); + + it('should render the disabled malformed icon in the last control column when malformed doc does not exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(0, 4); + const malformedDisableButton = await cellElement.findByTestSubject( + 'docTableMalformedDocDoesNotExist' + ); + expect(malformedDisableButton).to.not.be.empty(); + }); + }); + + it('should render the stacktrace icon in the last control column when stacktrace exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(4, 4); + const stacktraceButton = await cellElement.findByTestSubject('docTableStacktraceExist'); + expect(stacktraceButton).to.not.be.empty(); + }); + }); + + it('should render the stacktrace icon disabled in the last control column when stacktrace does not exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(1, 4); + const stacktraceButton = await cellElement.findByTestSubject( + 'docTableStacktraceDoesNotExist' + ); + expect(stacktraceButton).to.not.be.empty(); + }); + }); + }); + }); +} + +function generateLogsData({ to, count = 1 }: { to: string; count?: number }) { + const logs = timerange(moment(to).subtract(1, 'second'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log + .create() + .message('A sample log') + .logLevel('info') + .timestamp(timestamp) + .defaults({ 'service.name': 'synth-service' }); + }) + ); + + const malformedDocs = timerange( + moment(to).subtract(2, 'second'), + moment(to).subtract(1, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log + .create() + .message('A malformed doc') + .logLevel(MORE_THAN_1024_CHARS) + .timestamp(timestamp) + .defaults({ 'service.name': 'synth-service' }); + }) + ); + + const logsWithErrorMessage = timerange( + moment(to).subtract(3, 'second'), + moment(to).subtract(2, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.stack_trace': 'Error message in error.stack_trace', + 'service.name': 'node-service', + }); + }) + ); + + const logsWithErrorException = timerange( + moment(to).subtract(4, 'second'), + moment(to).subtract(3, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.exception.stacktrace': 'Error message in error.exception.stacktrace', + 'service.name': 'node-service', + }); + }) + ); + + const logsWithErrorInLog = timerange( + moment(to).subtract(5, 'second'), + moment(to).subtract(4, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.log.stacktrace': 'Error message in error.log.stacktrace', + 'service.name': 'node-service', + }); + }) + ); + + return [logs, malformedDocs, logsWithErrorMessage, logsWithErrorException, logsWithErrorInLog]; +} diff --git a/x-pack/test/functional/apps/observability_logs_explorer/flyout.ts b/x-pack/test/functional/apps/observability_logs_explorer/flyout.ts index 8e478755794a6..c3ef409546b31 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/flyout.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/flyout.ts @@ -66,30 +66,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should mount the flyout customization content', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutDetail'); }); it('should display a timestamp badge', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogTimestamp'); }); it('should display a log level badge when available', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogLevel'); await dataGrid.closeFlyout(); - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutLogLevel'); }); it('should display a message code block when available', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogMessage'); await dataGrid.closeFlyout(); - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutLogMessage'); }); }); diff --git a/x-pack/test/functional/apps/observability_logs_explorer/flyout_highlights.ts b/x-pack/test/functional/apps/observability_logs_explorer/flyout_highlights.ts index 678c76bde9f2f..238d456b5ec54 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/flyout_highlights.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/flyout_highlights.ts @@ -87,7 +87,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the service container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await testSubjects.existOrFail('logsExplorerFlyoutService'); await testSubjects.existOrFail('logsExplorerFlyoutTrace'); @@ -98,7 +98,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the service container even when 1 field is missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await testSubjects.missingOrFail('logsExplorerFlyoutService'); await testSubjects.existOrFail('logsExplorerFlyoutTrace'); @@ -109,7 +109,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should not load the service container if all fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 2 }); + await dataGrid.clickRowToggle({ rowIndex: 2, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await dataGrid.closeFlyout(); }); @@ -155,7 +155,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the cloud container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.existOrFail('logsExplorerFlyoutCloudProvider'); await testSubjects.existOrFail('logsExplorerFlyoutCloudRegion'); @@ -166,7 +166,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the cloud container even when some fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudProvider'); @@ -179,7 +179,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should not load the cloud container if all fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 2 }); + await dataGrid.clickRowToggle({ rowIndex: 2, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudProvider'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudRegion'); @@ -225,7 +225,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the other container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionOther'); await testSubjects.existOrFail('logsExplorerFlyoutLogPathFile'); await testSubjects.existOrFail('logsExplorerFlyoutNamespace'); @@ -235,7 +235,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the other container even when some fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionOther'); await testSubjects.missingOrFail('logsExplorerFlyoutLogPathFile'); diff --git a/x-pack/test/functional/apps/observability_logs_explorer/index.ts b/x-pack/test/functional/apps/observability_logs_explorer/index.ts index e8114a8d14bfd..c56a898b6d0c0 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/index.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/index.ts @@ -17,5 +17,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./flyout')); loadTestFile(require.resolve('./header_menu')); loadTestFile(require.resolve('./flyout_highlights.ts')); + loadTestFile(require.resolve('./custom_control_columns.ts')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts index a719b1ae854ce..cdc00483b9365 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts @@ -79,7 +79,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('render content virtual column properly', async () => { it('should render log level and log message when present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('A sample log')).to.be(true); @@ -88,7 +88,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render log message when present and skip log level when missing', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(1, 4); + const cellElement = await dataGrid.getCellElement(1, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(false); expect(cellValue.includes('A sample log')).to.be(true); @@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render message from error object when top level message not present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(2, 4); + const cellElement = await dataGrid.getCellElement(2, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('error.message')).to.be(true); @@ -107,7 +107,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render message from event.original when top level message and error.message not present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(3, 4); + const cellElement = await dataGrid.getCellElement(3, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); expect(cellValue.includes('event.original')).to.be(true); @@ -117,7 +117,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the whole JSON when neither message, error.message and event.original are present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(4, 4); + const cellElement = await dataGrid.getCellElement(4, 3); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('info')).to.be(true); @@ -133,7 +133,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('on cell expansion with no message field should open JSON Viewer', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - await dataGrid.clickCellExpandButton(4, 4); + await dataGrid.clickCellExpandButton(4, 3); await testSubjects.existOrFail('dataTableExpandCellActionJsonPopover'); }); }); @@ -141,7 +141,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('on cell expansion with message field should open regular popover', async () => { await navigateToLogsExplorer(); await retry.tryForTime(TEST_TIMEOUT, async () => { - await dataGrid.clickCellExpandButton(3, 4); + await dataGrid.clickCellExpandButton(3, 3); await testSubjects.existOrFail('euiDataGridExpansionPopover'); }); }); @@ -150,7 +150,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('render resource virtual column properly', async () => { it('should render service name and host name when present', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 3); + const cellElement = await dataGrid.getCellElement(0, 2); const cellValue = await cellElement.getVisibleText(); expect(cellValue.includes('synth-service')).to.be(true); expect(cellValue.includes('synth-host')).to.be(true); @@ -164,7 +164,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should render a popover with cell actions when a chip on content column is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -180,7 +180,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where log.level value is info when filter in action is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -200,7 +200,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where log.level value is not info when filter out action is clicked', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 4); + const cellElement = await dataGrid.getCellElement(0, 3); const logLevelChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_log.level' ); @@ -218,7 +218,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render the table filtered where service.name value is selected', async () => { await retry.tryForTime(TEST_TIMEOUT, async () => { - const cellElement = await dataGrid.getCellElement(0, 3); + const cellElement = await dataGrid.getCellElement(0, 2); const serviceNameChip = await cellElement.findByTestSubject( 'dataTablePopoverChip_service.name' ); diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/custom_control_columns.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/custom_control_columns.ts new file mode 100644 index 0000000000000..232a5bd20c001 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/custom_control_columns.ts @@ -0,0 +1,191 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { log, timerange } from '@kbn/apm-synthtrace-client'; +import expect from '@kbn/expect'; +import moment from 'moment'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +const MORE_THAN_1024_CHARS = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); + const PageObjects = getPageObjects(['discover', 'observabilityLogsExplorer', 'svlCommonPage']); + const synthtrace = getService('svlLogsSynthtraceClient'); + const dataGrid = getService('dataGrid'); + const from = '2024-02-06T10:24:14.035Z'; + const to = '2024-02-06T10:25:14.091Z'; + const TEST_TIMEOUT = 10 * 1000; // 10 secs + + const navigateToLogsExplorer = () => + PageObjects.observabilityLogsExplorer.navigateTo({ + pageState: { + time: { + from, + to, + mode: 'absolute', + }, + }, + }); + + describe('When the logs explorer loads', () => { + before(async () => { + await synthtrace.index(generateLogsData({ to })); + await PageObjects.svlCommonPage.login(); + await navigateToLogsExplorer(); + }); + + after(async () => { + await synthtrace.clean(); + await PageObjects.svlCommonPage.forceLogout(); + }); + + describe('should render custom control columns properly', async () => { + it('should render control column with proper header', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + // First control column has no title, so empty string, last control column has title + expect(await dataGrid.getControlColumnHeaderFields()).to.eql(['', 'actions']); + }); + }); + + it('should render the expand icon in the last control column', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(0, 4); + const expandButton = await cellElement.findByTestSubject('docTableExpandToggleColumn'); + expect(expandButton).to.not.be.empty(); + }); + }); + + it('should render the malformed icon in the last control column if malformed doc exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(1, 4); + const malformedButton = await cellElement.findByTestSubject('docTableMalformedDocExist'); + expect(malformedButton).to.not.be.empty(); + }); + }); + + it('should render the disabled malformed icon in the last control column when malformed doc does not exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(0, 4); + const malformedDisableButton = await cellElement.findByTestSubject( + 'docTableMalformedDocDoesNotExist' + ); + expect(malformedDisableButton).to.not.be.empty(); + }); + }); + + it('should render the stacktrace icon in the last control column when stacktrace exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(4, 4); + const stacktraceButton = await cellElement.findByTestSubject('docTableStacktraceExist'); + expect(stacktraceButton).to.not.be.empty(); + }); + }); + + it('should render the stacktrace icon disabled in the last control column when stacktrace does not exists', async () => { + await retry.tryForTime(TEST_TIMEOUT, async () => { + const cellElement = await dataGrid.getCellElement(1, 4); + const stacktraceButton = await cellElement.findByTestSubject( + 'docTableStacktraceDoesNotExist' + ); + expect(stacktraceButton).to.not.be.empty(); + }); + }); + }); + }); +} + +function generateLogsData({ to, count = 1 }: { to: string; count?: number }) { + const logs = timerange(moment(to).subtract(1, 'second'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log + .create() + .message('A sample log') + .logLevel('info') + .timestamp(timestamp) + .defaults({ 'service.name': 'synth-service' }); + }) + ); + + const malformedDocs = timerange( + moment(to).subtract(2, 'second'), + moment(to).subtract(1, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log + .create() + .message('A malformed doc') + .logLevel(MORE_THAN_1024_CHARS) + .timestamp(timestamp) + .defaults({ 'service.name': 'synth-service' }); + }) + ); + + const logsWithErrorMessage = timerange( + moment(to).subtract(3, 'second'), + moment(to).subtract(2, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.stack_trace': 'Error message in error.stack_trace', + 'service.name': 'node-service', + }); + }) + ); + + const logsWithErrorException = timerange( + moment(to).subtract(4, 'second'), + moment(to).subtract(3, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.exception.stacktrace': 'Error message in error.exception.stacktrace', + 'service.name': 'node-service', + }); + }) + ); + + const logsWithErrorInLog = timerange( + moment(to).subtract(5, 'second'), + moment(to).subtract(4, 'second') + ) + .interval('1m') + .rate(1) + .generator((timestamp) => + Array(count) + .fill(0) + .map(() => { + return log.create().logLevel('info').timestamp(timestamp).defaults({ + 'error.log.stacktrace': 'Error message in error.log.stacktrace', + 'service.name': 'node-service', + }); + }) + ); + + return [logs, malformedDocs, logsWithErrorMessage, logsWithErrorException, logsWithErrorInLog]; +} diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout.ts index f8087eff743c3..e952294c2cda1 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout.ts @@ -68,30 +68,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should mount the flyout customization content', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutDetail'); }); it('should display a timestamp badge', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogTimestamp'); }); it('should display a log level badge when available', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogLevel'); await dataGrid.closeFlyout(); - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutLogLevel'); }); it('should display a message code block when available', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutLogMessage'); await dataGrid.closeFlyout(); - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutLogMessage'); }); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout_highlights.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout_highlights.ts index 9fa836815a554..b143d59e96cad 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout_highlights.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/flyout_highlights.ts @@ -89,7 +89,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the service container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await testSubjects.existOrFail('logsExplorerFlyoutService'); await testSubjects.existOrFail('logsExplorerFlyoutTrace'); @@ -100,7 +100,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the service container even when 1 field is missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await testSubjects.missingOrFail('logsExplorerFlyoutService'); await testSubjects.existOrFail('logsExplorerFlyoutTrace'); @@ -111,7 +111,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should not load the service container if all fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 2 }); + await dataGrid.clickRowToggle({ rowIndex: 2, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutHighlightSectionServiceInfra'); await dataGrid.closeFlyout(); }); @@ -159,7 +159,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the cloud container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.existOrFail('logsExplorerFlyoutCloudProvider'); await testSubjects.existOrFail('logsExplorerFlyoutCloudRegion'); @@ -170,7 +170,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the cloud container even when some fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudProvider'); @@ -183,7 +183,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should not load the cloud container if all fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 2 }); + await dataGrid.clickRowToggle({ rowIndex: 2, columnIndex: 4 }); await testSubjects.missingOrFail('logsExplorerFlyoutHighlightSectionCloud'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudProvider'); await testSubjects.missingOrFail('logsExplorerFlyoutCloudRegion'); @@ -231,7 +231,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the other container with all fields', async () => { - await dataGrid.clickRowToggle(); + await dataGrid.clickRowToggle({ columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionOther'); await testSubjects.existOrFail('logsExplorerFlyoutLogPathFile'); await testSubjects.existOrFail('logsExplorerFlyoutNamespace'); @@ -241,7 +241,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should load the other container even when some fields are missing', async () => { - await dataGrid.clickRowToggle({ rowIndex: 1 }); + await dataGrid.clickRowToggle({ rowIndex: 1, columnIndex: 4 }); await testSubjects.existOrFail('logsExplorerFlyoutHighlightSectionOther'); await testSubjects.missingOrFail('logsExplorerFlyoutLogPathFile'); diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/index.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/index.ts index c248e31df92e3..98cde3a1d8267 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/index.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/index.ts @@ -17,5 +17,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./flyout')); loadTestFile(require.resolve('./header_menu')); loadTestFile(require.resolve('./flyout_highlights.ts')); + loadTestFile(require.resolve('./custom_control_columns.ts')); }); } From c3c1b667c1de1aa36955528098ce0be15e7272b1 Mon Sep 17 00:00:00 2001 From: Juan Pablo Djeredjian <jpdjeredjian@gmail.com> Date: Fri, 9 Feb 2024 17:47:13 +0100 Subject: [PATCH 085/104] [Security Solution] Disable installation button for users with Security:Read privileges (#176598) Fixes: https://github.com/elastic/kibana/issues/161543 ## Summary Original bug issue reported an infinite loading state in the **Add Elastic rules** page when user doesn't have write privileges, i.e. has `Security: Read`. However, that seems to have been fixed already, as the list of rules to install is shown, but no individual "Install button" for each row is showed. **This is expected behaviour**. ![image](https://github.com/elastic/kibana/assets/5354282/f57adc2b-9073-4019-a15e-8c05e48f1b9d) However, when displaying the Rule Details flyout, the button for Installation in the flyout is still enabled due to missing checks. This PR fixes that and now displays a disabled button for users with no privileges. ![image](https://github.com/elastic/kibana/assets/5354282/70a6b209-59bb-4199-99f9-f2222fb78d68) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../add_prebuilt_rules_table_context.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx index 54f33e81e1bba..f13c8130bf740 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx @@ -8,6 +8,7 @@ import type { Dispatch, SetStateAction } from 'react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { EuiButton } from '@elastic/eui'; +import { useUserData } from '../../../../../detections/components/user_info'; import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; @@ -99,6 +100,8 @@ export const AddPrebuiltRulesTableContextProvider = ({ const [loadingRules, setLoadingRules] = useState<RuleSignatureId[]>([]); const [selectedRules, setSelectedRules] = useState<RuleResponse[]>([]); + const [{ loading: userInfoLoading, canUserCRUD }] = useUserData(); + const [filterOptions, setFilterOptions] = useState<AddPrebuiltRulesTableFilterOptions>({ filter: '', tags: [], @@ -135,11 +138,13 @@ export const AddPrebuiltRulesTableContextProvider = ({ const filteredRules = useFilterPrebuiltRulesToInstall({ filterOptions, rules }); const { openRulePreview, closeRulePreview, previewedRule } = useRuleDetailsFlyout(filteredRules); - const canPreviewedRuleBeInstalled = Boolean( - (previewedRule?.rule_id && loadingRules.includes(previewedRule.rule_id)) || - isRefetching || - isUpgradingSecurityPackages - ); + + const isPreviewRuleLoading = + previewedRule?.rule_id && loadingRules.includes(previewedRule.rule_id); + const canPreviewedRuleBeInstalled = + !userInfoLoading && + canUserCRUD && + !(isPreviewRuleLoading || isRefetching || isUpgradingSecurityPackages); const installOneRule = useCallback( async (ruleId: RuleSignatureId) => { @@ -237,7 +242,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ closeFlyout={closeRulePreview} ruleActions={ <EuiButton - disabled={canPreviewedRuleBeInstalled} + disabled={!canPreviewedRuleBeInstalled} onClick={() => { installOneRule(previewedRule.rule_id ?? ''); closeRulePreview(); From 888562ce20cf04647b3e11eb73966a0d779fb287 Mon Sep 17 00:00:00 2001 From: Alex Szabo <alex.szabo@elastic.co> Date: Fri, 9 Feb 2024 18:00:32 +0100 Subject: [PATCH 086/104] [Ops] Remove -e from node.conf (in Kibana docker images) (#176588) ## Summary There seems to be an issue with the kibana docker image, and the error is the following: ``` /usr/share/kibana/bin/../node/bin/node: -e is not allowed in NODE_OPTIONS ``` See thread for details: https://elastic.slack.com/archives/C0574PUV998/p1707483034202249 ### Changes - chore(FIPS): remove -e flags from echo - they're emitted to the output, the newline seems to work without the flags (source: https://stackoverflow.com/questions/45532467/run-echo-e-deb-http-prepares-a-wrong-contents-of-the-target-file) --------- Co-authored-by: Jonathan Budzenski <jon@elastic.co> --- .../docker_generator/templates/base/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index b02efe3f5b5b3..d0bf01692ae8f 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -137,8 +137,8 @@ RUN set -e ; \ chown -R 1000:0 /usr/share/kibana/openssl-3.0.8 # Enable FIPS for Kibana only. In the future we can override OS wide with ENV OPENSSL_CONF -RUN echo -e '\n--enable-fips' >> config/node.options -RUN echo '--openssl-config=/usr/share/kibana/openssl-3.0.8/nodejs.cnf' >> config/node.options +RUN /usr/bin/echo -e '\n--enable-fips' >> config/node.options +RUN /usr/bin/echo '--openssl-config=/usr/share/kibana/openssl-3.0.8/nodejs.cnf' >> config/node.options COPY --chown=1000:0 openssl/nodejs.cnf /usr/share/kibana/openssl-3.0.8/nodejs.cnf ENV OPENSSL_MODULES=/usr/local/lib64/ossl-modules @@ -158,8 +158,8 @@ COPY --chown=1000:0 config/serverless.es.yml /usr/share/kibana/config/serverless COPY --chown=1000:0 config/serverless.oblt.yml /usr/share/kibana/config/serverless.oblt.yml COPY --chown=1000:0 config/serverless.security.yml /usr/share/kibana/config/serverless.security.yml # Supportability enhancement: enable capturing heap snapshots. See https://nodejs.org/api/cli.html#--heapsnapshot-signalsignal -RUN echo -e '\n--heapsnapshot-signal=SIGUSR2' >> config/node.options -RUN echo '--diagnostic-dir=./data' >> config/node.options +RUN /usr/bin/echo -e '\n--heapsnapshot-signal=SIGUSR2' >> config/node.options +RUN /usr/bin/echo '--diagnostic-dir=./data' >> config/node.options {{/serverless}} {{^opensslLegacyProvider}} RUN sed 's/\(--openssl-legacy-provider\)/#\1/' -i config/node.options @@ -221,7 +221,7 @@ ENTRYPOINT ["/bin/tini", "--"] CMD ["/app/kibana.sh"] # Generate a stub command that will be overwritten at runtime RUN mkdir /app && \ - echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ + /usr/bin/echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ chmod 0555 /app/kibana.sh {{/cloud}} From 2b49a407f7f3957803905c23b1f7ef2e1faf34a4 Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko <dzmitry.lemechko@elastic.co> Date: Fri, 9 Feb 2024 19:23:24 +0200 Subject: [PATCH 087/104] [ftr] update common serverless tests to use saml auth (#176221) ## Summary This PR updates FTR functional tests shared b/w projects to use SAML authentication instead of login with default user and kibana `/login` route. Few notes for reviewers: - admin role was added to each project roles.yml file and its definition matches cloud one. - please check your tests if selected role is as expected: the goal is to run test with the role that has minimal required permissions, but some tests were failing with lower access role: - `viewer` - read only - `editor` / `developer` for write actions (e.g. save search) - `admin` if full access required - svl_common_page.ts was updated: - `cleanBrowserState()` is added to reset state b/w test suites by deleting all cookies, clearing session & local storages. - `loginWithRole(role: string)` starts with `cleanBrowserState()` call, then sets the new cookie based on provided role and validates the role is applied correctly. On its finish browser is at Kibana home screen. - `loginAsAdmin()` and `loginWithPrivilegedRole()` to login as admin and editor/developer roles. - `forceLogout()` is only required in tests that use basic authentication. It starts with `cleanBrowserState()` call and then loads `/logout` route (we can't load base url because mock-id-plugin will trigger redirects). On its finish browser is at Cloud login screen. For @elastic/kibana-operations : This change affects the login in the functional serverless tests (18 config files at the moment) and while it seems to be stable enough, it might be the reason of sudden flakiness/failures on CI. [Flaky-test-runner 60x](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5107) to verify login via cookie is stable --------- Co-authored-by: Robert Oskamp <traeluki@gmail.com> --- .../project_roles/es/roles.yml | 14 ++- .../project_roles/oblt/roles.yml | 14 ++- .../project_roles/security/roles.yml | 14 ++- x-pack/test_serverless/README.md | 23 ++++ .../page_objects/svl_common_page.ts | 111 ++++++++++++++---- .../test_suites/common/console/console.ts | 11 +- .../common/context/_context_navigation.ts | 3 + .../common/context/_discover_navigation.ts | 2 + .../test_suites/common/context/_filters.ts | 4 +- .../test_suites/common/context/_size.ts | 3 +- .../test_suites/common/context/index.ts | 12 +- .../common/dev_tools/search_profiler.ts | 6 +- .../embeddable/_saved_search_embeddable.ts | 13 +- .../common/discover/embeddable/index.ts | 16 +-- .../common/discover/group1/_discover.ts | 2 + .../discover/group1/_discover_histogram.ts | 3 +- .../common/discover/group1/_url_state.ts | 4 +- .../common/discover/group1/index.ts | 5 +- .../discover/group2/_adhoc_data_views.ts | 5 +- .../group2/_data_grid_doc_navigation.ts | 3 +- .../discover/group2/_data_grid_doc_table.ts | 2 + .../common/discover/group2/index.ts | 5 +- .../common/discover/group3/_request_counts.ts | 4 +- .../common/discover/group3/_sidebar.ts | 3 +- .../discover/group3/_unsaved_changes_badge.ts | 4 +- .../common/discover/group3/index.ts | 5 +- .../common/discover/x_pack/index.ts | 9 +- .../common/discover/x_pack/reporting.ts | 10 +- .../common/discover/x_pack/visualize_field.ts | 16 ++- .../discover_ml_uptime/discover/index.ts | 9 +- .../discover/search_source_alert.ts | 2 + .../data_view_field_editor_example/index.ts | 3 +- .../customizations.ts | 3 +- .../common/examples/field_formats/index.ts | 3 +- .../common/examples/partial_results/index.ts | 3 +- .../common/examples/search/warnings.ts | 3 +- .../partial_results_example.ts | 6 +- .../search_examples/search_example.ts | 3 +- .../existing_fields.ts | 3 +- .../field_stats.ts | 3 +- .../common/grok_debugger/grok_debugger.ts | 3 +- .../test_suites/common/home_page/home_page.ts | 6 +- .../common/home_page/sample_data.ts | 3 +- .../common/management/advanced_settings.ts | 3 +- .../management/data_views/_runtime_fields.ts | 2 - .../data_views/_runtime_fields_composite.ts | 2 - .../common/management/data_views/index.ts | 3 +- .../management/data_views/serverless.ts | 3 - .../index_management/component_templates.ts | 7 +- .../index_management/create_enrich_policy.ts | 4 +- .../index_management/data_streams.ts | 7 +- .../index_management/enrich_policies.ts | 2 +- .../index_management/index_templates.ts | 4 +- .../management/index_management/indices.ts | 3 +- .../common/management/ingest_pipelines.ts | 5 +- .../common/management/landing_page.ts | 7 +- .../transforms/search_bar_features.ts | 6 +- .../management/transforms/transform_list.ts | 2 +- .../common/painless_lab/painless_lab.ts | 6 +- .../common/platform_security/api_keys.ts | 3 +- .../navigation/avatar_menu.ts | 6 +- .../user_profiles/user_profiles.ts | 5 + .../common/reporting/management.ts | 2 +- .../saved_objects_management/bulk_get.ts | 3 +- .../export_transform.ts | 9 +- .../common/saved_objects_management/find.ts | 3 +- .../hidden_from_http_apis.ts | 3 +- .../saved_objects_management/hidden_types.ts | 4 +- .../import_warnings.ts | 2 +- .../saved_objects_management/scroll_count.ts | 2 +- .../visible_in_management.ts | 3 +- .../common/visualizations/group1/index.ts | 2 - .../visualizations/group1/smokescreen.ts | 6 +- .../common/visualizations/group1/tsdb.ts | 9 +- .../visualizations/group1/vega_chart.ts | 2 + .../common/visualizations/group2/index.ts | 12 +- .../group2/open_in_lens/agg_based/gauge.ts | 8 +- .../group2/open_in_lens/agg_based/goal.ts | 8 +- .../group2/open_in_lens/agg_based/heatmap.ts | 8 +- .../group2/open_in_lens/agg_based/metric.ts | 8 +- .../group2/open_in_lens/agg_based/pie.ts | 8 +- .../group2/open_in_lens/agg_based/table.ts | 8 +- .../group2/open_in_lens/agg_based/xy.ts | 8 +- .../common/visualizations/group3/index.ts | 6 +- .../security/common_configs/config.group6.ts | 4 +- .../shared/services/svl_user_manager.ts | 46 +++++++- 86 files changed, 382 insertions(+), 251 deletions(-) diff --git a/packages/kbn-es/src/serverless_resources/project_roles/es/roles.yml b/packages/kbn-es/src/serverless_resources/project_roles/es/roles.yml index 85046bce4dc47..404806c4ac2f6 100644 --- a/packages/kbn-es/src/serverless_resources/project_roles/es/roles.yml +++ b/packages/kbn-es/src/serverless_resources/project_roles/es/roles.yml @@ -1,5 +1,5 @@ # ----- -# Source: https://github.com/elastic/project-controller/blob/main/internal/project/esproject/config/roles.yml +# Source: project-controller/blob/main/internal/project/esproject/config/roles.yml # ----- viewer: cluster: ['manage_own_api_key', 'read_pipeline'] @@ -29,6 +29,18 @@ developer: resources: - '*' +# admin role defined in elasticsearch controller +admin: + cluster: ['all'] + indices: + - names: ['*'] + privileges: ['all'] + allow_restricted_indices: false + applications: + - application: '*' + privileges: ['*'] + resources: ['*'] + # temporarily added for testing purpose system_indices_superuser: cluster: ['all'] diff --git a/packages/kbn-es/src/serverless_resources/project_roles/oblt/roles.yml b/packages/kbn-es/src/serverless_resources/project_roles/oblt/roles.yml index bd40fcf282b2a..e0091f5b7d055 100644 --- a/packages/kbn-es/src/serverless_resources/project_roles/oblt/roles.yml +++ b/packages/kbn-es/src/serverless_resources/project_roles/oblt/roles.yml @@ -1,5 +1,5 @@ # ----- -# Source: https://github.com/elastic/project-controller/blob/main/internal/project/security/config/roles.yml +# Source: project-controller/blob/main/internal/project/security/config/roles.yml # ----- viewer: cluster: [] @@ -77,6 +77,18 @@ editor: - '*' run_as: [] +# admin role defined in elasticsearch controller +admin: + cluster: ['all'] + indices: + - names: ['*'] + privileges: ['all'] + allow_restricted_indices: false + applications: + - application: '*' + privileges: ['*'] + resources: ['*'] + # temporarily added for testing purpose system_indices_superuser: cluster: ['all'] diff --git a/packages/kbn-es/src/serverless_resources/project_roles/security/roles.yml b/packages/kbn-es/src/serverless_resources/project_roles/security/roles.yml index 6fbdd4535bb53..def2ff2cdeb55 100644 --- a/packages/kbn-es/src/serverless_resources/project_roles/security/roles.yml +++ b/packages/kbn-es/src/serverless_resources/project_roles/security/roles.yml @@ -1,5 +1,5 @@ # ----- -# Source: https://github.com/elastic/project-controller/blob/main/internal/project/security/config/roles.yml +# Source: project-controller/blob/main/internal/project/security/config/roles.yml # ----- # modeled after the t1_analyst minus osquery run saved queries privilege viewer: @@ -724,6 +724,18 @@ endpoint_policy_manager: - feature_visualize.all resources: '*' +# admin role defined in elasticsearch controller +admin: + cluster: ['all'] + indices: + - names: ['*'] + privileges: ['all'] + allow_restricted_indices: false + applications: + - application: '*' + privileges: ['*'] + resources: ['*'] + # temporarily added for testing purpose system_indices_superuser: cluster: ['all'] diff --git a/x-pack/test_serverless/README.md b/x-pack/test_serverless/README.md index f90f89a8b3b46..289366dbfc016 100644 --- a/x-pack/test_serverless/README.md +++ b/x-pack/test_serverless/README.md @@ -103,6 +103,29 @@ tests that should run in a serverless environment have to be added to the Tests in this area should be clearly designed for the serverless environment, particularly when it comes to timing for API requests and UI interaction. +### Roles-based testing + +Each serverless project has its own set of SAML roles with [specfic permissions defined in roles.yml](https://github.com/elastic/kibana/blob/main/packages/kbn-es/src/serverless_resources/project_roles) +and in oder to properly test Kibana functionality, UI tests design requires to login with +a project-supported SAML role. + +Some recommendations: +- in each test file top level `describe` suite should start with `loginWithRole` in `before` hook +- use the minimal required role to access tested functionality +- when feature logic depends on both project type & role, make sure to add separate tests +- avoid using basic authentication, unless it is the actual test case +- no need to log out, you can change role by calling `loginWithRole` again. + +``` +describe("my test suite", async function() { + before(async () => { + await PageObjects.svlCommonPage.loginWithRole('viewer'); + await esArchiver.load(...); + await PageObjects.dashboard.navigateToApp(); + }); +}); +``` + ### Testing with feature flags **tl;dr:** Tests specific to functionality behind a feature flag need special diff --git a/x-pack/test_serverless/functional/page_objects/svl_common_page.ts b/x-pack/test_serverless/functional/page_objects/svl_common_page.ts index 681f024b8f837..d8ba679128410 100644 --- a/x-pack/test_serverless/functional/page_objects/svl_common_page.ts +++ b/x-pack/test_serverless/functional/page_objects/svl_common_page.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const find = getService('find'); const config = getService('config'); const pageObjects = getPageObjects(['security', 'common']); const retry = getService('retry'); @@ -24,28 +25,56 @@ export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProvide setTimeout(resolve, ms); }); + /** + * Delete browser cookies, clear session and local storages + */ + const cleanBrowserState = async () => { + // we need to load kibana host to delete/add cookie + const noAuthRequiredUrl = deployment.getHostPort() + '/bootstrap-anonymous.js'; + log.debug(`browser: navigate to /bootstrap-anonymous.js`); + await browser.get(noAuthRequiredUrl); + // previous test might left unsaved changes and alert will show up on url change + const alert = await browser.getAlert(); + if (alert) { + log.debug(`browser: closing alert`); + await alert.accept(); + } + log.debug(`browser: wait for resource page to be loaded`); + await find.byCssSelector('body > pre', 5000); + log.debug(`browser: delete all the cookies`); + await retry.waitForWithTimeout('Browser cookies are deleted', 10000, async () => { + await browser.deleteAllCookies(); + await pageObjects.common.sleep(1000); + const cookies = await browser.getCookies(); + return cookies.length === 0; + }); + log.debug(`browser: clearing session & local storages`); + await browser.clearSessionStorage(); + await browser.clearLocalStorage(); + await pageObjects.common.sleep(700); + }; + return { async loginWithRole(role: string) { + log.debug(`Fetch the cookie for '${role}' role`); + const sidCookie = await svlUserManager.getSessionCookieForRole(role); await retry.waitForWithTimeout( `Logging in by setting browser cookie for '${role}' role`, 30_000, async () => { - log.debug(`Delete all the cookies in the current browser context`); - await browser.deleteAllCookies(); - log.debug(`Setting the cookie for '${role}' role`); - const sidCookie = await svlUserManager.getSessionCookieForRole(role); - // Loading bootstrap.js in order to be on the domain that the cookie will be set for. - await browser.get(deployment.getHostPort() + '/bootstrap.js'); - await browser.setCookie('sid', sidCookie); + await cleanBrowserState(); + log.debug(`browser: set the new cookie`); + await retry.waitForWithTimeout('New cookie is added', 10000, async () => { + await browser.setCookie('sid', sidCookie); + await pageObjects.common.sleep(1000); + const cookies = await browser.getCookies(); + return cookies.length === 1; + }); // Cookie should be already set in the browsing context, navigating to the Home page + log.debug(`browser: refresh the page`); + await browser.refresh(); + log.debug(`browser: load base url and validate the cookie`); await browser.get(deployment.getHostPort()); - // Verifying that we are logged in - if (await testSubjects.exists('userMenuButton', { timeout: 10_000 })) { - log.debug('userMenuButton found, login passed'); - } else { - throw new Error(`Failed to login with cookie for '${role}' role`); - } - // Validating that the new cookie in the browser is set for the correct user const browserCookies = await browser.getCookies(); if (browserCookies.length === 0) { @@ -60,16 +89,31 @@ export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProvide // email returned from API call must match the email for the specified role if (body.email === userData.email) { log.debug(`The new cookie is properly set for '${role}' role`); - return true; } else { + log.debug(`API response body: ${JSON.stringify(body)}`); throw new Error( `Cookie is not set properly, expected email is '${userData.email}', but found '${body.email}'` ); } + // Verifying that we are logged in + if (await testSubjects.exists('userMenuButton', { timeout: 10_000 })) { + log.debug('userMenuButton found, login passed'); + return true; + } else { + throw new Error(`Failed to login with cookie for '${role}' role`); + } } ); }, + async loginAsAdmin() { + await this.loginWithRole('admin'); + }, + + async loginWithPrivilegedRole() { + await this.loginWithRole(svlUserManager.DEFAULT_ROLE); + }, + async navigateToLoginForm() { const url = deployment.getHostPort() + '/login'; await browser.get(url); @@ -79,8 +123,38 @@ export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProvide }); }, + async forceLogout() { + log.debug('SvlCommonPage.forceLogout'); + if (await find.existsByDisplayedByCssSelector('.login-form', 100)) { + log.debug('Already on the login page, not forcing anything'); + return; + } + + await cleanBrowserState(); + + log.debug(`Navigating to ${deployment.getHostPort()}/logout to force the logout`); + await browser.get(deployment.getHostPort() + '/logout'); + + // After logging out, the user can be redirected to various locations depending on the context. By default, we + // expect the user to be redirected to the login page. However, if the login page is not available for some reason, + // we should simply wait until the user is redirected *elsewhere*. + // Timeout has been doubled here in attempt to quiet the flakiness + await retry.waitForWithTimeout('URL redirects to finish', 40000, async () => { + const urlBefore = await browser.getCurrentUrl(); + delay(1000); + const urlAfter = await browser.getCurrentUrl(); + log.debug(`Expecting before URL '${urlBefore}' to equal after URL '${urlAfter}'`); + return urlAfter === urlBefore; + }); + + const currentUrl = await browser.getCurrentUrl(); + + // Logout might trigger multiple redirects, but in the end we expect the Cloud login page + return currentUrl.includes('/login') || currentUrl.includes('/projects'); + }, + async login() { - await pageObjects.security.forceLogout({ waitForLoginPage: false }); + await this.forceLogout(); // adding sleep to settle down logout await pageObjects.common.sleep(2500); @@ -135,11 +209,6 @@ export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProvide log.debug('Logged in successfully'); }, - async forceLogout() { - await pageObjects.security.forceLogout({ waitForLoginPage: false }); - log.debug('Logged out successfully'); - }, - async assertProjectHeaderExists() { await testSubjects.existOrFail('kibanaProjectHeader'); }, diff --git a/x-pack/test_serverless/functional/test_suites/common/console/console.ts b/x-pack/test_serverless/functional/test_suites/common/console/console.ts index d754abdf340bb..8cfa93e8e8572 100644 --- a/x-pack/test_serverless/functional/test_suites/common/console/console.ts +++ b/x-pack/test_serverless/functional/test_suites/common/console/console.ts @@ -26,9 +26,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['svlCommonPage', 'common', 'console', 'header']); describe('console app', function describeIndexTests() { - this.tags('includeFirefox'); before(async () => { - await PageObjects.svlCommonPage.login(); + // TODO: https://github.com/elastic/kibana/issues/176582 + // this test scenario requires roles definition check: + // Search & Oblt projects 'viewer' role has access to Console, but for + // Security project only 'admin' role has access + await PageObjects.svlCommonPage.loginWithRole('admin'); log.debug('navigateTo console'); await PageObjects.common.navigateToApp('dev_tools', { hash: '/console' }); }); @@ -37,10 +40,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.console.closeHelpIfExists(); }); - after(async () => { - await PageObjects.svlCommonPage.forceLogout(); - }); - it('should show the default request', async () => { await retry.try(async () => { const actualRequest = await PageObjects.console.getRequest(); diff --git a/x-pack/test_serverless/functional/test_suites/common/context/_context_navigation.ts b/x-pack/test_serverless/functional/test_suites/common/context/_context_navigation.ts index f23ebd55f1072..8da97f7e39f4b 100644 --- a/x-pack/test_serverless/functional/test_suites/common/context/_context_navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/common/context/_context_navigation.ts @@ -22,6 +22,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataGrid = getService('dataGrid'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'header', 'context', 'discover', @@ -47,6 +48,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.update({ defaultIndex: 'logstash-*', }); + // TODO: Serverless tests require login first + await PageObjects.svlCommonPage.loginWithRole('viewer'); await PageObjects.common.navigateToApp('discover'); await PageObjects.header.waitUntilLoadingHasFinished(); for (const [columnName, value] of TEST_FILTER_COLUMN_NAMES) { diff --git a/x-pack/test_serverless/functional/test_suites/common/context/_discover_navigation.ts b/x-pack/test_serverless/functional/test_suites/common/context/_discover_navigation.ts index 296a8245f9d1d..d53759ddc4e29 100644 --- a/x-pack/test_serverless/functional/test_suites/common/context/_discover_navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/common/context/_discover_navigation.ts @@ -20,6 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'timePicker', 'settings', @@ -40,6 +41,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.update({ defaultIndex: 'logstash-*', }); + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); await PageObjects.common.navigateToApp('discover'); await PageObjects.header.waitUntilLoadingHasFinished(); diff --git a/x-pack/test_serverless/functional/test_suites/common/context/_filters.ts b/x-pack/test_serverless/functional/test_suites/common/context/_filters.ts index c27998a658899..47f864787e6c5 100644 --- a/x-pack/test_serverless/functional/test_suites/common/context/_filters.ts +++ b/x-pack/test_serverless/functional/test_suites/common/context/_filters.ts @@ -21,7 +21,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'context']); + const PageObjects = getPageObjects(['common', 'context', 'svlCommonPage']); const testSubjects = getService('testSubjects'); describe('context filters', function contextSize() { @@ -29,6 +29,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.update({ 'discover:rowHeightOption': 0, // to have more grid rows visible at once }); + await PageObjects.svlCommonPage.loginWithRole('viewer'); + await PageObjects.common.navigateToApp('discover'); }); beforeEach(async function () { diff --git a/x-pack/test_serverless/functional/test_suites/common/context/_size.ts b/x-pack/test_serverless/functional/test_suites/common/context/_size.ts index 2daebf6ed0f82..1592e183a9faf 100644 --- a/x-pack/test_serverless/functional/test_suites/common/context/_size.ts +++ b/x-pack/test_serverless/functional/test_suites/common/context/_size.ts @@ -19,7 +19,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataGrid = getService('dataGrid'); const browser = getService('browser'); const testSubjects = getService('testSubjects'); - const PageObjects = getPageObjects(['context']); + const PageObjects = getPageObjects(['context', 'svlCommonPage']); let expectedRowLength = 2 * TEST_DEFAULT_CONTEXT_SIZE + 1; describe('context size', function contextSize() { @@ -29,6 +29,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'context:defaultSize': `${TEST_DEFAULT_CONTEXT_SIZE}`, 'context:step': `${TEST_STEP_SIZE}`, }); + await PageObjects.svlCommonPage.loginWithRole('viewer'); await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/context/index.ts b/x-pack/test_serverless/functional/test_suites/common/context/index.ts index 9ed486999e9f6..5d619b1824031 100644 --- a/x-pack/test_serverless/functional/test_suites/common/context/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/context/index.ts @@ -7,27 +7,17 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; -export default function ({ - getService, - getPageObjects, - loadTestFile, - getPageObject, -}: FtrProviderContext) { +export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const esArchiver = getService('esArchiver'); - const PageObjects = getPageObjects(['common']); const kibanaServer = getService('kibanaServer'); - const svlCommonPage = getPageObject('svlCommonPage'); describe('context app', function () { before(async () => { await browser.setWindowSize(1200, 800); - // TODO: Serverless tests require login first - await svlCommonPage.login(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/visualize.json'); await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); - await PageObjects.common.navigateToApp('discover'); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/dev_tools/search_profiler.ts b/x-pack/test_serverless/functional/test_suites/common/dev_tools/search_profiler.ts index 1747d6a517c5f..6a908ce4e0fe8 100644 --- a/x-pack/test_serverless/functional/test_suites/common/dev_tools/search_profiler.ts +++ b/x-pack/test_serverless/functional/test_suites/common/dev_tools/search_profiler.ts @@ -21,15 +21,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('Search Profiler Editor', () => { before(async () => { - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('searchProfiler'); expect(await PageObjects.searchProfiler.editorExists()).to.be(true); }); - after(async () => { - await PageObjects.svlCommonPage.forceLogout(); - }); - it('supports pre-configured search query', async () => { const query = { query: { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts index 5b95dace01a6d..726246776f2ec 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts @@ -19,10 +19,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); - const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'timePicker', 'discover']); + const PageObjects = getPageObjects([ + 'common', + 'svlCommonPage', + 'dashboard', + 'header', + 'timePicker', + 'discover', + ]); describe('discover saved search embeddable', () => { before(async () => { + await browser.setWindowSize(1300, 800); + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/dashboard/current/data'); await kibanaServer.savedObjects.cleanStandardList(); @@ -39,6 +48,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); after(async () => { + await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); + await esArchiver.unload('test/functional/fixtures/es_archiver/dashboard/current/data'); await kibanaServer.savedObjects.cleanStandardList(); await PageObjects.common.unsetTime(); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/index.ts index c27f827e74ff2..805112976c653 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/index.ts @@ -7,22 +7,8 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default function ({ getService, loadTestFile, getPageObject }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const browser = getService('browser'); - const svlCommonPage = getPageObject('svlCommonPage'); - +export default function ({ loadTestFile }: FtrProviderContext) { describe('discover/embeddable', function () { - before(async function () { - await browser.setWindowSize(1300, 800); - // TODO: Serverless tests require login first - await svlCommonPage.login(); - }); - - after(async function unloadMakelogs() { - await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); - }); - loadTestFile(require.resolve('./_saved_search_embeddable')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover.ts index e301266dcd168..1b5b3c8f6ff52 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover.ts @@ -20,6 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'header', 'timePicker', @@ -37,6 +38,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // and load a set of makelogs data await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.uiSettings.replace(defaultSettings); + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); await PageObjects.common.navigateToApp('discover'); await PageObjects.timePicker.setDefaultAbsoluteRange(); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover_histogram.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover_histogram.ts index cf581ad3edb51..0d7825caffe66 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover_histogram.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_discover_histogram.ts @@ -17,10 +17,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects([ 'timePicker', 'dashboard', - 'settings', 'discover', 'common', 'header', + 'svlCommonPage', ]); const defaultSettings = { defaultIndex: 'long-window-logstash-*', @@ -42,6 +42,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await security.testUser.setRoles(['kibana_admin', 'long_window_logstash']); await kibanaServer.uiSettings.replace(defaultSettings); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); await PageObjects.common.navigateToApp('discover'); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_url_state.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_url_state.ts index 0f8c9ffd54744..242dfedde74ef 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group1/_url_state.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group1/_url_state.ts @@ -19,11 +19,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'header', 'timePicker', - 'unifiedFieldList', - 'visualize', 'svlCommonNavigation', ]); @@ -38,6 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // and load a set of makelogs data await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.uiSettings.replace(defaultSettings); + await PageObjects.svlCommonPage.loginWithRole('viewer'); await PageObjects.common.navigateToApp('discover'); await PageObjects.timePicker.setDefaultAbsoluteRange(); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group1/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group1/index.ts index 0365d037e8f32..4ad60320df38b 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group1/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group1/index.ts @@ -7,16 +7,13 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default function ({ getService, loadTestFile, getPageObject }: FtrProviderContext) { +export default function ({ getService, loadTestFile }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); - const svlCommonPage = getPageObject('svlCommonPage'); describe('discover/group1', function () { before(async function () { await browser.setWindowSize(1300, 800); - // TODO: Serverless tests require login first - await svlCommonPage.login(); }); after(async function unloadMakelogs() { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_adhoc_data_views.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_adhoc_data_views.ts index 03dd58892e5cf..b27001a396bb6 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_adhoc_data_views.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_adhoc_data_views.ts @@ -22,10 +22,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const PageObjects = getPageObjects([ 'common', - 'unifiedSearch', + 'svlCommonPage', 'discover', 'timePicker', - 'settings', 'header', 'context', 'dashboard', @@ -45,7 +44,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); await PageObjects.common.navigateToApp('discover'); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_navigation.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_navigation.ts index d690efea7693b..6fc07fe38cbef 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_navigation.ts @@ -12,7 +12,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const dataGrid = getService('dataGrid'); const testSubjects = getService('testSubjects'); - const PageObjects = getPageObjects(['common', 'discover', 'timePicker', 'context']); + const PageObjects = getPageObjects(['common', 'svlCommonPage', 'discover', 'timePicker']); const esArchiver = getService('esArchiver'); const retry = getService('retry'); const kibanaServer = getService('kibanaServer'); @@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + await PageObjects.svlCommonPage.loginWithRole('viewer'); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts index fdb0660727129..2ca4c5f856937 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts @@ -19,6 +19,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dashboardAddPanel = getService('dashboardAddPanel'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'header', 'timePicker', @@ -41,6 +42,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.uiSettings.replace(defaultSettings); await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); }); beforeEach(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts index 72243eaa24047..c579eca3bb7bd 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/index.ts @@ -7,16 +7,13 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default function ({ getService, loadTestFile, getPageObject }: FtrProviderContext) { +export default function ({ getService, loadTestFile }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); - const svlCommonPage = getPageObject('svlCommonPage'); describe('discover/group2', function () { before(async function () { await browser.setWindowSize(1600, 1200); - // TODO: Serverless tests require login first - await svlCommonPage.login(); }); after(async function unloadMakelogs() { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_request_counts.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_request_counts.ts index 8e373bae57ad6..e69dcb361722d 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_request_counts.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_request_counts.ts @@ -13,11 +13,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'timePicker', 'header', - 'unifiedSearch', - 'settings', ]); const testSubjects = getService('testSubjects'); const browser = getService('browser'); @@ -27,6 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('discover request counts', function describeIndexTests() { before(async function () { + await PageObjects.svlCommonPage.loginAsAdmin(); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts index 0504049f89ed5..270abef04517e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts @@ -13,10 +13,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects([ 'common', + 'svlCommonPage', 'discover', 'timePicker', 'header', - 'unifiedSearch', 'unifiedFieldList', ]); const testSubjects = getService('testSubjects'); @@ -31,6 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('discover sidebar', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); + await PageObjects.svlCommonPage.loginAsAdmin(); }); beforeEach(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_unsaved_changes_badge.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_unsaved_changes_badge.ts index 1f6f89a7bb33b..45fcd18d6cb26 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_unsaved_changes_badge.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_unsaved_changes_badge.ts @@ -18,12 +18,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataGrid = getService('dataGrid'); const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ - 'settings', 'common', + 'svlCommonPage', 'discover', 'header', 'timePicker', - 'dashboard', 'unifiedFieldList', ]); const security = getService('security'); @@ -37,6 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group3/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group3/index.ts index 75b2e6c9cd252..9f322013d986b 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group3/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group3/index.ts @@ -7,16 +7,13 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default function ({ getService, loadTestFile, getPageObject }: FtrProviderContext) { +export default function ({ getService, loadTestFile }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); - const svlCommonPage = getPageObject('svlCommonPage'); describe('discover/group3', function () { before(async function () { await browser.setWindowSize(1300, 800); - // TODO: Serverless tests require login first - await svlCommonPage.login(); }); after(async function unloadMakelogs() { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/index.ts index 96fad2c47d099..6d717fa082850 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/index.ts @@ -7,15 +7,8 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default function ({ loadTestFile, getPageObject }: FtrProviderContext) { - const svlCommonPage = getPageObject('svlCommonPage'); - +export default function ({ loadTestFile }: FtrProviderContext) { describe('discover', function () { - before(async function () { - // TODO: Serverless tests require login first - await svlCommonPage.login(); - }); - loadTestFile(require.resolve('./reporting')); loadTestFile(require.resolve('./visualize_field')); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/reporting.ts b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/reporting.ts index e2a491de828d9..620bf876cb9a9 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/reporting.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/reporting.ts @@ -18,7 +18,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const browser = getService('browser'); const retry = getService('retry'); - const PageObjects = getPageObjects(['reporting', 'common', 'discover', 'timePicker', 'share']); + const PageObjects = getPageObjects([ + 'reporting', + 'common', + 'svlCommonPage', + 'discover', + 'timePicker', + 'share', + ]); const filterBar = getService('filterBar'); const find = getService('find'); const testSubjects = getService('testSubjects'); @@ -56,6 +63,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Discover CSV Export', () => { describe('Check Available', () => { before(async () => { + await PageObjects.svlCommonPage.loginAsAdmin(); // TODO: emptyKibanaIndex fails in Serverless with // "index_not_found_exception: no such index [.kibana_ingest]", // so it was switched to `savedObjects.cleanStandardList()` diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/visualize_field.ts b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/visualize_field.ts index e412fea58df57..6027f3baed69d 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/visualize_field.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/x_pack/visualize_field.ts @@ -18,13 +18,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects([ 'common', - 'error', + 'svlCommonPage', 'discover', 'timePicker', - 'unifiedSearch', 'lens', - 'security', - 'spaceSelector', 'header', 'unifiedFieldList', ]); @@ -36,11 +33,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { } describe('discover field visualize button', () => { - beforeEach(async () => { + before(async () => { + // Security project requires admin role, search/oblt project passes with developer/editor. + await PageObjects.svlCommonPage.loginAsAdmin(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' ); + await kibanaServer.uiSettings.replace({ + defaultIndex: 'logstash-*', + }); + }); + + beforeEach(async () => { await PageObjects.common.navigateToApp('discover'); await setDiscoverTimeRange(); }); @@ -50,6 +55,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kibanaServer.importExport.unload( 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' ); + await kibanaServer.uiSettings.replace({}); }); it('shows "visualize" field button', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/index.ts index 253effe65b460..f4f8c8c550cb2 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/index.ts @@ -6,15 +6,8 @@ */ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default ({ loadTestFile, getPageObject }: FtrProviderContext) => { - const svlCommonPage = getPageObject('svlCommonPage'); - +export default ({ loadTestFile }: FtrProviderContext) => { describe('Discover alerting', function () { - before(async function () { - // TODO: Serverless tests require login first - await svlCommonPage.login(); - }); - loadTestFile(require.resolve('./search_source_alert')); }); }; diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts index d2e8f863d5fe9..25ae3eb08af48 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts @@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const monacoEditor = getService('monacoEditor'); const PageObjects = getPageObjects([ 'settings', + 'svlCommonPage', 'common', 'header', 'discover', @@ -343,6 +344,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Search source Alert', () => { before(async () => { await security.testUser.setRoles(['discover_alert']); + await PageObjects.svlCommonPage.loginAsAdmin(); log.debug('create source indices'); await createSourceIndex(); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/data_view_field_editor_example/index.ts b/x-pack/test_serverless/functional/test_suites/common/examples/data_view_field_editor_example/index.ts index f8f96c0bbdd20..ded70c1c77f29 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/data_view_field_editor_example/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/data_view_field_editor_example/index.ts @@ -25,8 +25,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid describe('data view field editor example', function () { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); // TODO: emptyKibanaIndex fails in Serverless with // "index_not_found_exception: no such index [.kibana_ingest]", // so it was switched to `savedObjects.cleanStandardList()` diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/discover_customization_examples/customizations.ts b/x-pack/test_serverless/functional/test_suites/common/examples/discover_customization_examples/customizations.ts index d653c6f8505ba..e538ead1ce64b 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/discover_customization_examples/customizations.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/discover_customization_examples/customizations.ts @@ -22,8 +22,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { describe('Customizations', () => { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/field_formats/index.ts b/x-pack/test_serverless/functional/test_suites/common/examples/field_formats/index.ts index 9da271eee5941..d6df9ec7f07c8 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/field_formats/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/field_formats/index.ts @@ -14,8 +14,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Field formats example', function () { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('fieldFormatsExample'); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/partial_results/index.ts b/x-pack/test_serverless/functional/test_suites/common/examples/partial_results/index.ts index 88298145edeb3..c5a5bb2995217 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/partial_results/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/partial_results/index.ts @@ -15,8 +15,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // FLAKY: https://github.com/elastic/kibana/issues/167643 describe.skip('Partial Results Example', function () { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('partialResultsExample'); const element = await testSubjects.find('example-help'); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/search/warnings.ts b/x-pack/test_serverless/functional/test_suites/common/examples/search/warnings.ts index 43ec250ff9967..43b6c6c086717 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/search/warnings.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/search/warnings.ts @@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }; before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); // create rollup data log.info(`loading ${testIndex} index...`); await esArchiver.loadIfNeeded(testArchive); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/partial_results_example.ts b/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/partial_results_example.ts index e4c86a4a64faf..6e8fbb465bb08 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/partial_results_example.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/partial_results_example.ts @@ -15,15 +15,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Partial results example', () => { before(async () => { - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('searchExamples'); await testSubjects.click('/search'); }); - after(async () => { - await PageObjects.svlCommonPage.forceLogout(); - }); - it('should update a progress bar', async () => { await testSubjects.click('responseTab'); const progressBar = await testSubjects.find('progressBar'); diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/search_example.ts b/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/search_example.ts index b62987007b1c8..a07e823b57972 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/search_example.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/search_examples/search_example.ts @@ -17,8 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Search example', () => { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); }); describe('with bfetch', () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/existing_fields.ts b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/existing_fields.ts index 1b3bf8a63caa2..4725b39bd9db1 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/existing_fields.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/existing_fields.ts @@ -65,7 +65,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { await kibanaServer.importExport.load( 'test/api_integration/fixtures/kbn_archiver/index_patterns/constant_keyword.json' ); - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('unifiedFieldListExamples'); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.waitFor('combobox is ready', async () => { @@ -90,7 +90,6 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { ); await PageObjects.unifiedFieldList.cleanSidebarLocalStorage(); await kibanaServer.savedObjects.cleanStandardList(); - await PageObjects.svlCommonPage.forceLogout(); }); // FLAKY: https://github.com/elastic/kibana/issues/172781 diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts index 47bbefa0dc8d6..a1c72e7c46182 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts @@ -29,8 +29,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { describe('Field stats', () => { before(async () => { - // TODO: Serverless tests require login first - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.load( diff --git a/x-pack/test_serverless/functional/test_suites/common/grok_debugger/grok_debugger.ts b/x-pack/test_serverless/functional/test_suites/common/grok_debugger/grok_debugger.ts index c3547fe790303..96f7c61cfb618 100644 --- a/x-pack/test_serverless/functional/test_suites/common/grok_debugger/grok_debugger.ts +++ b/x-pack/test_serverless/functional/test_suites/common/grok_debugger/grok_debugger.ts @@ -22,7 +22,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // fold. Otherwise it can't be clicked by the browser driver. await browser.setWindowSize(1600, 1000); await security.testUser.setRoles(['global_devtools_read', 'ingest_pipelines_user']); - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('dev_tools', { hash: '/grokdebugger' }); await retry.waitFor('Grok Debugger Header to be visible', async () => { return testSubjects.isDisplayed('grokDebuggerContainer'); @@ -30,7 +30,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); after(async () => { - await PageObjects.svlCommonPage.forceLogout(); await security.testUser.restoreDefaults(); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/home_page/home_page.ts b/x-pack/test_serverless/functional/test_suites/common/home_page/home_page.ts index 228a8b431ad32..cbf1bb5b933b9 100644 --- a/x-pack/test_serverless/functional/test_suites/common/home_page/home_page.ts +++ b/x-pack/test_serverless/functional/test_suites/common/home_page/home_page.ts @@ -13,11 +13,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { describe('home page', function () { before(async () => { - await svlCommonPage.login(); - }); - - after(async () => { - await svlCommonPage.forceLogout(); + await svlCommonPage.loginWithRole('viewer'); }); it('has project header', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/home_page/sample_data.ts b/x-pack/test_serverless/functional/test_suites/common/home_page/sample_data.ts index 803e0edeba789..4fd5a47f0b903 100644 --- a/x-pack/test_serverless/functional/test_suites/common/home_page/sample_data.ts +++ b/x-pack/test_serverless/functional/test_suites/common/home_page/sample_data.ts @@ -14,12 +14,11 @@ export default function ({ getPageObjects }: FtrProviderContext) { // Failing - should be fixed with https://github.com/elastic/kibana/pull/164052 describe.skip('Sample data in serverless', function () { before(async () => { - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { await pageObjects.home.removeSampleDataSet('ecommerce'); - await pageObjects.svlCommonPage.forceLogout(); }); it('Sample data loads', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/management/advanced_settings.ts b/x-pack/test_serverless/functional/test_suites/common/management/advanced_settings.ts index 3b07f05fa9191..55221b1451d2b 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/advanced_settings.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/advanced_settings.ts @@ -46,7 +46,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await kibanaServer.uiSettings.update({ 'csv:quoteValues': true, }); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('settings'); }); @@ -55,7 +55,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await kibanaServer.uiSettings.update({ 'csv:quoteValues': INITIAL_CSV_QUOTE_VALUES_SETTING_VALUE, }); - await pageObjects.svlCommonPage.forceLogout(); }); it('renders the page', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields.ts index b7bc99d9aecb1..5657b1aebfee5 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields.ts @@ -18,8 +18,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // Failing: See https://github.com/elastic/kibana/issues/173558 describe.skip('runtime fields', function () { - this.tags(['skipFirefox']); - before(async function () { await browser.setWindowSize(1200, 800); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields_composite.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields_composite.ts index a047a4f0e85a5..74bd6312807a0 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields_composite.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_runtime_fields_composite.ts @@ -17,8 +17,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); describe('runtime fields', function () { - this.tags(['skipFirefox']); - before(async function () { await browser.setWindowSize(1200, 800); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts index 69fec71b2ad22..dd33cb266d618 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts @@ -13,8 +13,7 @@ export default ({ getService, loadTestFile, getPageObject }: FtrProviderContext) const svlCommonPage = getPageObject('svlCommonPage'); before(async () => { - // TODO: Serverless tests require login first - await svlCommonPage.login(); + await svlCommonPage.loginAsAdmin(); await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/makelogs'); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/serverless.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/serverless.ts index 896c95b6dc2bd..6e5831ee30beb 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/serverless.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/serverless.ts @@ -20,9 +20,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); describe('Serverless tests', function () { - this.beforeAll(async () => { - await PageObjects.svlCommonPage.login(); - }); describe('disables scripted fields', function () { let dataViewId = ''; diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts index e70470582b2b5..d72aadd9dbb1a 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts @@ -22,8 +22,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Index component templates', function () { before(async () => { await security.testUser.setRoles(['index_management_user']); - // Navigate to the index management page - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); }); beforeEach(async () => { @@ -33,10 +32,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.header.waitUntilLoadingHasFinished(); }); - after(async () => { - await pageObjects.svlCommonPage.forceLogout(); - }); - it('renders the component templates tab', async () => { const url = await browser.getCurrentUrl(); expect(url).to.contain(`/component_templates`); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/create_enrich_policy.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/create_enrich_policy.ts index 60753a0ad9bd9..d5cd5e450019e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/create_enrich_policy.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/create_enrich_policy.ts @@ -46,7 +46,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } log.debug('Navigating to the enrich policies tab'); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('indexManagement'); // Navigate to the enrich policies tab @@ -64,8 +64,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } catch (e) { log.debug('[Teardown error] Error deleting test policy'); throw e; - } finally { - await pageObjects.svlCommonPage.forceLogout(); } }); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/data_streams.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/data_streams.ts index 4bd839e2c9ebb..4a92df7d90f39 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/data_streams.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/data_streams.ts @@ -21,7 +21,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Data Streams', function () { before(async () => { - await log.debug('Creating required data stream'); + log.debug('Creating required data stream'); try { await es.cluster.putComponentTemplate({ name: `${TEST_DS_NAME}_mapping`, @@ -56,8 +56,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } await security.testUser.setRoles(['index_management_user']); - // Navigate to the index management page - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('indexManagement'); // Navigate to the indices tab await pageObjects.indexManagement.changeTabs('data_streamsTab'); @@ -65,7 +64,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); after(async () => { - await log.debug('Cleaning up created data stream'); + log.debug('Cleaning up created data stream'); try { await es.indices.deleteDataStream({ name: TEST_DS_NAME }); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/enrich_policies.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/enrich_policies.ts index 66819c1e6d233..5c8bd2f45fef9 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/enrich_policies.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/enrich_policies.ts @@ -53,7 +53,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } log.debug('Navigating to the enrich policies tab'); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('indexManagement'); // Navigate to the enrich policies tab diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/index_templates.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/index_templates.ts index 7d591ade32c3c..147ce1126ca33 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/index_templates.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/index_templates.ts @@ -23,7 +23,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Index Templates', function () { before(async () => { - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); }); beforeEach(async () => { @@ -42,8 +42,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { log.debug('[Setup error] Error creating test policy'); throw e; } - - await pageObjects.svlCommonPage.forceLogout(); }); it('renders the index templates tab', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/indices.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/indices.ts index efcddefda84e1..c0994de088513 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/indices.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/indices.ts @@ -16,8 +16,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Indices', function () { before(async () => { await security.testUser.setRoles(['index_management_user']); - // Navigate to the index management page - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('indexManagement'); // Navigate to the indices tab await pageObjects.indexManagement.changeTabs('indicesTab'); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/ingest_pipelines.ts b/x-pack/test_serverless/functional/test_suites/common/management/ingest_pipelines.ts index c9a5b730cc00e..5a7c13c6a4b56 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/ingest_pipelines.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/ingest_pipelines.ts @@ -29,14 +29,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Ingest Pipelines', function () { this.tags('smoke'); before(async () => { - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); }); beforeEach(async () => { await pageObjects.common.navigateToApp('ingestPipelines'); }); - after(async () => { - await pageObjects.svlCommonPage.forceLogout(); - }); it('Loads the app', async () => { log.debug('Checking for section heading to say Ingest Pipelines.'); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/landing_page.ts b/x-pack/test_serverless/functional/test_suites/common/management/landing_page.ts index e3271ec1009c2..b3c98e61e7d2a 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/landing_page.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/landing_page.ts @@ -17,15 +17,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Management landing page', function () { this.tags('smoke'); before(async () => { - // Navigate to the index management page - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); }); - after(async () => { - await pageObjects.svlCommonPage.forceLogout(); - }); - it('renders the page', async () => { await retry.waitFor('page to be visible', async () => { return await testSubjects.exists('cards-navigation-page'); diff --git a/x-pack/test_serverless/functional/test_suites/common/management/transforms/search_bar_features.ts b/x-pack/test_serverless/functional/test_suites/common/management/transforms/search_bar_features.ts index 124fe461d5306..2add9bcc4476e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/transforms/search_bar_features.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/transforms/search_bar_features.ts @@ -16,11 +16,7 @@ export default function ({ getPageObjects }: FtrProviderContext) { describe('Search bar features', () => { before(async () => { - await PageObjects.svlCommonPage.login(); - }); - - after(async () => { - await PageObjects.svlCommonPage.forceLogout(); + await PageObjects.svlCommonPage.loginAsAdmin(); }); describe('list features', () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/management/transforms/transform_list.ts b/x-pack/test_serverless/functional/test_suites/common/management/transforms/transform_list.ts index 453db13c33c28..a7b0a83d56af2 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/transforms/transform_list.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/transforms/transform_list.ts @@ -17,7 +17,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Transform List', function () { before(async () => { await security.testUser.setRoles(['transform_user']); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); // For this test to work, make sure there are no pre-existing transform present. // For example, solutions might set up transforms automatically. diff --git a/x-pack/test_serverless/functional/test_suites/common/painless_lab/painless_lab.ts b/x-pack/test_serverless/functional/test_suites/common/painless_lab/painless_lab.ts index e781808189100..2f385967149ee 100644 --- a/x-pack/test_serverless/functional/test_suites/common/painless_lab/painless_lab.ts +++ b/x-pack/test_serverless/functional/test_suites/common/painless_lab/painless_lab.ts @@ -27,17 +27,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Painless lab', function describeIndexTests() { before(async () => { - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('dev_tools', { hash: '/painless_lab' }); await retry.waitFor('Wait for editor to be visible', async () => { return testSubjects.isDisplayed('painless_lab'); }); }); - after(async () => { - await PageObjects.svlCommonPage.forceLogout(); - }); - it('should show the editor and preview panels', async () => { const editor = await testSubjects.find('kibanaCodeEditor'); const preview = await testSubjects.find('painlessTabs'); diff --git a/x-pack/test_serverless/functional/test_suites/common/platform_security/api_keys.ts b/x-pack/test_serverless/functional/test_suites/common/platform_security/api_keys.ts index 986e6d31c942e..265be2469ac90 100644 --- a/x-pack/test_serverless/functional/test_suites/common/platform_security/api_keys.ts +++ b/x-pack/test_serverless/functional/test_suites/common/platform_security/api_keys.ts @@ -33,12 +33,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // TimeoutError: Waiting for element to be located By(css selector, [data-test-subj="apiKeysCreatePromptButton"]) Wait timed out after 10028ms this.tags(['failsOnMKI']); before(async () => { - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); }); after(async () => { await clearAllApiKeys(es, log); - await pageObjects.svlCommonPage.forceLogout(); }); it('should create and delete API keys correctly', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/platform_security/navigation/avatar_menu.ts b/x-pack/test_serverless/functional/test_suites/common/platform_security/navigation/avatar_menu.ts index ca693e2b966c8..8b2dd1b227b9e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/platform_security/navigation/avatar_menu.ts +++ b/x-pack/test_serverless/functional/test_suites/common/platform_security/navigation/avatar_menu.ts @@ -13,11 +13,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { describe('Avatar menu', function () { before(async () => { - await svlCommonPage.login(); - }); - - after(async () => { - await svlCommonPage.forceLogout(); + await svlCommonPage.loginWithRole('viewer'); }); it('is displayed', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts b/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts index 57ef995a4f7a6..2045f172d3db0 100644 --- a/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts +++ b/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts @@ -13,9 +13,14 @@ export default function ({ getPageObjects }: FtrProviderContext) { describe('User Profile Page', async () => { before(async () => { + // TODO: migrate to SAML role when profile page displays the data await pageObjects.svlCommonPage.login(); }); + after(async () => { + await pageObjects.svlCommonPage.forceLogout(); + }); + describe('Theme', async () => { it('should change theme based on the User Profile Theme control', async () => { await pageObjects.common.navigateToApp('security_account'); diff --git a/x-pack/test_serverless/functional/test_suites/common/reporting/management.ts b/x-pack/test_serverless/functional/test_suites/common/reporting/management.ts index 90be1b602441a..6d23ef5512b76 100644 --- a/x-pack/test_serverless/functional/test_suites/common/reporting/management.ts +++ b/x-pack/test_serverless/functional/test_suites/common/reporting/management.ts @@ -24,7 +24,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const navigateToReportingManagement = async () => { log.debug(`navigating to reporting management app`); await retry.tryForTime(60 * 1000, async () => { - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('reportingManagement'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.existOrFail('reportingPageHeader', { timeout: 2000 }); diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/bulk_get.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/bulk_get.ts index 78d4f41033388..92e1a4a69c205 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/bulk_get.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/bulk_get.ts @@ -26,7 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/hidden_saved_objects' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -40,7 +40,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/hidden_saved_objects' ); await kibanaServer.savedObjects.cleanStandardList(); - await pageObjects.svlCommonPage.forceLogout(); }); const URL = '/api/kibana/management/saved_objects/_bulk_get'; diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/export_transform.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/export_transform.ts index dea6b1118b0f1..80de679ca7b49 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/export_transform.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/export_transform.ts @@ -28,7 +28,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/export_transform' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -39,7 +39,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'test/functional/fixtures/es_archiver/saved_objects_management/export_transform' ); await kibanaServer.savedObjects.cleanStandardList(); - await pageObjects.svlCommonPage.forceLogout(); }); it('allows to mutate the objects during an export', async () => { @@ -159,7 +158,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -170,7 +169,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'test/functional/fixtures/es_archiver/saved_objects_management/nested_export_transform' ); await kibanaServer.savedObjects.cleanStandardList(); - await pageObjects.svlCommonPage.forceLogout(); }); it('execute export transforms for reference objects', async () => { @@ -211,7 +209,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/export_exclusion' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -222,7 +220,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'test/functional/fixtures/es_archiver/saved_objects_management/export_exclusion' ); await kibanaServer.savedObjects.cleanStandardList(); - await pageObjects.svlCommonPage.forceLogout(); }); it('should only export objects returning `true` for `isExportable`', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/find.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/find.ts index e2787135b093a..986479518bfd4 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/find.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/find.ts @@ -25,7 +25,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/hidden_saved_objects' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -42,7 +42,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // "index_not_found_exception: no such index [.kibana_ingest]", // so it was switched to `savedObjects.cleanStandardList() await kibanaServer.savedObjects.cleanStandardList(); - await pageObjects.svlCommonPage.forceLogout(); }); it('returns saved objects with importableAndExportable types', async () => diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_from_http_apis.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_from_http_apis.ts index 404773e584a2a..d5edfb0e73bf2 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_from_http_apis.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_from_http_apis.ts @@ -29,7 +29,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kbnServer.importExport.load( 'test/functional/fixtures/kbn_archiver/saved_objects_management/hidden_from_http_apis' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -42,7 +42,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.unload( 'test/functional/fixtures/es_archiver/saved_objects_management/hidden_from_http_apis' ); - await pageObjects.svlCommonPage.forceLogout(); }); describe('APIS', () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts index 767e833ecc20f..9a48fd898d3c7 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/hidden_types.ts @@ -27,7 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/hidden_types' ); - await PageObjects.svlCommonPage.login(); + await PageObjects.svlCommonPage.loginAsAdmin(); await PageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await PageObjects.savedObjects.waitTableIsLoaded(); @@ -38,11 +38,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'test/functional/fixtures/es_archiver/saved_objects_management/hidden_types' ); await kibanaServer.savedObjects.cleanStandardList(); - await PageObjects.svlCommonPage.forceLogout(); }); beforeEach(async () => { - // await PageObjects.svlCommonPage.login(); await PageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await PageObjects.savedObjects.waitTableIsLoaded(); diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/import_warnings.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/import_warnings.ts index ca3d81f2c4551..a469010f09f71 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/import_warnings.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/import_warnings.ts @@ -21,10 +21,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // "index_not_found_exception: no such index [.kibana_ingest]", // so it was switched to `savedObjects.cleanStandardList() await kibanaServer.savedObjects.cleanStandardList(); + await PageObjects.svlCommonPage.loginAsAdmin(); }); beforeEach(async () => { - await PageObjects.svlCommonPage.login(); await PageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await PageObjects.savedObjects.waitTableIsLoaded(); diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/scroll_count.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/scroll_count.ts index d6d173b646563..1ae8afebcc354 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/scroll_count.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/scroll_count.ts @@ -26,7 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/hidden_saved_objects' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); diff --git a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/visible_in_management.ts b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/visible_in_management.ts index f0e4486a5254b..f4e1b28682b40 100644 --- a/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/visible_in_management.ts +++ b/x-pack/test_serverless/functional/test_suites/common/saved_objects_management/visible_in_management.ts @@ -28,7 +28,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.load( 'test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management' ); - await pageObjects.svlCommonPage.login(); + await pageObjects.svlCommonPage.loginAsAdmin(); await pageObjects.common.navigateToApp('management'); await testSubjects.click('app-card-objects'); await pageObjects.savedObjects.waitTableIsLoaded(); @@ -38,7 +38,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.unload( 'test/functional/fixtures/es_archiver/saved_objects_management/visible_in_management' ); - await pageObjects.svlCommonPage.forceLogout(); }); describe('export', () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/index.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/index.ts index 3b8db07a689ac..d5f782fc7ee6c 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/index.ts @@ -59,7 +59,6 @@ export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext }); await kibanaServer.importExport.load(fixtureDirs.lensBasic); await kibanaServer.importExport.load(fixtureDirs.lensDefault); - await PageObjects.svlCommonPage.login(); // changing the timepicker default here saves us from having to set it in Discover (~8s) await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); }); @@ -67,7 +66,6 @@ export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext after(async () => { await esArchiver.unload(esArchive); await PageObjects.timePicker.resetDefaultAbsoluteRangeViaUiSettings(); - await PageObjects.svlCommonPage.forceLogout(); await kibanaServer.importExport.unload(fixtureDirs.lensBasic); await kibanaServer.importExport.unload(fixtureDirs.lensDefault); await kibanaServer.savedObjects.cleanStandardList(); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/smokescreen.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/smokescreen.ts index d4337d16db4ea..027afe3c2ebe5 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/smokescreen.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/smokescreen.ts @@ -10,7 +10,7 @@ import { range } from 'lodash'; import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']); + const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header', 'svlCommonPage']); const find = getService('find'); const listingTable = getService('listingTable'); const testSubjects = getService('testSubjects'); @@ -20,6 +20,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const config = getService('config'); describe('lens smokescreen tests', () => { + before(async () => { + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); + }); + it('should allow creation of lens xy chart', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/tsdb.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/tsdb.ts index 96b1d0125c955..99633e01940c1 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/tsdb.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/tsdb.ts @@ -238,7 +238,13 @@ function sumFirstNValues(n: number, bars: Array<{ y: number }>): number { } export default function ({ getService, getPageObjects }: FtrProviderContext) { - const PageObjects = getPageObjects(['common', 'timePicker', 'lens', 'dashboard']); + const PageObjects = getPageObjects([ + 'common', + 'timePicker', + 'lens', + 'dashboard', + 'svlCommonPage', + ]); const testSubjects = getService('testSubjects'); const find = getService('find'); const kibanaServer = getService('kibanaServer'); @@ -319,6 +325,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const toTime = 'Jun 16, 2023 @ 00:00:00.000'; before(async () => { + await PageObjects.svlCommonPage.loginAsAdmin(); log.info(`loading ${tsdbIndex} index...`); await esArchiver.loadIfNeeded(tsdbEsArchive); log.info(`creating a data view for "${tsdbDataView}"...`); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/vega_chart.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/vega_chart.ts index e38c188a73096..347304b4b9f19 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/vega_chart.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group1/vega_chart.ts @@ -32,6 +32,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'visChart', 'visEditor', 'vegaChart', + 'svlCommonPage', ]); const filterBar = getService('filterBar'); const inspector = getService('inspector'); @@ -42,6 +43,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('vega chart in visualize app', () => { before(async () => { + await PageObjects.svlCommonPage.loginWithPrivilegedRole(); await PageObjects.visualize.initTests(); log.debug('navigateToApp visualize'); await PageObjects.visualize.navigateToNewVisualization(); diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts index f3abd6dccef91..d63cbd6e60dbd 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/index.ts @@ -7,18 +7,8 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; -export default ({ loadTestFile, getPageObject }: FtrProviderContext) => { - const svlCommonPage = getPageObject('svlCommonPage'); - +export default ({ loadTestFile }: FtrProviderContext) => { describe('Visualizations - Group 2', function () { - before(async () => { - await svlCommonPage.login(); - }); - - after(async () => { - await svlCommonPage.forceLogout(); - }); - loadTestFile(require.resolve('./open_in_lens/agg_based')); }); }; diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/gauge.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/gauge.ts index d13f2e5b2aed1..8315a8e2a7eda 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/gauge.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/gauge.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const testSubjects = getService('testSubjects'); const find = getService('find'); @@ -22,6 +27,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts index b67cbe95e1ba6..d1c73fc4dc45f 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/goal.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const testSubjects = getService('testSubjects'); const panelActions = getService('dashboardPanelActions'); @@ -21,6 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/heatmap.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/heatmap.ts index 6e486d6d34e5d..836dceaee8b4e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/heatmap.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/heatmap.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const panelActions = getService('dashboardPanelActions'); const kibanaServer = getService('kibanaServer'); @@ -20,6 +25,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts index c608c454e3039..d767efbe11f10 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/metric.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const testSubjects = getService('testSubjects'); const panelActions = getService('dashboardPanelActions'); @@ -21,6 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/pie.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/pie.ts index d1aa46064e573..bdd51d65b703d 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/pie.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/pie.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const pieChart = getService('pieChart'); const testSubjects = getService('testSubjects'); @@ -22,6 +27,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts index 4761bd22d9429..7fa380951a12d 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/table.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const testSubjects = getService('testSubjects'); const panelActions = getService('dashboardPanelActions'); @@ -22,6 +27,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/xy.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/xy.ts index 08da72b5e66fb..299142e7cf9b5 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/xy.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group2/open_in_lens/agg_based/xy.ts @@ -9,7 +9,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const { lens, timePicker, dashboard } = getPageObjects(['lens', 'timePicker', 'dashboard']); + const { svlCommonPage, lens, timePicker, dashboard } = getPageObjects([ + 'svlCommonPage', + 'lens', + 'timePicker', + 'dashboard', + ]); const testSubjects = getService('testSubjects'); const retry = getService('retry'); @@ -22,6 +27,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await kibanaServer.importExport.load(fixture); + await svlCommonPage.loginWithPrivilegedRole(); }); after(async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/index.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/index.ts index 4dbf361074deb..6bf20a6968d99 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/index.ts @@ -12,11 +12,7 @@ export default ({ loadTestFile, getPageObject }: FtrProviderContext) => { describe('Visualizations - Group 3', function () { before(async () => { - await svlCommonPage.login(); - }); - - after(async () => { - await svlCommonPage.forceLogout(); + await svlCommonPage.loginWithPrivilegedRole(); }); loadTestFile(require.resolve('./open_in_lens/tsvb')); diff --git a/x-pack/test_serverless/functional/test_suites/security/common_configs/config.group6.ts b/x-pack/test_serverless/functional/test_suites/security/common_configs/config.group6.ts index f3276ecd3c67c..8ebd1f6958ec7 100644 --- a/x-pack/test_serverless/functional/test_suites/security/common_configs/config.group6.ts +++ b/x-pack/test_serverless/functional/test_suites/security/common_configs/config.group6.ts @@ -15,7 +15,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { testFiles: [ require.resolve('../../common/discover/embeddable'), require.resolve('../../common/discover/x_pack'), - require.resolve('../../common/discover_ml_uptime/discover'), + // flaky for Security project, should be checked with Admin role permissions. + // https://github.com/elastic/kibana/issues/172365 + // require.resolve('../../common/discover_ml_uptime/discover'), require.resolve('../../common/context'), ], junit: { diff --git a/x-pack/test_serverless/shared/services/svl_user_manager.ts b/x-pack/test_serverless/shared/services/svl_user_manager.ts index 9ed3395340494..2299b4d78e974 100644 --- a/x-pack/test_serverless/shared/services/svl_user_manager.ts +++ b/x-pack/test_serverless/shared/services/svl_user_manager.ts @@ -9,6 +9,8 @@ import { ServerlessProjectType, SERVERLESS_ROLES_ROOT_PATH } from '@kbn/es'; import { SamlSessionManager } from '@kbn/test'; import { readRolesFromResource } from '@kbn/es'; import { resolve } from 'path'; +import { Role } from '@kbn/test/src/auth/types'; +import { isServerlessProjectType } from '@kbn/es/src/utils'; import { FtrProviderContext } from '../../functional/ftr_provider_context'; export function SvlUserManagerProvider({ getService }: FtrProviderContext) { @@ -17,11 +19,32 @@ export function SvlUserManagerProvider({ getService }: FtrProviderContext) { const isCloud = !!process.env.TEST_CLOUD; const kbnServerArgs = config.get('kbnTestServer.serverArgs') as string[]; const projectType = kbnServerArgs - .find((arg) => arg.startsWith('--serverless'))! - .split('=')[1] as ServerlessProjectType; + .filter((arg) => arg.startsWith('--serverless')) + .reduce((acc, arg) => { + const match = arg.match(/--serverless[=\s](\w+)/); + return acc + (match ? match[1] : ''); + }, '') as ServerlessProjectType; - const resourcePath = resolve(SERVERLESS_ROLES_ROOT_PATH, projectType, 'roles.yml'); - const supportedRoles = readRolesFromResource(resourcePath); + if (!isServerlessProjectType(projectType)) { + throw new Error(`Unsupported serverless projectType: ${projectType}`); + } + + const supportedRoles = readRolesFromResource( + resolve(SERVERLESS_ROLES_ROOT_PATH, projectType, 'roles.yml') + ); + const defaultRolesToMap = new Map<string, Role>([ + ['es', 'developer'], + ['security', 'editor'], + ['oblt', 'editor'], + ]); + + const getDefaultRole = () => { + if (defaultRolesToMap.has(projectType)) { + return defaultRolesToMap.get(projectType)!; + } else { + throw new Error(`Default role is not defined for ${projectType} project`); + } + }; // Sharing the instance within FTR config run means cookies are persistent for each role between tests. const sessionManager = new SamlSessionManager({ @@ -37,5 +60,18 @@ export function SvlUserManagerProvider({ getService }: FtrProviderContext) { supportedRoles, }); - return sessionManager; + const DEFAULT_ROLE = getDefaultRole(); + + return { + async getSessionCookieForRole(role: string) { + return sessionManager.getSessionCookieForRole(role); + }, + async getApiCredentialsForRole(role: string) { + return sessionManager.getApiCredentialsForRole(role); + }, + async getUserData(role: string) { + return sessionManager.getUserData(role); + }, + DEFAULT_ROLE, + }; } From 4ceff18802dd7efaf664b7e1233114028f9afe71 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet <nicolas.chaulet@elastic.co> Date: Fri, 9 Feb 2024 12:26:46 -0500 Subject: [PATCH 088/104] [Fleet] Sync kuery url querystring with current search in agent list (#176606) --- .../hooks/use_fetch_agents_data.test.tsx | 35 ++++++++++++++++--- .../hooks/use_fetch_agents_data.tsx | 23 ++++++++++-- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.test.tsx index 6e948f45ea942..5640890b3f810 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.test.tsx @@ -5,11 +5,12 @@ * 2.0. */ -import { renderHook, act } from '@testing-library/react-hooks'; +import { act } from '@testing-library/react-hooks'; import { useStartServices } from '../../../../hooks'; import { ExperimentalFeaturesService } from '../../../../services'; +import { createFleetTestRendererMock } from '../../../../../../mock'; import { useFetchAgentsData } from './use_fetch_agents_data'; @@ -78,7 +79,6 @@ jest.mock('../../../../hooks', () => ({ pageSizeOptions: [5, 20, 50], setPagination: jest.fn(), }), - useUrlParams: jest.fn().mockReturnValue({ urlParams: { kuery: '' } }), })); describe('useFetchAgentsData', () => { @@ -97,10 +97,9 @@ describe('useFetchAgentsData', () => { }); it('should fetch agents and agent policies data', async () => { - let result: any | undefined; - let waitForNextUpdate: any | undefined; + const renderer = createFleetTestRendererMock(); + const { result, waitForNextUpdate } = renderer.renderHook(() => useFetchAgentsData()); await act(async () => { - ({ result, waitForNextUpdate } = renderHook(() => useFetchAgentsData())); await waitForNextUpdate(); }); @@ -139,4 +138,30 @@ describe('useFetchAgentsData', () => { expect(result?.current.pagination).toEqual({ currentPage: 1, pageSize: 5 }); expect(result?.current.pageSizeOptions).toEqual([5, 20, 50]); }); + + it('sync querystring kuery with current search', async () => { + const renderer = createFleetTestRendererMock(); + const { result, waitForNextUpdate } = renderer.renderHook(() => useFetchAgentsData()); + await act(async () => { + await waitForNextUpdate(); + }); + + expect(renderer.history.location.search).toEqual(''); + + // Set search + await act(async () => { + result.current.setSearch('active:true'); + await waitForNextUpdate(); + }); + + expect(renderer.history.location.search).toEqual('?kuery=active%3Atrue'); + + // Clear search + await act(async () => { + result.current.setSearch(''); + await waitForNextUpdate(); + }); + + expect(renderer.history.location.search).toEqual(''); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.tsx index 711a5fb91a9ba..ae0067a6af21a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/hooks/use_fetch_agents_data.tsx @@ -7,6 +7,7 @@ import { useState, useMemo, useCallback, useRef, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { isEqual } from 'lodash'; +import { useHistory } from 'react-router-dom'; import { agentStatusesToSummary } from '../../../../../../../common/services'; @@ -33,14 +34,16 @@ export function useFetchAgentsData() { const { notifications } = useStartServices(); // useBreadcrumbs('agent_list'); - const defaultKuery: string = (useUrlParams().urlParams.kuery as string) || ''; + const history = useHistory(); + const { urlParams, toUrlParams } = useUrlParams(); + const defaultKuery: string = (urlParams.kuery as string) || ''; // Agent data states const [showUpgradeable, setShowUpgradeable] = useState<boolean>(false); // Table and search states const [draftKuery, setDraftKuery] = useState<string>(defaultKuery); - const [search, setSearch] = useState<string>(defaultKuery); + const [search, setSearchState] = useState<string>(defaultKuery); const { pagination, pageSizeOptions, setPagination } = usePagination(); const [sortField, setSortField] = useState<keyof Agent>('enrolled_at'); const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); @@ -65,6 +68,22 @@ export function useFetchAgentsData() { return selectedStatus.some((status) => status === 'inactive' || status === 'unenrolled'); }, [selectedStatus]); + const setSearch = useCallback( + (newVal: string) => { + setSearchState(newVal); + if (newVal.trim() === '' && !urlParams.kuery) { + return; + } + + if (urlParams.kuery !== newVal) { + history.replace({ + search: toUrlParams({ ...urlParams, kuery: newVal === '' ? undefined : newVal }), + }); + } + }, + [urlParams, history, toUrlParams] + ); + // filters kuery const kuery = useMemo(() => { return getKuery({ From c9f279a74bd0c9372170e70c5c97d32d8805345e Mon Sep 17 00:00:00 2001 From: Tiago Costa <tiago.costa@elastic.co> Date: Fri, 9 Feb 2024 17:27:52 +0000 Subject: [PATCH 089/104] skip flaky suite (#176524) --- .../public/components/user_actions/user_actions_list.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx index 7a5a0b232589e..8c8633310b4b4 100644 --- a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx @@ -31,7 +31,8 @@ const defaultProps = { jest.mock('../../common/lib/kibana'); -describe(`UserActionsList`, () => { +// FLAKY: https://github.com/elastic/kibana/issues/176524 +describe.skip(`UserActionsList`, () => { let appMockRender: AppMockRenderer; beforeEach(() => { From fc5880d639b7df6967cce0319d40a57b1aeddae6 Mon Sep 17 00:00:00 2001 From: Tiago Costa <tiago.costa@elastic.co> Date: Fri, 9 Feb 2024 17:28:02 +0000 Subject: [PATCH 090/104] skip flaky suite (#176525) --- .../public/components/user_actions/user_actions_list.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx index 8c8633310b4b4..8e042c1b95a72 100644 --- a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx @@ -32,6 +32,7 @@ const defaultProps = { jest.mock('../../common/lib/kibana'); // FLAKY: https://github.com/elastic/kibana/issues/176524 +// FLAKY: https://github.com/elastic/kibana/issues/176525 describe.skip(`UserActionsList`, () => { let appMockRender: AppMockRenderer; From 7e74fe7bad363880adcc0723ceadc396f4f13a7c Mon Sep 17 00:00:00 2001 From: Pablo Machado <pablo.nevesmachado@elastic.co> Date: Fri, 9 Feb 2024 18:28:43 +0100 Subject: [PATCH 091/104] [Security Solution] Fix date fields not formatted on the new user expandable flyout (#176572) ## Summary Fix first-seen and last-seen fields not properly formatted on the new user expandable flyout. **Before** <img width="400" src="https://github.com/elastic/kibana/assets/1490444/00140a86-1b2a-42ea-8ecd-6a27c9f6bd59" /> **After** <img width="400" src="https://github.com/elastic/kibana/assets/1490444/b841dfb2-e2b8-4fcf-8e7e-e51d831059b7" /> ### How to test * Enable the experimental flag `newUserDetailsFlyout` * Open the alerts page populated with data * Click on the user name * It should display the new user flyout with formatted dates ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../hooks/use_observed_user_items.test.ts | 10 ++++----- ...r_items.ts => use_observed_user_items.tsx} | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) rename x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/{use_observed_user_items.ts => use_observed_user_items.tsx} (75%) diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.test.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.test.ts index abd771d240cae..f02ccc68cce0e 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.test.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.test.ts @@ -28,14 +28,12 @@ describe('useManagedUserItems', () => { getValues: expect.any(Function), }, { - field: '@timestamp', label: 'First seen', - getValues: expect.any(Function), + render: expect.any(Function), }, { - field: '@timestamp', label: 'Last seen', - getValues: expect.any(Function), + render: expect.any(Function), }, { field: 'host.os.name', @@ -65,8 +63,8 @@ describe('useManagedUserItems', () => { [ ['1234', '321'], // id ['test domain', 'another test domain'], // domain - ['2023-02-23T20:03:17.489Z'], // First seen - ['2023-02-23T20:03:17.489Z'], // Last seen + undefined, // First seen doesn't implement getValues + undefined, // Last seen doesn't implement getValues ['testOs'], // OS name ['testFamily'], // os family ['10.0.0.1', '127.0.0.1'], // IP addresses diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.tsx similarity index 75% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.tsx index 7275b2ca55570..3dbc4fd1b507f 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/hooks/use_observed_user_items.tsx @@ -5,13 +5,15 @@ * 2.0. */ -import { useMemo } from 'react'; +import React, { useMemo } from 'react'; +import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; import type { UserItem } from '../../../../../common/search_strategy'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; import { getAnomaliesFields } from '../../shared/common'; import * as i18n from './translations'; import type { ObservedEntityData } from '../../shared/components/observed_entity/types'; import type { EntityTableRows } from '../../shared/components/entity_table/types'; +import { getEmptyTagValue } from '../../../../common/components/empty_value'; const basicUserFields: EntityTableRows<ObservedEntityData<UserItem>> = [ { @@ -26,15 +28,21 @@ const basicUserFields: EntityTableRows<ObservedEntityData<UserItem>> = [ }, { label: i18n.FIRST_SEEN, - getValues: (userData: ObservedEntityData<UserItem>) => - userData.firstSeen.date ? [userData.firstSeen.date] : undefined, - field: '@timestamp', + render: (userData: ObservedEntityData<UserItem>) => + userData.firstSeen.date ? ( + <FormattedRelativePreferenceDate value={userData.firstSeen.date} /> + ) : ( + getEmptyTagValue() + ), }, { label: i18n.LAST_SEEN, - getValues: (userData: ObservedEntityData<UserItem>) => - userData.lastSeen.date ? [userData.lastSeen.date] : undefined, - field: '@timestamp', + render: (userData: ObservedEntityData<UserItem>) => + userData.lastSeen.date ? ( + <FormattedRelativePreferenceDate value={userData.lastSeen.date} /> + ) : ( + getEmptyTagValue() + ), }, { label: i18n.OPERATING_SYSTEM_TITLE, From 3503a1184400877d2889eb82eb443453b3cfcfe1 Mon Sep 17 00:00:00 2001 From: Tiago Costa <tiago.costa@elastic.co> Date: Fri, 9 Feb 2024 17:33:28 +0000 Subject: [PATCH 092/104] skip flaky suite (#175655) --- .../public/components/case_view/components/edit_tags.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/case_view/components/edit_tags.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/edit_tags.test.tsx index baad93c219b9d..f36620c033b7e 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/edit_tags.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/edit_tags.test.tsx @@ -25,7 +25,8 @@ const defaultProps: EditTagsProps = { tags: [], }; -describe('EditTags ', () => { +// FLAKY: https://github.com/elastic/kibana/issues/175655 +describe.skip('EditTags ', () => { let appMockRender: AppMockRenderer; const sampleTags = ['coke', 'pepsi']; From d696e91f97ef5b5aefebfebb407f00e7bbe0d515 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Fri, 9 Feb 2024 19:57:28 +0200 Subject: [PATCH 093/104] [Cases] Persist the cases table state on the URL (#175237) ## Summary This PR persists the whole state of the cases table in the URL. Specifically: - The format of the URL changed. The Rison format will be used which is widely used in Kibana. - The old format will be supported to support BWC. - All filters are persisted in the URL including custom fields. - The URL is the source of truth and it takes precedence over everything. - The state is also persisted in the local storage. The state from the local storage is loaded only when the URL is empty. - The state in the local storage is stored under a new key called `cases.list.state`. The old key will not be taken into account. - Navigate through pages and back to the cases table do not lose the state of the table. - ## Testing - Test that the filtering is working as expected with all possible filters and values. - Test that the URL is updating correctly as you change the filters and the pagination. - Test that submitting a URL takes priority over the state persisted in the local storage. - Test that submitting a URL changes the filters and the pagination as expected. - Test that submitting a URL makes any hidden filters visible. - Test that legacy URLs are working as expected. - Put malformed values and keys in the URL and see how the application behaves. - Test that the extra query params put by the Security solution persisted and do not affect the cases filtering. - Test that the configuration of the filters (which ones are visible and which ones are hidden) is not affected. - Hide all filters and put a URL that contains all filters. They should be shown. - Remove the local storage state and check how the application behaves when you enter a URL with filters - Ensure that when you navigate between pages your filtering is persisted. - Ensure that the state from the local storage is loaded when you enter a URL without query parameters. - No assignees filtering is working. - Passing non-existing custom fields on the URL does not lead to an error. - Paste a URL that is not the same as the state in the local storage, navigate to a case, and come back to the cases table. The filters set by the URL should be the same. Blocked by: https://github.com/elastic/kibana/pull/176546 Flaky test runner: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5114, https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5119 ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [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 - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ## Release notes Persist all filter options of the cases table, including custom fields, in the URL. The filtering also persists when navigating back and forth between pages. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/cases/common/constants/index.ts | 3 +- x-pack/plugins/cases/common/ui/types.ts | 18 +- .../all_cases/all_cases_list.test.tsx | 24 +- .../components/all_cases/all_cases_list.tsx | 43 +- .../public/components/all_cases/constants.ts | 18 + .../all_cases/multi_select_filter.test.tsx | 7 + .../all_cases/multi_select_filter.tsx | 7 +- .../components/all_cases/schema.test.ts | 96 +++ .../public/components/all_cases/schema.ts | 46 ++ .../components/all_cases/search.test.tsx | 72 ++ .../public/components/all_cases/search.tsx | 49 ++ .../components/all_cases/severity_filter.tsx | 1 + .../components/all_cases/solution_filter.tsx | 1 + .../components/all_cases/status_filter.tsx | 1 + .../public/components/all_cases/table.tsx | 21 +- .../more_filters_selectable.tsx | 3 + .../use_custom_fields_filter_config.tsx | 21 +- .../use_filter_config.test.tsx | 101 ++- .../table_filter_config/use_filter_config.tsx | 38 +- .../use_system_filter_config.tsx | 2 + .../all_cases/table_filters.test.tsx | 293 ++++--- .../components/all_cases/table_filters.tsx | 57 +- .../components/all_cases/translations.ts | 9 +- .../public/components/all_cases/types.ts | 24 +- .../all_cases/use_all_cases_state.test.tsx | 761 ++++++++++++++---- .../all_cases/use_all_cases_state.tsx | 382 ++++----- .../all_cases/use_cases_columns_selection.tsx | 2 +- .../components/all_cases/utility_bar.test.tsx | 131 +-- .../components/all_cases/utility_bar.tsx | 18 + .../all_cases_url_state_deserializer.test.ts | 217 +++++ .../utils/all_cases_url_state_deserializer.ts | 85 ++ .../all_cases_url_state_serializer.test.ts | 119 +++ .../utils/all_cases_url_state_serializer.ts | 53 ++ .../components/all_cases/utils/index.test.ts | 66 ++ .../components/all_cases/utils/index.ts | 76 +- ...rge_selected_columns_with_configuration.ts | 52 ++ .../all_cases/utils/parse_url_params.test.tsx | 254 ++++++ .../all_cases/utils/parse_url_params.tsx | 129 +++ .../parse_url_with_filter_options.test.tsx | 56 -- .../utils/parse_url_with_filter_options.tsx | 42 - .../utils/sanitize_filter_options.test.tsx | 46 -- .../utils/sanitize_filter_options.tsx | 37 - .../all_cases/utils/sanitize_state.test.ts | 55 ++ .../all_cases/utils/sanitize_state.ts | 78 ++ .../utils/serialize_url_params.test.tsx | 77 -- .../all_cases/utils/serialize_url_params.tsx | 27 - .../utils/stringify_url_params.test.tsx | 131 +++ .../all_cases/utils/stringify_url_params.tsx | 35 + .../components/all_cases/utils/utils.test.tsx | 71 -- .../plugins/cases/public/components/utils.ts | 1 + .../cases/public/containers/constants.ts | 7 + x-pack/plugins/cases/tsconfig.json | 1 + .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - x-pack/test/functional/services/cases/list.ts | 68 ++ .../functional/services/cases/navigation.ts | 8 +- .../apps/cases/group2/list_view.ts | 288 ++++++- 58 files changed, 3228 insertions(+), 1103 deletions(-) create mode 100644 x-pack/plugins/cases/public/components/all_cases/constants.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/schema.test.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/schema.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/search.test.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/search.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.test.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.test.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/index.test.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/merge_selected_columns_with_configuration.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.test.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.test.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.test.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.test.ts create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.ts delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.test.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.test.tsx create mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.tsx delete mode 100644 x-pack/plugins/cases/public/components/all_cases/utils/utils.test.tsx diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index 50dda0c185176..b4a21607a293c 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -201,10 +201,9 @@ export const SEARCH_DEBOUNCE_MS = 500; * Local storage keys */ export const LOCAL_STORAGE_KEYS = { - casesQueryParams: 'cases.list.queryParams', - casesFilterOptions: 'cases.list.filterOptions', casesTableColumns: 'cases.list.tableColumns', casesTableFiltersConfig: 'cases.list.tableFiltersConfig', + casesTableState: 'cases.list.state', }; /** diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index 2ab04f058179d..a6e747ac6e85b 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -137,18 +137,6 @@ export interface QueryParams extends SortingParams { page: number; perPage: number; } -export type PartialQueryParams = Partial<QueryParams>; - -export interface UrlQueryParams extends SortingParams { - page: string; - perPage: string; -} - -export interface ParsedUrlQueryParams extends Partial<UrlQueryParams> { - [index: string]: string | string[] | undefined | null; -} - -export type LocalStorageQueryParams = Partial<Omit<QueryParams, 'page'>>; export interface SystemFilterOptions { search: string; @@ -171,11 +159,13 @@ export interface FilterOptions extends SystemFilterOptions { }; } -export type PartialFilterOptions = Partial<FilterOptions>; - export type SingleCaseMetrics = SingleCaseMetricsResponse; export type SingleCaseMetricsFeature = Exclude<CaseMetricsFeature, CaseMetricsFeature.MTTR>; +/** + * If you add a new value here and you want to support it on the URL + * you have to also add it here x-pack/plugins/cases/public/components/all_cases/schema.ts + */ export enum SortFieldCase { closedAt = 'closedAt', createdAt = 'createdAt', diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx index 028849f48fdb4..6e96596a41ab9 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx @@ -39,7 +39,11 @@ import { useGetTags } from '../../containers/use_get_tags'; import { useGetCategories } from '../../containers/use_get_categories'; import { useUpdateCase } from '../../containers/use_update_case'; import { useGetCases } from '../../containers/use_get_cases'; -import { DEFAULT_QUERY_PARAMS, DEFAULT_FILTER_OPTIONS } from '../../containers/constants'; +import { + DEFAULT_QUERY_PARAMS, + DEFAULT_FILTER_OPTIONS, + DEFAULT_CASES_TABLE_STATE, +} from '../../containers/constants'; import { useGetCurrentUserProfile } from '../../containers/user_profiles/use_get_current_user_profile'; import { userProfiles, userProfilesMap } from '../../containers/user_profiles/api.mock'; import { useBulkGetUserProfiles } from '../../containers/user_profiles/use_bulk_get_user_profiles'; @@ -202,7 +206,9 @@ describe('AllCasesListGeneric', () => { expect(screen.getByTestId('case-table-case-count')).toHaveTextContent( `Showing 10 of ${useGetCasesMockState.data.total} cases` ); + expect(screen.queryByTestId('all-cases-maximum-limit-warning')).not.toBeInTheDocument(); + expect(screen.queryByTestId('all-cases-clear-filters-link-icon')).not.toBeInTheDocument(); }); }); @@ -643,6 +649,22 @@ describe('AllCasesListGeneric', () => { expect(alertCounts.length).toBeGreaterThan(0); }); + it('should clear the filters correctly', async () => { + useLicenseMock.mockReturnValue({ isAtLeastPlatinum: () => true }); + + appMockRenderer.render(<AllCasesList />); + + userEvent.click(await screen.findByTestId('options-filter-popover-button-category')); + await waitForEuiPopoverOpen(); + userEvent.click(await screen.findByTestId('options-filter-popover-item-twix')); + + userEvent.click(await screen.findByTestId('all-cases-clear-filters-link-icon')); + + await waitFor(() => { + expect(useGetCasesMock).toHaveBeenLastCalledWith(DEFAULT_CASES_TABLE_STATE); + }); + }); + describe('Solutions', () => { it('should hide the solutions filter if the owner is provided', async () => { const { queryByTestId } = render( diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.tsx index 735ff95a5edf7..ea4810b5a8db3 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.tsx @@ -8,18 +8,17 @@ import React, { useCallback, useMemo, useState } from 'react'; import type { EuiTableSelectionType } from '@elastic/eui'; import { EuiProgress } from '@elastic/eui'; -import { difference, head, isEmpty } from 'lodash/fp'; import styled, { css } from 'styled-components'; +import deepEqual from 'react-fast-compare'; import type { CaseUI, FilterOptions, CasesUI } from '../../../common/ui/types'; import type { EuiBasicTableOnChange } from './types'; import { SortFieldCase } from '../../../common/ui/types'; import type { CaseStatuses } from '../../../common/types/domain'; -import { caseStatuses } from '../../../common/types/domain'; import { useCasesColumns } from './use_cases_columns'; import { CasesTableFilters } from './table_filters'; -import { CASES_TABLE_PERPAGE_VALUES } from './types'; +import { CASES_TABLE_PER_PAGE_VALUES } from './types'; import { CasesTable } from './table'; import { useCasesContext } from '../cases_context/use_cases_context'; import { CasesMetrics } from './cases_metrics'; @@ -32,6 +31,8 @@ import { useIsLoadingCases } from './use_is_loading_cases'; import { useAllCasesState } from './use_all_cases_state'; import { useAvailableCasesOwners } from '../app/use_available_owners'; import { useCasesColumnsSelection } from './use_cases_columns_selection'; +import { DEFAULT_CASES_TABLE_STATE } from '../../containers/constants'; +import { CasesTableUtilityBar } from './utility_bar'; const ProgressLoader = styled(EuiProgress)` ${({ $isShow }: { $isShow: boolean }) => @@ -64,15 +65,9 @@ export const AllCasesList = React.memo<AllCasesListProps>( const hasOwner = !!owner.length; - const firstAvailableStatus = head(difference(caseStatuses, hiddenStatuses)); - const initialFilterOptions = { - ...(!isEmpty(hiddenStatuses) && firstAvailableStatus && { status: [firstAvailableStatus] }), - }; + const { queryParams, setQueryParams, filterOptions, setFilterOptions } = + useAllCasesState(isSelectorView); - const { queryParams, setQueryParams, filterOptions, setFilterOptions } = useAllCasesState( - isSelectorView, - initialFilterOptions - ); const [selectedCases, setSelectedCases] = useState<CasesUI>([]); const { data = initialData, isFetching: isLoadingCases } = useGetCases({ @@ -164,7 +159,7 @@ export const AllCasesList = React.memo<AllCasesListProps>( pageIndex: queryParams.page - 1, pageSize: queryParams.perPage, totalItemCount: data.total ?? 0, - pageSizeOptions: CASES_TABLE_PERPAGE_VALUES, + pageSizeOptions: CASES_TABLE_PER_PAGE_VALUES, }), [data, queryParams] ); @@ -190,6 +185,15 @@ export const AllCasesList = React.memo<AllCasesListProps>( onRowClick?.(undefined, true); }, [onRowClick]); + const onClearFilters = useCallback(() => { + setFilterOptions(DEFAULT_CASES_TABLE_STATE.filterOptions); + }, [setFilterOptions]); + + const showClearFiltersButton = !deepEqual( + DEFAULT_CASES_TABLE_STATE.filterOptions, + filterOptions + ); + return ( <> <ProgressLoader @@ -212,6 +216,17 @@ export const AllCasesList = React.memo<AllCasesListProps>( currentUserProfile={currentUserProfile} filterOptions={filterOptions} /> + <CasesTableUtilityBar + pagination={pagination} + isSelectorView={isSelectorView} + totalCases={data.total ?? 0} + selectedCases={selectedCases} + deselectCases={deselectCases} + selectedColumns={selectedColumns} + onSelectedColumnsChange={setSelectedColumns} + onClearFilters={onClearFilters} + showClearFiltersButton={showClearFiltersButton} + /> <CasesTable columns={columns} data={data} @@ -223,13 +238,9 @@ export const AllCasesList = React.memo<AllCasesListProps>( isSelectorView={isSelectorView} onChange={tableOnChangeCallback} pagination={pagination} - selectedCases={selectedCases} selection={euiBasicTableSelectionProps} sorting={sorting} tableRowProps={tableRowProps} - deselectCases={deselectCases} - selectedColumns={selectedColumns} - onSelectedColumnsChange={setSelectedColumns} /> </> ); diff --git a/x-pack/plugins/cases/public/components/all_cases/constants.ts b/x-pack/plugins/cases/public/components/all_cases/constants.ts new file mode 100644 index 0000000000000..d55a1c4810f35 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/constants.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const CUSTOM_FIELD_KEY_PREFIX = 'cf_'; +export const ALL_CASES_STATE_URL_KEY = 'cases'; + +export const LEGACY_SUPPORTED_STATE_KEYS = [ + 'status', + 'severity', + 'page', + 'perPage', + 'sortField', + 'sortOrder', +] as const; diff --git a/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.test.tsx b/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.test.tsx index 5210e3d52e215..50ea3a82974bf 100644 --- a/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.test.tsx @@ -23,6 +23,7 @@ describe('multi select filter', () => { { label: 'tag d', key: 'tag d' }, ], onChange, + isLoading: false, }; render(<MultiSelectFilter {...props} />); @@ -46,6 +47,7 @@ describe('multi select filter', () => { selectedOptionKeys: ['tag a'], limit: 1, limitReachedMessage: 'Limit reached', + isLoading: false, }; const { rerender } = render(<MultiSelectFilter {...props} />); @@ -76,6 +78,7 @@ describe('multi select filter', () => { selectedOptionKeys: ['tag a'], limit: 2, limitReachedMessage: 'Limit reached', + isLoading: false, }; const { rerender } = render(<MultiSelectFilter {...props} />); @@ -109,6 +112,7 @@ describe('multi select filter', () => { selectedOptionKeys: ['tag a'], limit: 1, limitReachedMessage: 'Limit reached', + isLoading: false, }; render(<MultiSelectFilter {...props} />); @@ -134,6 +138,7 @@ describe('multi select filter', () => { ], onChange, selectedOptionKeys: ['tag b'], + isLoading: false, }; const { rerender } = render(<MultiSelectFilter {...props} />); @@ -154,6 +159,7 @@ describe('multi select filter', () => { ], onChange, renderOption, + isLoading: false, }; render(<MultiSelectFilter {...props} />); @@ -173,6 +179,7 @@ describe('multi select filter', () => { ], onChange, selectedOptionKeys: ['tag b'], + isLoading: false, }; const { rerender } = render(<MultiSelectFilter {...props} />); diff --git a/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.tsx b/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.tsx index b56c926bab965..080fe6df352c7 100644 --- a/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/multi_select_filter.tsx @@ -76,6 +76,7 @@ interface UseFilterParams<T extends string, K extends string = string> { renderOption?: (option: FilterOption<T, K>) => React.ReactNode; selectedOptionKeys?: string[]; transparentBackground?: boolean; + isLoading: boolean; } export const MultiSelectFilter = <T extends string, K extends string = string>({ buttonLabel, @@ -89,6 +90,7 @@ export const MultiSelectFilter = <T extends string, K extends string = string>({ selectedOptionKeys = [], renderOption, transparentBackground, + isLoading, }: UseFilterParams<T, K>) => { const { euiTheme } = useEuiTheme(); const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -101,13 +103,14 @@ export const MultiSelectFilter = <T extends string, K extends string = string>({ const newSelectedOptions = selectedOptionKeys.filter((selectedOptionKey) => rawOptions.some(({ key: optionKey }) => optionKey === selectedOptionKey) ); - if (!isEqual(newSelectedOptions, selectedOptionKeys)) { + + if (!isEqual(newSelectedOptions, selectedOptionKeys) && !isLoading) { onChange({ filterId: id, selectedOptionKeys: newSelectedOptions, }); } - }, [selectedOptionKeys, rawOptions, id, onChange]); + }, [selectedOptionKeys, rawOptions, id, onChange, isLoading]); const _onChange = (newOptions: Array<FilterOption<T, K>>) => { const newSelectedOptions = getEuiSelectableCheckedOptions(newOptions); diff --git a/x-pack/plugins/cases/public/components/all_cases/schema.test.ts b/x-pack/plugins/cases/public/components/all_cases/schema.test.ts new file mode 100644 index 0000000000000..bdf6e627131f8 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/schema.test.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 { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; +import { omit, pick } from 'lodash'; +import { DEFAULT_CASES_TABLE_STATE } from '../../containers/constants'; +import { AllCasesURLQueryParamsRt, validateSchema } from './schema'; + +describe('Schema', () => { + const supportedFilterOptions = pick(DEFAULT_CASES_TABLE_STATE.filterOptions, [ + 'search', + 'severity', + 'status', + 'tags', + 'assignees', + 'category', + ]); + + const defaultState = { + ...supportedFilterOptions, + ...DEFAULT_CASES_TABLE_STATE.queryParams, + }; + + describe('AllCasesURLQueryParamsRt', () => { + it('decodes correctly with defaults', () => { + const [params, errors] = validateNonExact(defaultState, AllCasesURLQueryParamsRt); + + expect(params).toEqual(defaultState); + expect(errors).toEqual(null); + }); + + it('decodes correctly with values', () => { + const state = { + assignees: ['elastic'], + tags: ['a', 'b'], + category: ['my category'], + status: ['open'], + search: 'My title', + severity: ['high'], + customFields: { my_field: ['one', 'two'] }, + sortOrder: 'asc', + sortField: 'updatedAt', + page: 5, + perPage: 20, + }; + + const [params, errors] = validateNonExact(state, AllCasesURLQueryParamsRt); + + expect(params).toEqual(state); + expect(errors).toEqual(null); + }); + + it('does not throws an error when missing fields', () => { + for (const [key] of Object.entries(defaultState)) { + const stateWithoutKey = omit(defaultState, key); + const [params, errors] = validateNonExact(stateWithoutKey, AllCasesURLQueryParamsRt); + + expect(params).toEqual(stateWithoutKey); + expect(errors).toEqual(null); + } + }); + + it('removes unknown properties', () => { + const [params, errors] = validateNonExact({ page: 10, foo: 'bar' }, AllCasesURLQueryParamsRt); + + expect(params).toEqual({ page: 10 }); + expect(errors).toEqual(null); + }); + + it.each(['status', 'severity', 'sortOrder', 'sortField', 'page', 'perPage'])( + 'throws if %s has invalid value', + (key) => { + const [params, errors] = validateNonExact({ [key]: 'foo' }, AllCasesURLQueryParamsRt); + + expect(params).toEqual(null); + expect(errors).toEqual(`Invalid value "foo" supplied to "${key}"`); + } + ); + }); + + describe('validateSchema', () => { + it('validates schema correctly', () => { + const params = validateSchema(defaultState, AllCasesURLQueryParamsRt); + expect(params).toEqual(defaultState); + }); + + it('throws an error if the schema is not valid', () => { + const params = validateSchema({ severity: 'foo' }, AllCasesURLQueryParamsRt); + expect(params).toEqual(null); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/schema.ts b/x-pack/plugins/cases/public/components/all_cases/schema.ts new file mode 100644 index 0000000000000..75f8e2be12dd4 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/schema.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isLeft } from 'fp-ts/lib/Either'; +import * as rt from 'io-ts'; +import { CaseSeverityRt, CaseStatusRt } from '../../../common/types/domain'; + +export const AllCasesURLQueryParamsRt = rt.exact( + rt.partial({ + search: rt.string, + severity: rt.array(CaseSeverityRt), + status: rt.array(CaseStatusRt), + tags: rt.array(rt.string), + category: rt.array(rt.string), + assignees: rt.array(rt.union([rt.string, rt.null])), + customFields: rt.record(rt.string, rt.array(rt.string)), + sortOrder: rt.union([rt.literal('asc'), rt.literal('desc')]), + sortField: rt.union([ + rt.literal('closedAt'), + rt.literal('createdAt'), + rt.literal('updatedAt'), + rt.literal('severity'), + rt.literal('status'), + rt.literal('title'), + rt.literal('category'), + ]), + page: rt.number, + perPage: rt.number, + }) +); + +export const validateSchema = <T extends rt.Mixed>( + obj: unknown, + schema: T +): rt.TypeOf<T> | null => { + const decoded = schema.decode(obj); + if (isLeft(decoded)) { + return null; + } else { + return decoded.right; + } +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/search.test.tsx b/x-pack/plugins/cases/public/components/all_cases/search.test.tsx new file mode 100644 index 0000000000000..8ea775e5e10a6 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/search.test.tsx @@ -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. + */ + +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { screen } from '@testing-library/react'; +import type { AppMockRenderer } from '../../common/mock'; +import { createAppMockRenderer } from '../../common/mock'; +import { TableSearch } from './search'; + +describe('TableSearch', () => { + const onFilterOptionsChange = jest.fn(); + + let appMockRender: AppMockRenderer; + + beforeEach(() => { + appMockRender = createAppMockRenderer(); + jest.clearAllMocks(); + }); + + it('renders with empty value correctly', async () => { + appMockRender.render( + <TableSearch filterOptionsSearch="" onFilterOptionsChange={onFilterOptionsChange} /> + ); + + await screen.findByDisplayValue(''); + }); + + it('renders with initial value correctly', async () => { + appMockRender.render( + <TableSearch filterOptionsSearch="My search" onFilterOptionsChange={onFilterOptionsChange} /> + ); + + await screen.findByDisplayValue('My search'); + }); + + it('calls onFilterOptionsChange correctly', async () => { + appMockRender.render( + <TableSearch filterOptionsSearch="" onFilterOptionsChange={onFilterOptionsChange} /> + ); + + userEvent.type(await screen.findByTestId('search-cases'), 'My search{enter}'); + + expect(onFilterOptionsChange).toHaveBeenCalledWith({ search: 'My search' }); + }); + + it('calls onFilterOptionsChange if the search term is empty', async () => { + appMockRender.render( + <TableSearch filterOptionsSearch="" onFilterOptionsChange={onFilterOptionsChange} /> + ); + + userEvent.type(await screen.findByTestId('search-cases'), ' {enter}'); + + expect(onFilterOptionsChange).toHaveBeenCalledWith({ search: '' }); + }); + + it('calls onFilterOptionsChange when clearing the search bar', async () => { + appMockRender.render( + <TableSearch filterOptionsSearch="My search" onFilterOptionsChange={onFilterOptionsChange} /> + ); + + await screen.findByDisplayValue('My search'); + + userEvent.click(await screen.findByTestId('clearSearchButton')); + + expect(onFilterOptionsChange).toHaveBeenCalledWith({ search: '' }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/search.tsx b/x-pack/plugins/cases/public/components/all_cases/search.tsx new file mode 100644 index 0000000000000..265c42470cdbd --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/search.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFieldSearch } from '@elastic/eui'; +import React, { useCallback, useState } from 'react'; +import * as i18n from './translations'; +import type { FilterOptions } from '../../containers/types'; + +interface TableSearchComponentProps { + filterOptionsSearch: string; + onFilterOptionsChange: (filterOptions: Partial<FilterOptions>) => void; +} + +const TableSearchComponent: React.FC<TableSearchComponentProps> = ({ + filterOptionsSearch, + onFilterOptionsChange, +}) => { + const [search, setSearch] = useState(filterOptionsSearch); + + const onSearch = useCallback( + (newSearch) => { + const trimSearch = newSearch.trim(); + setSearch(trimSearch); + onFilterOptionsChange({ search: trimSearch }); + }, + [onFilterOptionsChange] + ); + + return ( + <EuiFieldSearch + aria-label={i18n.SEARCH_CASES} + data-test-subj="search-cases" + fullWidth + incremental={false} + placeholder={i18n.SEARCH_PLACEHOLDER} + onChange={(e) => setSearch(e.target.value)} + onSearch={onSearch} + value={search} + /> + ); +}; + +TableSearchComponent.displayName = 'TableSearchComponent'; + +export const TableSearch = React.memo(TableSearchComponent); diff --git a/x-pack/plugins/cases/public/components/all_cases/severity_filter.tsx b/x-pack/plugins/cases/public/components/all_cases/severity_filter.tsx index 650e5215c6aac..dbc7bdef31c2a 100644 --- a/x-pack/plugins/cases/public/components/all_cases/severity_filter.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/severity_filter.tsx @@ -40,6 +40,7 @@ export const SeverityFilter: React.FC<Props> = ({ selectedOptionKeys, onChange } options={options} renderOption={renderOption} selectedOptionKeys={selectedOptionKeys} + isLoading={false} /> ); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/solution_filter.tsx b/x-pack/plugins/cases/public/components/all_cases/solution_filter.tsx index f2002e4c7899b..39e024161144f 100644 --- a/x-pack/plugins/cases/public/components/all_cases/solution_filter.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/solution_filter.tsx @@ -63,6 +63,7 @@ export const SolutionFilterComponent = ({ options={options} renderOption={renderOption} selectedOptionKeys={selectedOptionKeys} + isLoading={false} /> ); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/status_filter.tsx b/x-pack/plugins/cases/public/components/all_cases/status_filter.tsx index cc4b032f96c71..6e665a3c19236 100644 --- a/x-pack/plugins/cases/public/components/all_cases/status_filter.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/status_filter.tsx @@ -73,6 +73,7 @@ export const StatusFilterComponent = ({ options={options} renderOption={renderOption} selectedOptionKeys={selectedOptionKeys} + isLoading={false} /> ); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/table.tsx b/x-pack/plugins/cases/public/components/all_cases/table.tsx index edd7ab7e9955b..b3a943a2c31d9 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table.tsx @@ -12,11 +12,9 @@ import { EuiEmptyPrompt, EuiSkeletonText, EuiBasicTable } from '@elastic/eui'; import classnames from 'classnames'; import styled from 'styled-components'; -import { CasesTableUtilityBar } from './utility_bar'; import { LinkButton } from '../links'; -import type { CasesFindResponseUI, CasesUI, CaseUI } from '../../../common/ui/types'; -import type { CasesColumnSelection } from './types'; +import type { CasesFindResponseUI, CaseUI } from '../../../common/ui/types'; import * as i18n from './translations'; import { useCreateCaseNavigation } from '../../common/navigation'; @@ -32,14 +30,10 @@ interface CasesTableProps { isSelectorView?: boolean; onChange: EuiBasicTableProps<CaseUI>['onChange']; pagination: Pagination; - selectedCases: CasesUI; selection: EuiTableSelectionType<CaseUI>; sorting: EuiBasicTableProps<CaseUI>['sorting']; tableRef?: MutableRefObject<EuiBasicTable | null>; tableRowProps: EuiBasicTableProps<CaseUI>['rowProps']; - deselectCases: () => void; - selectedColumns: CasesColumnSelection[]; - onSelectedColumnsChange: (columns: CasesColumnSelection[]) => void; isLoadingColumns: boolean; } @@ -57,14 +51,10 @@ export const CasesTable: FunctionComponent<CasesTableProps> = ({ isSelectorView, onChange, pagination, - selectedCases, selection, sorting, tableRef, tableRowProps, - deselectCases, - selectedColumns, - onSelectedColumnsChange, isLoadingColumns, }) => { const { permissions } = useCasesContext(); @@ -87,15 +77,6 @@ export const CasesTable: FunctionComponent<CasesTableProps> = ({ </Div> ) : ( <> - <CasesTableUtilityBar - pagination={pagination} - isSelectorView={isSelectorView} - totalCases={data.total ?? 0} - selectedCases={selectedCases} - deselectCases={deselectCases} - selectedColumns={selectedColumns} - onSelectedColumnsChange={onSelectedColumnsChange} - /> <EuiBasicTable className={classnames({ isSelectorView })} columns={columns} diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/more_filters_selectable.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/more_filters_selectable.tsx index d191b339a05aa..a3ccd976199a0 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/more_filters_selectable.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/more_filters_selectable.tsx @@ -13,9 +13,11 @@ export const MoreFiltersSelectable = ({ options, activeFilters, onChange, + isLoading, }: { options: Array<MultiSelectFilterOption<string>>; activeFilters: string[]; + isLoading: boolean; onChange: (params: { filterId: string; selectedOptionKeys: string[] }) => void; }) => { return ( @@ -28,6 +30,7 @@ export const MoreFiltersSelectable = ({ options={options} selectedOptionKeys={activeFilters} transparentBackground={true} + isLoading={isLoading} /> ); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_custom_fields_filter_config.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_custom_fields_filter_config.tsx index 6901bca807319..ed5fa48838602 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_custom_fields_filter_config.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_custom_fields_filter_config.tsx @@ -6,13 +6,12 @@ */ import React from 'react'; +import type { CasesConfigurationUI } from '../../../../common/ui'; import type { CustomFieldTypes } from '../../../../common/types/domain'; import { builderMap as customFieldsBuilder } from '../../custom_fields/builder'; -import { useGetCaseConfiguration } from '../../../containers/configure/use_get_case_configuration'; import type { FilterChangeHandler, FilterConfig, FilterConfigRenderParams } from './types'; import { MultiSelectFilter } from '../multi_select_filter'; - -export const CUSTOM_FIELD_KEY_PREFIX = 'cf_'; +import { deflattenCustomFieldKey, flattenCustomFieldKey } from '../utils'; interface CustomFieldFilterOptionFactoryProps { buttonLabel: string; @@ -20,6 +19,7 @@ interface CustomFieldFilterOptionFactoryProps { fieldKey: string; onFilterOptionsChange: FilterChangeHandler; type: CustomFieldTypes; + isLoading: boolean; } const customFieldFilterOptionFactory = ({ buttonLabel, @@ -27,9 +27,10 @@ const customFieldFilterOptionFactory = ({ fieldKey, onFilterOptionsChange, type, + isLoading, }: CustomFieldFilterOptionFactoryProps) => { return { - key: `${CUSTOM_FIELD_KEY_PREFIX}${fieldKey}`, // this prefix is set in case custom field has the same key as a system field + key: flattenCustomFieldKey(fieldKey), // this prefix is set in case custom field has the same key as a system field isActive: false, isAvailable: true, label: buttonLabel, @@ -53,7 +54,7 @@ const customFieldFilterOptionFactory = ({ }) => { onFilterOptionsChange({ customFields: { - [filterId.replace(CUSTOM_FIELD_KEY_PREFIX, '')]: { + [deflattenCustomFieldKey(filterId)]: { options: selectedOptionKeys, type, }, @@ -71,6 +72,7 @@ const customFieldFilterOptionFactory = ({ label: option.label, }))} selectedOptionKeys={filterOptions.customFields[fieldKey]?.options || []} + isLoading={isLoading} /> ); }, @@ -79,15 +81,15 @@ const customFieldFilterOptionFactory = ({ export const useCustomFieldsFilterConfig = ({ isSelectorView, + customFields, + isLoading, onFilterOptionsChange, }: { isSelectorView: boolean; + customFields: CasesConfigurationUI['customFields']; + isLoading: boolean; onFilterOptionsChange: FilterChangeHandler; }) => { - const { - data: { customFields }, - } = useGetCaseConfiguration(); - const customFieldsFilterConfig: FilterConfig[] = []; if (isSelectorView) { @@ -106,6 +108,7 @@ export const useCustomFieldsFilterConfig = ({ fieldKey, onFilterOptionsChange, type, + isLoading, }) ); } diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.test.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.test.tsx index 62dd688cae29a..25dd550a3ecf3 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.test.tsx @@ -9,17 +9,10 @@ import { renderHook } from '@testing-library/react-hooks'; import type { AppMockRenderer } from '../../../common/mock'; import { createAppMockRenderer } from '../../../common/mock'; import type { FilterConfig, FilterConfigRenderParams } from './types'; -import { getCaseConfigure } from '../../../containers/configure/api'; import { useFilterConfig } from './use_filter_config'; import type { FilterOptions } from '../../../../common/ui'; - -jest.mock('../../../containers/configure/api', () => { - const originalModule = jest.requireActual('../../../containers/configure/api'); - return { - ...originalModule, - getCaseConfigure: jest.fn(), - }; -}); +import { CUSTOM_FIELD_KEY_PREFIX } from '../constants'; +import { CustomFieldTypes } from '../../../../common/types/domain'; const emptyFilterOptions: FilterOptions = { search: '', @@ -33,9 +26,31 @@ const emptyFilterOptions: FilterOptions = { category: [], customFields: {}, }; -const getCaseConfigureMock = getCaseConfigure as jest.Mock; describe('useFilterConfig', () => { + const onFilterOptionsChange = jest.fn(); + const getEmptyOptions = jest.fn().mockReturnValue({ severity: [] }); + const filters: FilterConfig[] = [ + { + key: 'severity', + label: 'Severity', + isActive: true, + isAvailable: true, + getEmptyOptions, + render: ({ filterOptions }: FilterConfigRenderParams) => null, + }, + { + key: 'tags', + label: 'Tags', + isActive: true, + isAvailable: true, + getEmptyOptions() { + return { tags: ['initialValue'] }; + }, + render: ({ filterOptions }: FilterConfigRenderParams) => null, + }, + ]; + let appMockRender: AppMockRenderer; beforeEach(() => { @@ -48,32 +63,6 @@ describe('useFilterConfig', () => { }); it('should remove a selected option if the filter is deleted', async () => { - getCaseConfigureMock.mockReturnValue(() => { - return []; - }); - const onFilterOptionsChange = jest.fn(); - const getEmptyOptions = jest.fn().mockReturnValue({ severity: [] }); - const filters: FilterConfig[] = [ - { - key: 'severity', - label: 'Severity', - isActive: true, - isAvailable: true, - getEmptyOptions, - render: ({ filterOptions }: FilterConfigRenderParams) => null, - }, - { - key: 'tags', - label: 'Tags', - isActive: true, - isAvailable: true, - getEmptyOptions() { - return { tags: ['initialValue'] }; - }, - render: ({ filterOptions }: FilterConfigRenderParams) => null, - }, - ]; - const { rerender } = renderHook(useFilterConfig, { wrapper: ({ children }) => <appMockRender.AppWrapper>{children}</appMockRender.AppWrapper>, initialProps: { @@ -81,16 +70,22 @@ describe('useFilterConfig', () => { onFilterOptionsChange, isSelectorView: false, filterOptions: emptyFilterOptions, + customFields: [], + isLoading: false, }, }); expect(onFilterOptionsChange).not.toHaveBeenCalled(); + rerender({ systemFilterConfig: [], onFilterOptionsChange, isSelectorView: false, filterOptions: emptyFilterOptions, + customFields: [], + isLoading: false, }); + expect(getEmptyOptions).toHaveBeenCalledTimes(1); expect(onFilterOptionsChange).toHaveBeenCalledTimes(1); expect(onFilterOptionsChange).toHaveBeenCalledWith({ @@ -98,4 +93,38 @@ describe('useFilterConfig', () => { tags: ['initialValue'], }); }); + + it('should activate custom fields correctly when they are hidden', async () => { + const customFieldKey = 'toggleKey'; + const uiCustomFieldKey = `${CUSTOM_FIELD_KEY_PREFIX}${customFieldKey}`; + + localStorage.setItem( + 'testAppId.cases.list.tableFiltersConfig', + JSON.stringify([{ key: uiCustomFieldKey, isActive: false }]) + ); + + const { result } = renderHook(useFilterConfig, { + wrapper: ({ children }) => <appMockRender.AppWrapper>{children}</appMockRender.AppWrapper>, + initialProps: { + systemFilterConfig: filters, + onFilterOptionsChange, + isSelectorView: false, + filterOptions: { + ...emptyFilterOptions, + customFields: { [customFieldKey]: { type: CustomFieldTypes.TOGGLE, options: ['on'] } }, + }, + customFields: [ + { + key: customFieldKey, + type: CustomFieldTypes.TOGGLE, + required: false, + label: 'My toggle', + }, + ], + isLoading: false, + }, + }); + + expect(result.current.activeSelectableOptionKeys).toEqual([uiCustomFieldKey]); + }); }); diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.tsx index 8d721cd13daa7..6c342770a12f3 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_filter_config.tsx @@ -9,11 +9,12 @@ import type { SetStateAction } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import { merge, isEqual, isEmpty } from 'lodash'; -import type { FilterOptions } from '../../../../common/ui'; +import type { CasesConfigurationUI, FilterOptions } from '../../../../common/ui'; import { LOCAL_STORAGE_KEYS } from '../../../../common/constants'; import type { FilterConfig, FilterConfigState } from './types'; import { useCustomFieldsFilterConfig } from './use_custom_fields_filter_config'; import { useCasesContext } from '../../cases_context/use_cases_context'; +import { deflattenCustomFieldKey, isFlattenCustomField } from '../utils'; const mergeSystemAndCustomFieldConfigs = ({ systemFilterConfig, @@ -38,6 +39,13 @@ const shouldBeActive = ({ filter: FilterConfigState; filterOptions: FilterOptions; }) => { + if (isFlattenCustomField(filter.key)) { + return ( + !filter.isActive && + !isEmpty(filterOptions.customFields[deflattenCustomFieldKey(filter.key)]?.options) + ); + } + return !filter.isActive && !isEmpty(filterOptions[filter.key as keyof FilterOptions]); }; @@ -52,6 +60,7 @@ const useActiveByFilterKeyState = ({ filterOptions }: { filterOptions: FilterOpt * Activates filters that aren't active but have a value in the filterOptions */ const newActiveByFilterKey = [...(activeByFilterKey || [])]; + newActiveByFilterKey.forEach((filter) => { if (shouldBeActive({ filter, filterOptions })) { const currentIndex = newActiveByFilterKey.findIndex((_filter) => filter.key === _filter.key); @@ -98,25 +107,45 @@ export const useFilterConfig = ({ onFilterOptionsChange, systemFilterConfig, filterOptions, + customFields, + isLoading, }: { isSelectorView: boolean; + isLoading: boolean; onFilterOptionsChange: (params: Partial<FilterOptions>) => void; systemFilterConfig: FilterConfig[]; filterOptions: FilterOptions; + customFields: CasesConfigurationUI['customFields']; }) => { /** * Initially we won't save any order, it will use the default config as it is defined in the system. * Once the user adds/removes a filter, we start saving the order and the visible state. */ - const [activeByFilterKey, setActiveByFilterKey] = useActiveByFilterKeyState({ filterOptions }); + const [activeByFilterKey, setActiveByFilterKey] = useActiveByFilterKeyState({ + filterOptions, + }); + const { customFieldsFilterConfig } = useCustomFieldsFilterConfig({ isSelectorView, + customFields, + isLoading, onFilterOptionsChange, }); + const activeCustomFieldsConfig = customFieldsFilterConfig.map((customField) => { + return { + ...customField, + isActive: Object.entries(filterOptions.customFields).find( + ([key, _]) => key === deflattenCustomFieldKey(customField.key) + ) + ? true + : customField.isActive, + }; + }); + const filterConfigs = mergeSystemAndCustomFieldConfigs({ systemFilterConfig, - customFieldsFilterConfig, + customFieldsFilterConfig: activeCustomFieldsConfig, }); const prevFilterConfigs = usePrevious(filterConfigs) ?? new Map(); @@ -192,11 +221,14 @@ export const useFilterConfig = ({ if (a.label < b.label) return -1; return a.key > b.key ? 1 : -1; }); + const source = activeByFilterKey && activeByFilterKey.length > 0 ? activeByFilterKey : filterConfigArray; + const activeFilters = source .filter((filter) => filter.isActive && filterConfigs.has(filter.key)) .map((filter) => filterConfigs.get(filter.key)) as FilterConfig[]; + const activeFilterKeys = activeFilters.map((filter) => filter.key); return { diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_system_filter_config.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_system_filter_config.tsx index ba2ca2d5f363f..e186e5c990d06 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_system_filter_config.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filter_config/use_system_filter_config.tsx @@ -137,6 +137,7 @@ export const getSystemFilterConfig = ({ onChange={onSystemFilterChange} options={mapToMultiSelectOption(tags)} selectedOptionKeys={filterOptions?.tags} + isLoading={isLoading} /> ), }, @@ -159,6 +160,7 @@ export const getSystemFilterConfig = ({ onChange={onSystemFilterChange} options={mapToMultiSelectOption(categories)} selectedOptionKeys={filterOptions?.category} + isLoading={isLoading} /> ), }, diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filters.test.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filters.test.tsx index 0abed867a29b3..d407d03517b25 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filters.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filters.test.tsx @@ -17,30 +17,26 @@ import { SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER } from '../../../common/co import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer } from '../../common/mock'; import { DEFAULT_FILTER_OPTIONS } from '../../containers/constants'; +import type { CasesTableFiltersProps } from './table_filters'; import { CasesTableFilters } from './table_filters'; import { useGetTags } from '../../containers/use_get_tags'; import { useGetCategories } from '../../containers/use_get_categories'; import { useSuggestUserProfiles } from '../../containers/user_profiles/use_suggest_user_profiles'; import { userProfiles } from '../../containers/user_profiles/api.mock'; -import { getCaseConfigure } from '../../containers/configure/api'; -import { CUSTOM_FIELD_KEY_PREFIX } from './table_filter_config/use_custom_fields_filter_config'; +import { CUSTOM_FIELD_KEY_PREFIX } from './constants'; +import { useGetCaseConfiguration } from '../../containers/configure/use_get_case_configuration'; +import { useCaseConfigureResponse } from '../configure_cases/__mock__'; jest.mock('../../containers/use_get_tags'); jest.mock('../../containers/use_get_categories'); jest.mock('../../containers/user_profiles/use_suggest_user_profiles'); -jest.mock('../../containers/configure/api', () => { - const originalModule = jest.requireActual('../../containers/configure/api'); - return { - ...originalModule, - getCaseConfigure: jest.fn(), - }; -}); +jest.mock('../../containers/configure/use_get_case_configuration'); -const getCaseConfigureMock = getCaseConfigure as jest.Mock; +const useGetCaseConfigurationMock = useGetCaseConfiguration as jest.Mock; const onFilterChanged = jest.fn(); -const props = { +const props: CasesTableFiltersProps = { countClosedCases: 1234, countOpenCases: 99, countInProgressCases: 54, @@ -48,7 +44,6 @@ const props = { filterOptions: DEFAULT_FILTER_OPTIONS, availableSolutions: [], isLoading: false, - initialFilterOptions: DEFAULT_FILTER_OPTIONS, currentUserProfile: undefined, }; @@ -100,6 +95,8 @@ describe('CasesTableFilters ', () => { isLoading: false, }); (useSuggestUserProfiles as jest.Mock).mockReturnValue({ data: userProfiles, isLoading: false }); + + useGetCaseConfigurationMock.mockImplementation(() => useCaseConfigureResponse); }); afterEach(() => { @@ -107,22 +104,22 @@ describe('CasesTableFilters ', () => { window.localStorage.clear(); }); - it('should render the case status filter dropdown', () => { + it('should render the case status filter dropdown', async () => { appMockRender.render(<CasesTableFilters {...props} />); - expect(screen.getByTestId('options-filter-popover-button-status')).toBeInTheDocument(); + expect(await screen.findByTestId('options-filter-popover-button-status')).toBeInTheDocument(); }); - it('should render the case severity filter dropdown', () => { + it('should render the case severity filter dropdown', async () => { appMockRender.render(<CasesTableFilters {...props} />); - expect(screen.getByTestId('options-filter-popover-button-severity')).toBeTruthy(); + expect(await screen.findByTestId('options-filter-popover-button-severity')).toBeTruthy(); }); it('should call onFilterChange when the severity filter changes', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-severity')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-severity')); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-high')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-high')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, severity: ['high'] }); }); @@ -130,9 +127,9 @@ describe('CasesTableFilters ', () => { it('should call onFilterChange when selected tags change', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-tags')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-tags')); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-coke')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-coke')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, tags: ['coke'] }); }); @@ -140,9 +137,9 @@ describe('CasesTableFilters ', () => { it('should call onFilterChange when selected category changes', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-category')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-category')); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-twix')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-twix')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, category: ['twix'] }); }); @@ -184,17 +181,39 @@ describe('CasesTableFilters ', () => { it('should call onFilterChange when search changes', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.type(screen.getByTestId('search-cases'), 'My search{enter}'); + userEvent.type(await screen.findByTestId('search-cases'), 'My search{enter}'); + + await waitFor(() => { + expect(onFilterChanged.mock.calls[0][0].search).toEqual('My search'); + }); + }); + + it('should change the initial value of search when the state changes', async () => { + const { rerender } = appMockRender.render( + <CasesTableFilters + {...props} + filterOptions={{ ...props.filterOptions, search: 'My search' }} + /> + ); + + await screen.findByDisplayValue('My search'); + + rerender( + <CasesTableFilters + {...props} + filterOptions={{ ...props.filterOptions, search: 'My new search' }} + /> + ); - expect(onFilterChanged).toBeCalledWith({ search: 'My search' }); + await screen.findByDisplayValue('My new search'); }); it('should call onFilterChange when changing status', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-status')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-status')); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-closed')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-closed')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, @@ -205,10 +224,10 @@ describe('CasesTableFilters ', () => { it('should show in progress status only when "in p" is searched in the filter', async () => { appMockRender.render(<CasesTableFilters {...props} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-status')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-status')); await waitForEuiPopoverOpen(); - userEvent.type(screen.getByTestId('status-search-input'), 'in p'); + userEvent.type(await screen.findByTestId('status-search-input'), 'in p'); const allOptions = screen.getAllByRole('option'); expect(allOptions).toHaveLength(1); @@ -234,7 +253,7 @@ describe('CasesTableFilters ', () => { appMockRender = createAppMockRenderer({ license }); appMockRender.render(<CasesTableFilters {...overrideProps} />); - userEvent.click(screen.getByTestId('options-filter-popover-button-assignees')); + userEvent.click(await screen.findByTestId('options-filter-popover-button-assignees')); await waitForEuiPopoverOpen(); userEvent.click(screen.getByText('Physical Dinosaur')); @@ -261,7 +280,7 @@ describe('CasesTableFilters ', () => { }); describe('Solution filter', () => { - it('shows Solution filter when provided more than 1 availableSolutions', () => { + it('shows Solution filter when provided more than 1 availableSolutions', async () => { appMockRender = createAppMockRenderer({ owner: [SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER], }); @@ -271,7 +290,7 @@ describe('CasesTableFilters ', () => { availableSolutions={[SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER]} /> ); - expect(screen.getByTestId('options-filter-popover-button-owner')).toBeInTheDocument(); + expect(await screen.findByTestId('options-filter-popover-button-owner')).toBeInTheDocument(); }); it('does not show Solution filter when provided less than 1 availableSolutions', () => { @@ -282,7 +301,7 @@ describe('CasesTableFilters ', () => { expect(screen.queryByTestId('options-filter-popover-button-owner')).not.toBeInTheDocument(); }); - it('does not select a solution on initial render', () => { + it('does not select a solution on initial render', async () => { appMockRender = createAppMockRenderer({ owner: [SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER], }); @@ -293,7 +312,7 @@ describe('CasesTableFilters ', () => { /> ); - expect(screen.getByTestId('options-filter-popover-button-owner')).not.toHaveAttribute( + expect(await screen.findByTestId('options-filter-popover-button-owner')).not.toHaveAttribute( 'hasActiveFilters' ); }); @@ -375,10 +394,12 @@ describe('CasesTableFilters ', () => { appMockRender = createAppMockRenderer({ license }); appMockRender.render(<CasesTableFilters {...props} />); - expect(screen.getByTestId('options-filter-popover-button-assignees')).toBeInTheDocument(); + expect( + await screen.findByTestId('options-filter-popover-button-assignees') + ).toBeInTheDocument(); }); - it('shuld reset the assignees when deactivating the filter', async () => { + it('should reset the assignees when deactivating the filter', async () => { const overrideProps = { ...props, filterOptions: { @@ -411,7 +432,7 @@ describe('CasesTableFilters ', () => { expect(screen.queryByTestId('cases-table-add-case-filter-bar')).not.toBeInTheDocument(); }); - it('should render the create case button when isSelectorView is true and onCreateCasePressed are passed', () => { + it('should render the create case button when isSelectorView is true and onCreateCasePressed are passed', async () => { const onCreateCasePressed = jest.fn(); appMockRender.render( <CasesTableFilters @@ -420,7 +441,7 @@ describe('CasesTableFilters ', () => { onCreateCasePressed={onCreateCasePressed} /> ); - expect(screen.getByTestId('cases-table-add-case-filter-bar')).toBeInTheDocument(); + expect(await screen.findByTestId('cases-table-add-case-filter-bar')).toBeInTheDocument(); }); it('should call the onCreateCasePressed when create case is clicked', async () => { @@ -433,7 +454,7 @@ describe('CasesTableFilters ', () => { /> ); - userEvent.click(screen.getByTestId('cases-table-add-case-filter-bar')); + userEvent.click(await screen.findByTestId('cases-table-add-case-filter-bar')); await waitForComponentToUpdate(); // NOTE: intentionally checking no arguments are passed @@ -451,11 +472,14 @@ describe('CasesTableFilters ', () => { 'testAppId.cases.list.tableFiltersConfig', JSON.stringify(previousState) ); - getCaseConfigureMock.mockImplementation(() => { - return { + + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + data: { + ...useCaseConfigureResponse.data, customFields: [{ type: 'toggle', key: customFieldKey, label: 'Toggle', required: false }], - }; - }); + }, + })); }); afterEach(() => { @@ -481,7 +505,7 @@ describe('CasesTableFilters ', () => { userEvent.click(await screen.findByRole('button', { name: 'Toggle' })); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-on')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-on')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, @@ -500,7 +524,7 @@ describe('CasesTableFilters ', () => { userEvent.click(await screen.findByRole('button', { name: 'Toggle' })); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-off')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-off')); expect(onFilterChanged).toBeCalledWith({ ...DEFAULT_FILTER_OPTIONS, @@ -531,7 +555,7 @@ describe('CasesTableFilters ', () => { userEvent.click(await screen.findByRole('button', { name: 'Toggle' })); await waitForEuiPopoverOpen(); - userEvent.click(screen.getByTestId('options-filter-popover-item-off')); + userEvent.click(await screen.findByTestId('options-filter-popover-item-off')); expect(onFilterChanged).toHaveBeenCalledWith({ ...DEFAULT_FILTER_OPTIONS, @@ -581,21 +605,23 @@ describe('CasesTableFilters ', () => { describe('custom filters configuration', () => { beforeEach(() => { - getCaseConfigureMock.mockImplementation(() => { - return { + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + data: { + ...useCaseConfigureResponse.data, customFields: [ { type: 'toggle', key: 'toggle', label: 'Toggle', required: false }, { type: 'text', key: 'text', label: 'Text', required: false }, ], - }; - }); + }, + })); }); afterEach(() => { jest.clearAllMocks(); }); - it('shouldnt render the more button when in selector view', async () => { + it('should not render the more button when in selector view', async () => { appMockRender.render(<CasesTableFilters {...props} isSelectorView />); expect(screen.queryByRole('button', { name: 'More' })).not.toBeInTheDocument(); }); @@ -607,9 +633,9 @@ describe('CasesTableFilters ', () => { userEvent.click(screen.getByRole('button', { name: 'More' })); await waitFor(() => expect(screen.getAllByRole('option')).toHaveLength(5)); - expect(screen.getByTestId('options-filter-popover-item-status')).toBeInTheDocument(); + expect(await screen.findByTestId('options-filter-popover-item-status')).toBeInTheDocument(); expect( - screen.getByTestId(`options-filter-popover-item-${CUSTOM_FIELD_KEY_PREFIX}toggle`) + await screen.findByTestId(`options-filter-popover-item-${CUSTOM_FIELD_KEY_PREFIX}toggle`) ).toBeInTheDocument(); }); @@ -632,7 +658,7 @@ describe('CasesTableFilters ', () => { userEvent.click(screen.getByRole('option', { name: 'Toggle' })); expect(screen.getByRole('button', { name: 'Toggle' })).toBeInTheDocument(); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); const allFilters = within(filterBar).getAllByRole('button'); const orderedFilterLabels = ['Severity', 'Status', 'Tags', 'Categories', 'Toggle', 'More']; orderedFilterLabels.forEach((label, index) => { @@ -685,7 +711,7 @@ describe('CasesTableFilters ', () => { userEvent.click(screen.getByRole('option', { name: 'Status' })); expect(screen.queryByRole('button', { name: 'Status' })).not.toBeInTheDocument(); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); const allFilters = within(filterBar).getAllByRole('button'); const orderedFilterLabels = ['Severity', 'Tags', 'Categories', 'More']; orderedFilterLabels.forEach((label, index) => { @@ -764,6 +790,7 @@ describe('CasesTableFilters ', () => { { key: 'status', isActive: false }, { key: 'severity', isActive: true }, ]; + localStorage.setItem( 'testAppId.cases.list.tableFiltersConfig', JSON.stringify(previousState) @@ -771,7 +798,7 @@ describe('CasesTableFilters ', () => { appMockRender.render(<CasesTableFilters {...props} />); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); let allFilters: HTMLElement[]; await waitFor(() => { allFilters = within(filterBar).getAllByRole('button'); @@ -801,7 +828,7 @@ describe('CasesTableFilters ', () => { appMockRender.render(<CasesTableFilters {...props} />); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); let allFilters: HTMLElement[]; await waitFor(() => { allFilters = within(filterBar).getAllByRole('button'); @@ -815,8 +842,10 @@ describe('CasesTableFilters ', () => { }); it('should sort the labels shown in the popover (on equal label, sort by key)', async () => { - getCaseConfigureMock.mockImplementation(() => { - return { + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + data: { + ...useCaseConfigureResponse.data, customFields: [ { type: 'toggle', key: 'za', label: 'ZToggle', required: false }, { type: 'toggle', key: 'tc', label: 'Toggle', required: false }, @@ -824,8 +853,9 @@ describe('CasesTableFilters ', () => { { type: 'toggle', key: 'tb', label: 'Toggle', required: false }, { type: 'toggle', key: 'aa', label: 'AToggle', required: false }, ], - }; - }); + }, + })); + appMockRender.render(<CasesTableFilters {...props} />); userEvent.click(screen.getByRole('button', { name: 'More' })); @@ -851,10 +881,10 @@ describe('CasesTableFilters ', () => { }); }); - it('when a filter is active and isnt last in the list, it should move the filter to last position after deactivating and activating', async () => { + it('when a filter is active and is not last in the list, it should move the filter to last position after deactivating and activating', async () => { appMockRender.render(<CasesTableFilters {...props} />); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); let allFilters = within(filterBar).getAllByRole('button'); let orderedFilterLabels = ['Severity', 'Status', 'Tags', 'Categories', 'More']; orderedFilterLabels.forEach((label, index) => { @@ -876,17 +906,20 @@ describe('CasesTableFilters ', () => { }); it('should avoid key collisions between custom fields and default fields', async () => { - getCaseConfigureMock.mockImplementation(() => { - return { + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + data: { + ...useCaseConfigureResponse.data, customFields: [ { type: 'toggle', key: 'severity', label: 'Fake Severity', required: false }, { type: 'toggle', key: 'status', label: 'Fake Status', required: false }, ], - }; - }); + }, + })); + appMockRender.render(<CasesTableFilters {...props} />); - const filterBar = screen.getByTestId('cases-table-filters'); + const filterBar = await screen.findByTestId('cases-table-filters'); let allFilters: HTMLElement[]; await waitFor(() => { allFilters = within(filterBar).getAllByRole('button'); @@ -906,7 +939,7 @@ describe('CasesTableFilters ', () => { }); }); - it('should delete stored filters that dont exist anymore', async () => { + it('should delete stored filters that do not exist anymore', async () => { const previousState = [ { key: 'severity', isActive: true }, { key: 'status', isActive: false }, @@ -954,35 +987,111 @@ describe('CasesTableFilters ', () => { ] `); }); - }); - it('should activate a filter when there is a value in the global state as this means that it has a value set in the url', async () => { - const previousState = [ - { key: 'severity', isActive: false }, // notice severity filter not active - { key: 'status', isActive: false }, // notice status filter not active - { key: 'tags', isActive: true }, - { key: 'category', isActive: false }, - ]; + it('should activate all filters when there is a value in the global state and is not active in the local storage', async () => { + const license = licensingMock.createLicense({ + license: { type: 'platinum' }, + }); - localStorage.setItem('testAppId.cases.list.tableFiltersConfig', JSON.stringify(previousState)); + const previousState = [ + { key: 'severity', isActive: false }, // notice severity filter not active + { key: 'status', isActive: false }, // notice status filter not active + { key: 'tags', isActive: false }, + { key: 'category', isActive: false }, + { key: 'cf_toggle', isActive: false }, + { key: 'assignees', isActive: false }, + ]; - const overrideProps = { - ...props, - filterOptions: { - ...DEFAULT_FILTER_OPTIONS, - severity: [CaseSeverity.MEDIUM], // but they have values - status: [CaseStatuses.open, CaseStatuses['in-progress']], - }, - }; + localStorage.setItem( + 'testAppId.cases.list.tableFiltersConfig', + JSON.stringify(previousState) + ); - appMockRender.render(<CasesTableFilters {...overrideProps} />); + const overrideProps = { + ...props, + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + severity: [CaseSeverity.MEDIUM], // but they have values + status: [CaseStatuses.open, CaseStatuses['in-progress']], + tags: ['coke'], + category: ['twix'], + assignees: [userProfiles[0].uid], + customFields: { toggle: { type: CustomFieldTypes.TOGGLE, options: ['on'] } }, + }, + }; + + appMockRender = createAppMockRenderer({ license }); + appMockRender.render(<CasesTableFilters {...overrideProps} />); - const statusButton = await screen.findByRole('button', { name: 'Status' }); - expect(statusButton).toBeInTheDocument(); - expect(within(statusButton).getByLabelText('2 active filters')).toBeInTheDocument(); + const filters = [ + { name: 'Status', active: 2 }, + { name: 'Severity', active: 1 }, + { name: 'Tags', active: 1 }, + { name: 'Categories', active: 1 }, + { name: 'Toggle', active: 1 }, + { name: 'click to filter assignees', active: 1 }, + ]; + + await waitForComponentToUpdate(); + + const totalFilters = await screen.findAllByRole('button'); + // plus the more button + expect(totalFilters.length).toBe(filters.length + 1); + + for (const filter of filters) { + const button = await screen.findByRole('button', { name: filter.name }); + expect(button).toBeInTheDocument(); + expect( + await within(button).findByLabelText(`${filter.active} active filters`) + ).toBeInTheDocument(); + } + }); - const severityButton = await screen.findByRole('button', { name: 'Severity' }); - expect(severityButton).toBeInTheDocument(); - expect(within(severityButton).getByLabelText('1 active filters')).toBeInTheDocument(); + it('should activate all filters when there is a value in the global state and the local storage is empty', async () => { + const license = licensingMock.createLicense({ + license: { type: 'platinum' }, + }); + + localStorage.setItem('testAppId.cases.list.tableFiltersConfig', JSON.stringify([])); + + const overrideProps = { + ...props, + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + severity: [CaseSeverity.MEDIUM], // but they have values + status: [CaseStatuses.open, CaseStatuses['in-progress']], + tags: ['coke'], + category: ['twix'], + assignees: [userProfiles[0].uid], + customFields: { toggle: { type: CustomFieldTypes.TOGGLE, options: ['on'] } }, + }, + }; + + appMockRender = createAppMockRenderer({ license }); + appMockRender.render(<CasesTableFilters {...overrideProps} />); + + const filters = [ + { name: 'Status', active: 2 }, + { name: 'Severity', active: 1 }, + { name: 'Tags', active: 1 }, + { name: 'Categories', active: 1 }, + { name: 'Toggle', active: 1 }, + { name: 'click to filter assignees', active: 1 }, + ]; + + await waitForComponentToUpdate(); + + const totalFilters = await screen.findAllByRole('button'); + // plus the more button + expect(totalFilters.length).toBe(filters.length + 1); + + for (const filter of filters) { + const button = await screen.findByRole('button', { name: filter.name }); + expect(button).toBeInTheDocument(); + expect( + await within(button).findByLabelText(`${filter.active} active filters`) + ).toBeInTheDocument(); + } + }); }); }); diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx index dbdc947418eca..adece041c67ad 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import React, { useCallback, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiFieldSearch, EuiButton } from '@elastic/eui'; +import React, { useCallback } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; import { mergeWith, isEqual } from 'lodash'; import { MoreFiltersSelectable } from './table_filter_config/more_filters_selectable'; import type { CaseStatuses } from '../../../common/types/domain'; @@ -18,6 +18,8 @@ import type { CurrentUserProfile } from '../types'; import { useCasesFeatures } from '../../common/use_cases_features'; import { useSystemFilterConfig } from './table_filter_config/use_system_filter_config'; import { useFilterConfig } from './table_filter_config/use_filter_config'; +import { useGetCaseConfiguration } from '../../containers/configure/use_get_case_configuration'; +import { TableSearch } from './search'; export interface CasesTableFiltersProps { countClosedCases: number | null; @@ -52,10 +54,13 @@ const CasesTableFiltersComponent = ({ currentUserProfile, filterOptions, }: CasesTableFiltersProps) => { - const [search, setSearch] = useState(filterOptions.search); - const { data: tags = [] } = useGetTags(); - const { data: categories = [] } = useGetCategories(); + const { data: tags = [], isLoading: isLoadingTags } = useGetTags(); + const { data: categories = [], isLoading: isLoadingCategories } = useGetCategories(); const { caseAssignmentAuthorized } = useCasesFeatures(); + const { + data: { customFields }, + isFetching: isLoadingCasesConfiguration, + } = useGetCaseConfiguration(); const onFilterOptionsChange = useCallback( (partialFilterOptions: Partial<FilterOptions>) => { @@ -67,6 +72,9 @@ const CasesTableFiltersComponent = ({ [filterOptions, onFilterChanged] ); + const isLoadingFilters = + isLoading || isLoadingTags || isLoadingCategories || isLoadingCasesConfiguration; + const { systemFilterConfig } = useSystemFilterConfig({ availableSolutions, caseAssignmentAuthorized, @@ -76,7 +84,7 @@ const CasesTableFiltersComponent = ({ countOpenCases, currentUserProfile, hiddenStatuses, - isLoading, + isLoading: isLoadingFilters, isSelectorView, onFilterOptionsChange, tags, @@ -87,18 +95,14 @@ const CasesTableFiltersComponent = ({ selectableOptions, activeSelectableOptionKeys, onFilterConfigChange, - } = useFilterConfig({ systemFilterConfig, onFilterOptionsChange, isSelectorView, filterOptions }); - - const handleOnSearch = useCallback( - (newSearch) => { - const trimSearch = newSearch.trim(); - if (!isEqual(trimSearch, search)) { - setSearch(trimSearch); - onFilterChanged({ search: trimSearch }); - } - }, - [onFilterChanged, search] - ); + } = useFilterConfig({ + systemFilterConfig, + onFilterOptionsChange, + isSelectorView, + filterOptions, + customFields, + isLoading: isLoadingFilters, + }); const handleOnCreateCasePressed = useCallback(() => { if (onCreateCasePressed) { @@ -126,13 +130,15 @@ const CasesTableFiltersComponent = ({ </EuiFlexItem> ) : null} <EuiFlexItem grow={false}> - <EuiFieldSearch - aria-label={i18n.SEARCH_CASES} - data-test-subj="search-cases" - fullWidth - incremental={false} - placeholder={i18n.SEARCH_PLACEHOLDER} - onSearch={handleOnSearch} + <TableSearch + filterOptionsSearch={filterOptions.search} + /** + * we need this to reset the internal state of the + * TableSearch component each time the search in + * the all cases state changes + */ + key={filterOptions.search} + onFilterOptionsChange={onFilterOptionsChange} /> </EuiFlexItem> {activeFilters.map((filter) => ( @@ -147,6 +153,7 @@ const CasesTableFiltersComponent = ({ options={selectableOptions} activeFilters={activeSelectableOptionKeys} onChange={onFilterConfigChange} + isLoading={isLoadingFilters} /> </EuiFlexItem> )} diff --git a/x-pack/plugins/cases/public/components/all_cases/translations.ts b/x-pack/plugins/cases/public/components/all_cases/translations.ts index f0c402d097e8d..e29019516e911 100644 --- a/x-pack/plugins/cases/public/components/all_cases/translations.ts +++ b/x-pack/plugins/cases/public/components/all_cases/translations.ts @@ -139,12 +139,9 @@ export const FILTER_ASSIGNEES_ARIA_LABEL = i18n.translate( } ); -export const CLEAR_FILTERS = i18n.translate( - 'xpack.cases.allCasesView.filterAssignees.clearFilters', - { - defaultMessage: 'Clear filters', - } -); +export const CLEAR_FILTERS = i18n.translate('xpack.cases.allCasesView.clearFilters', { + defaultMessage: 'Clear filters', +}); export const TOTAL_ASSIGNEES_FILTERED = (total: number) => i18n.translate('xpack.cases.allCasesView.totalFilteredUsers', { diff --git a/x-pack/plugins/cases/public/components/all_cases/types.ts b/x-pack/plugins/cases/public/components/all_cases/types.ts index c0872b63cd892..4a1dd61aa505c 100644 --- a/x-pack/plugins/cases/public/components/all_cases/types.ts +++ b/x-pack/plugins/cases/public/components/all_cases/types.ts @@ -5,9 +5,11 @@ * 2.0. */ -import type { SortOrder } from '../../../common/ui'; +import type * as rt from 'io-ts'; +import type { FilterOptions, QueryParams, SortOrder } from '../../../common/ui'; +import type { AllCasesURLQueryParamsRt } from './schema'; -export const CASES_TABLE_PERPAGE_VALUES = [10, 25, 50, 100]; +export const CASES_TABLE_PER_PAGE_VALUES = [10, 25, 50, 100]; export interface EuiBasicTableSortTypes { field: string; @@ -32,3 +34,21 @@ export interface CasesColumnSelection { name: string; isChecked: boolean; } + +type SupportedFilterOptionsInURL = Pick< + FilterOptions, + 'search' | 'severity' | 'status' | 'tags' | 'assignees' | 'category' +>; + +export interface AllCasesTableState { + filterOptions: FilterOptions; + queryParams: QueryParams; +} + +export interface AllCasesURLState { + filterOptions: Partial<SupportedFilterOptionsInURL> & + Partial<Pick<FilterOptions, 'customFields'>>; + queryParams: Partial<QueryParams>; +} + +export type AllCasesURLQueryParams = rt.TypeOf<typeof AllCasesURLQueryParamsRt>; diff --git a/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.test.tsx b/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.test.tsx index 30de5acb0bfac..43aec66176c6f 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.test.tsx @@ -6,351 +6,780 @@ */ import React from 'react'; -import { useHistory } from 'react-router-dom'; -import { act, renderHook } from '@testing-library/react-hooks'; +import { renderHook, act } from '@testing-library/react-hooks'; +import { waitFor } from '@testing-library/react'; +import { CaseStatuses } from '@kbn/cases-components'; import { TestProviders } from '../../common/mock'; -import { - useAllCasesState, - getQueryParamsLocalStorageKey, - getFilterOptionsLocalStorageKey, -} from './use_all_cases_state'; -import { - DEFAULT_FILTER_OPTIONS, - DEFAULT_QUERY_PARAMS, - DEFAULT_TABLE_ACTIVE_PAGE, - DEFAULT_TABLE_LIMIT, -} from '../../containers/constants'; -import { CaseStatuses } from '../../../common/types/domain'; +import { useAllCasesState } from './use_all_cases_state'; +import { DEFAULT_CASES_TABLE_STATE, DEFAULT_TABLE_LIMIT } from '../../containers/constants'; import { SortFieldCase } from '../../containers/types'; -import { stringifyToURL } from '../utils'; - -const LOCAL_STORAGE_QUERY_PARAMS_DEFAULTS = { - perPage: DEFAULT_QUERY_PARAMS.perPage, - sortOrder: DEFAULT_QUERY_PARAMS.sortOrder, -}; - -const LOCAL_STORAGE_FILTER_OPTIONS_DEFAULTS = { - severity: DEFAULT_FILTER_OPTIONS.severity, - status: DEFAULT_FILTER_OPTIONS.status, -}; - -const URL_DEFAULTS = { - ...DEFAULT_QUERY_PARAMS, - ...LOCAL_STORAGE_FILTER_OPTIONS_DEFAULTS, -}; +import { stringifyUrlParams } from './utils/stringify_url_params'; +import { CaseSeverity } from '../../../common'; +import type { AllCasesTableState } from './types'; +import { CustomFieldTypes } from '../../../common/types/domain'; +import { useCaseConfigureResponse } from '../configure_cases/__mock__'; +import { useGetCaseConfiguration } from '../../containers/configure/use_get_case_configuration'; const mockLocation = { search: '' }; +const mockPush = jest.fn(); +const mockReplace = jest.fn(); + +jest.mock('../../containers/configure/use_get_case_configuration'); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useLocation: jest.fn().mockImplementation(() => { return mockLocation; }), - useHistory: jest.fn().mockReturnValue({ - replace: jest.fn(), - push: jest.fn(), + useHistory: jest.fn().mockImplementation(() => ({ + replace: mockReplace, + push: mockPush, location: { search: '', }, - }), + })), })); -const APP_ID = 'testAppId'; -const LOCALSTORAGE_QUERY_PARAMS_KEY = getQueryParamsLocalStorageKey(APP_ID); -const LOCALSTORAGE_FILTER_OPTIONS_KEY = getFilterOptionsLocalStorageKey(APP_ID); +const useGetCaseConfigurationMock = useGetCaseConfiguration as jest.Mock; + +const LS_KEY = 'testAppId.cases.list.state'; describe('useAllCasesQueryParams', () => { beforeEach(() => { localStorage.clear(); + mockLocation.search = ''; + + useGetCaseConfigurationMock.mockImplementation(() => useCaseConfigureResponse); }); afterEach(() => { jest.clearAllMocks(); }); - it('calls setState with default values on first run', () => { + it('returns default state with empty URL and local storage', () => { const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.queryParams).toStrictEqual(DEFAULT_QUERY_PARAMS); - expect(result.current.filterOptions).toStrictEqual(DEFAULT_FILTER_OPTIONS); + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); }); - it('updates localstorage with default values on first run', () => { - expect(localStorage.getItem(LOCALSTORAGE_QUERY_PARAMS_KEY)).toStrictEqual(null); - expect(localStorage.getItem(LOCALSTORAGE_FILTER_OPTIONS_KEY)).toStrictEqual(null); + it('takes into account existing localStorage query params on first run', () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_TABLE_LIMIT + 10, + sortOrder: 'asc', + sortField: SortFieldCase.severity, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - renderHook(() => useAllCasesState(), { + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toMatchObject(existingLocalStorageValues.queryParams); + }); + + it('takes into account existing localStorage filter options values on first run', () => { + const existingLocalStorageValues = { + queryParams: DEFAULT_CASES_TABLE_STATE.queryParams, + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + severity: ['critical'], + status: ['open'], + }, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); + + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(JSON.parse(localStorage.getItem(LOCALSTORAGE_QUERY_PARAMS_KEY)!)).toMatchObject({ - ...LOCAL_STORAGE_QUERY_PARAMS_DEFAULTS, + expect(result.current.filterOptions).toMatchObject(existingLocalStorageValues.filterOptions); + }); + + it('takes into account existing url query params on first run', () => { + mockLocation.search = stringifyUrlParams({ page: 2, perPage: 15 }); + + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(JSON.parse(localStorage.getItem(LOCALSTORAGE_FILTER_OPTIONS_KEY)!)).toMatchObject({ - ...LOCAL_STORAGE_FILTER_OPTIONS_DEFAULTS, + + expect(result.current.queryParams).toMatchObject({ + ...DEFAULT_CASES_TABLE_STATE.queryParams, + ...{ page: 2, perPage: 15 }, }); }); - it('takes into account input filter options', () => { - const existingLocalStorageValues = { owner: ['foobar'], status: [CaseStatuses.open] }; + it('takes into account existing url filter options on first run', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.CRITICAL], + status: [CaseStatuses.open], + }); - const { result } = renderHook(() => useAllCasesState(false, existingLocalStorageValues), { + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.filterOptions).toStrictEqual({ - ...DEFAULT_FILTER_OPTIONS, - ...existingLocalStorageValues, + expect(result.current.filterOptions).toMatchObject({ + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + ...{ severity: ['critical'], status: ['open'] }, }); }); - it('calls history.replace on every run', () => { + it('takes into account legacy url filter option "all"', () => { + const nonDefaultUrlParams = new URLSearchParams(); + nonDefaultUrlParams.append('severity', 'all'); + nonDefaultUrlParams.append('status', 'all'); + nonDefaultUrlParams.append('status', 'open'); + nonDefaultUrlParams.append('severity', 'low'); + + mockLocation.search = nonDefaultUrlParams.toString(); + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledTimes(1); - expect(useHistory().push).toHaveBeenCalledTimes(0); + expect(result.current.filterOptions).toMatchObject({ + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + ...{ severity: ['low'], status: ['open'] }, + }); + }); + + it('preserves non cases state url parameters', () => { + mockLocation.search = `${stringifyUrlParams({ + status: [CaseStatuses.open], + })}&foo=bar&foo=baz&test=my-test`; + + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); act(() => { - result.current.setQueryParams({ perPage: DEFAULT_TABLE_LIMIT + 10 }); + result.current.setFilterOptions({ severity: [CaseSeverity.MEDIUM] }); }); - expect(useHistory().replace).toHaveBeenCalledTimes(2); - expect(useHistory().push).toHaveBeenCalledTimes(0); + expect(mockPush).toHaveBeenCalledWith({ + search: + 'cases=(page:1,perPage:10,severity:!(medium),sortField:createdAt,sortOrder:desc,status:!(open))&foo=bar&foo=baz&test=my-test', + }); }); - it('takes into account existing localStorage query params on first run', () => { + it('does not preserve cases state in the url when clearing filters', async () => { + const defaultStateWithValues: AllCasesTableState = { + filterOptions: { + search: 'my search', + searchFields: ['title'], + severity: [CaseSeverity.MEDIUM], + assignees: ['elastic'], + reporters: [], + status: [CaseStatuses.closed], + tags: ['test-tag'], + owner: ['cases'], + category: ['test-category'], + customFields: { + testCustomField: { options: ['foo'], type: CustomFieldTypes.TEXT }, + }, + }, + queryParams: { + page: DEFAULT_CASES_TABLE_STATE.queryParams.page + 10, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 50, + sortField: SortFieldCase.closedAt, + sortOrder: 'asc', + }, + }; + + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + act(() => { + result.current.setFilterOptions(defaultStateWithValues.filterOptions); + }); + + act(() => { + result.current.setQueryParams(defaultStateWithValues.queryParams); + }); + + await waitFor(() => { + expect(result.current.queryParams).toStrictEqual(defaultStateWithValues.queryParams); + expect(result.current.filterOptions).toStrictEqual(defaultStateWithValues.filterOptions); + }); + + act(() => { + result.current.setFilterOptions(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + act(() => { + result.current.setQueryParams(DEFAULT_CASES_TABLE_STATE.queryParams); + }); + + await waitFor(() => { + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + }); + + it('urlParams take precedence over localStorage query params values', () => { + mockLocation.search = stringifyUrlParams({ perPage: 15 }); + const existingLocalStorageValues = { - perPage: DEFAULT_TABLE_LIMIT + 10, - sortOrder: 'asc', - sortField: SortFieldCase.severity, + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, perPage: 20 }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, }; - localStorage.setItem(LOCALSTORAGE_QUERY_PARAMS_KEY, JSON.stringify(existingLocalStorageValues)); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); expect(result.current.queryParams).toMatchObject({ - ...LOCAL_STORAGE_QUERY_PARAMS_DEFAULTS, - ...existingLocalStorageValues, + ...DEFAULT_CASES_TABLE_STATE.queryParams, + ...{ perPage: 15 }, }); }); - it('takes into account existing localStorage filter options values on first run', () => { - const existingLocalStorageValues = { severity: ['critical'], status: ['open'] }; + it('urlParams take precedence over localStorage filter options values', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses.open], + }); - localStorage.setItem( - LOCALSTORAGE_FILTER_OPTIONS_KEY, - JSON.stringify(existingLocalStorageValues) - ); + const existingLocalStorageValues = { + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + severity: ['low'], + status: ['closed'], + }, + queryParams: DEFAULT_CASES_TABLE_STATE.queryParams, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.filterOptions).toMatchObject(existingLocalStorageValues); + expect(result.current.filterOptions).toMatchObject({ severity: ['high'], status: ['open'] }); }); - it('takes into account legacy localStorage filter values as string', () => { - const existingLocalStorageValues = { severity: 'critical', status: 'open' }; + it('loads the URL from the local storage when the URL is empty on first run', async () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; - localStorage.setItem( - LOCALSTORAGE_FILTER_OPTIONS_KEY, - JSON.stringify(existingLocalStorageValues) - ); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - const { result } = renderHook(() => useAllCasesState(), { + renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.filterOptions).toMatchObject({ - severity: ['critical'], - status: ['open'], + expect(mockReplace).toHaveBeenCalledWith({ + search: 'cases=(page:1,perPage:30,sortField:createdAt,sortOrder:desc)', }); }); - it('takes into account legacy localStorage filter value all', () => { - const existingLocalStorageValues = { severity: 'all', status: 'all' }; + it('does not load the URL from the local storage when the URL is empty on the second run', async () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; - localStorage.setItem( - LOCALSTORAGE_FILTER_OPTIONS_KEY, - JSON.stringify(existingLocalStorageValues) - ); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - const { result } = renderHook(() => useAllCasesState(), { + const { rerender } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.filterOptions).toMatchObject({ - severity: [], - status: [], - }); + rerender(); + + expect(mockReplace).toHaveBeenCalledTimes(1); }); - it('takes into account existing url query params on first run', () => { - const nonDefaultUrlParams = { - page: DEFAULT_TABLE_ACTIVE_PAGE + 1, - perPage: DEFAULT_TABLE_LIMIT + 5, + it('does not load the URL from the local storage when the URL is not empty', async () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses.open], + }); + + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, }; - const expectedUrl = { ...URL_DEFAULTS, ...nonDefaultUrlParams }; - mockLocation.search = stringifyToURL(nonDefaultUrlParams as unknown as Record<string, string>); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: stringifyToURL(expectedUrl as unknown as Record<string, string>), + expect(mockReplace).toHaveBeenCalledTimes(0); + }); + + it('loads the state from the URL correctly', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + }); + + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + status: [CaseStatuses['in-progress']], + severity: [CaseSeverity.HIGH], }); }); - it('takes into account existing url filter options on first run', () => { - const nonDefaultUrlParams = { severity: 'critical', status: 'open' }; + it('loads the state from the local storage if they URL is empty correctly', () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; - mockLocation.search = stringifyToURL(nonDefaultUrlParams); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - renderHook(() => useAllCasesState(), { + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: 'severity=critical&status=open&page=1&perPage=10&sortField=createdAt&sortOrder=desc', + expect(result.current.queryParams).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, }); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); }); - it('takes into account legacy url filter option "all"', () => { - const nonDefaultUrlParams = new URLSearchParams(); - nonDefaultUrlParams.append('severity', 'all'); - nonDefaultUrlParams.append('status', 'all'); - nonDefaultUrlParams.append('status', 'open'); - nonDefaultUrlParams.append('severity', 'low'); + it('updates the query params correctly', () => { + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); - mockLocation.search = stringifyToURL(nonDefaultUrlParams); + act(() => { + result.current.setQueryParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + }); - renderHook(() => useAllCasesState(), { + expect(result.current.queryParams).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + it('updates URL when updating the query params', () => { + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: 'severity=low&status=open&page=1&perPage=10&sortField=createdAt&sortOrder=desc', + act(() => { + result.current.setQueryParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + }); + + expect(mockPush).toHaveBeenCalledWith({ + search: 'cases=(page:1,perPage:30,sortField:createdAt,sortOrder:desc)', }); }); - it('preserves other url parameters', () => { - const nonDefaultUrlParams = { - foo: 'bar', - }; + it('updates the local storage when updating the query params', () => { + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); - mockLocation.search = stringifyToURL(nonDefaultUrlParams); + act(() => { + result.current.setQueryParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + }); - renderHook(() => useAllCasesState(), { + const localStorageState = JSON.parse(localStorage.getItem(LS_KEY) ?? '{}'); + expect(localStorageState).toEqual({ + ...DEFAULT_CASES_TABLE_STATE, + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + }); + }); + + it('updates the filter options correctly', () => { + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: 'foo=bar&page=1&perPage=10&sortField=createdAt&sortOrder=desc&severity=&status=', + act(() => { + result.current.setFilterOptions({ status: [CaseStatuses.closed] }); + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + status: [CaseStatuses.closed], }); }); - it('urlParams take precedence over localStorage query params values', () => { - const nonDefaultUrlParams = { - perPage: DEFAULT_TABLE_LIMIT + 5, - }; + it('updates the URL when updating the filter options', () => { + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); - mockLocation.search = stringifyToURL(nonDefaultUrlParams as unknown as Record<string, string>); + act(() => { + result.current.setFilterOptions({ status: [CaseStatuses.closed] }); + }); - localStorage.setItem( - LOCALSTORAGE_QUERY_PARAMS_KEY, - JSON.stringify({ perPage: DEFAULT_TABLE_LIMIT + 10 }) - ); + expect(mockPush).toHaveBeenCalledWith({ + search: 'cases=(page:1,perPage:10,sortField:createdAt,sortOrder:desc,status:!(closed))', + }); + }); + it('updates the local storage when updating the filter options', () => { const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.queryParams).toMatchObject({ - ...DEFAULT_QUERY_PARAMS, - ...nonDefaultUrlParams, + act(() => { + result.current.setFilterOptions({ status: [CaseStatuses.closed] }); + }); + + const localStorageState = JSON.parse(localStorage.getItem(LS_KEY) ?? '{}'); + expect(localStorageState).toEqual({ + ...DEFAULT_CASES_TABLE_STATE, + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + status: [CaseStatuses.closed], + }, }); }); - it('urlParams take precedence over localStorage filter options values', () => { - const nonDefaultUrlParams = { - severity: 'high', - status: 'open', + it('updates the local storage when navigating to a URL and the query params are not empty', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + customFields: { my_field: ['foo'] }, + }); + + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + data: { + ...useCaseConfigureResponse.data, + customFields: [ + { key: 'my_field', required: false, type: CustomFieldTypes.TEXT, label: 'foo' }, + ], + }, + })); + + renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + const localStorageState = JSON.parse(localStorage.getItem(LS_KEY) ?? '{}'); + + expect(localStorageState).toEqual({ + ...DEFAULT_CASES_TABLE_STATE, + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + customFields: { my_field: { options: ['foo'], type: CustomFieldTypes.TEXT } }, + }, + }); + }); + + it('does not update the local storage when navigating to an empty URL', () => { + const lsSpy = jest.spyOn(Storage.prototype, 'setItem'); + + renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + // first call is the initial call made by useLocalStorage + expect(lsSpy).toBeCalledTimes(1); + }); + + it('does not update the local storage on the second run', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + }); + + const lsSpy = jest.spyOn(Storage.prototype, 'setItem'); + + const { rerender } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + rerender(); + + // first call is the initial call made by useLocalStorage + expect(lsSpy).toBeCalledTimes(2); + }); + + it('does not update the local storage when the URL and the local storage are the same', async () => { + mockLocation.search = stringifyUrlParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + + const lsSpy = jest.spyOn(Storage.prototype, 'setItem'); + + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, }; - mockLocation.search = stringifyToURL(nonDefaultUrlParams); + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - localStorage.setItem( - LOCALSTORAGE_FILTER_OPTIONS_KEY, - JSON.stringify({ severity: ['low'], status: ['closed'] }) - ); + renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); - const { result } = renderHook(() => useAllCasesState(), { + // first call is the initial call made by useLocalStorage + expect(lsSpy).toBeCalledTimes(1); + }); + + it('does not update the local storage when the custom field configuration is loading', async () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + }); + + useGetCaseConfigurationMock.mockImplementation(() => ({ + ...useCaseConfigureResponse, + isFetching: true, + })); + + const lsSpy = jest.spyOn(Storage.prototype, 'setItem'); + + renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.filterOptions).toMatchObject({ severity: ['high'], status: ['open'] }); + // first call is the initial call made by useLocalStorage + expect(lsSpy).toBeCalledTimes(1); }); describe('validation', () => { it('localStorage perPage query param cannot be > 100', () => { - localStorage.setItem(LOCALSTORAGE_QUERY_PARAMS_KEY, JSON.stringify({ perPage: 1000 })); + const existingLocalStorageValues = { + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, perPage: 1000 }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); expect(result.current.queryParams).toMatchObject({ - ...LOCAL_STORAGE_QUERY_PARAMS_DEFAULTS, perPage: 100, }); }); it('url perPage query param cannot be > 100', () => { - mockLocation.search = stringifyToURL({ perPage: '1000' }); + mockLocation.search = stringifyUrlParams({ perPage: 1000 }); - renderHook(() => useAllCasesState(), { + const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: 'perPage=100&page=1&sortField=createdAt&sortOrder=desc&severity=&status=', + expect(result.current.queryParams).toMatchObject({ + ...DEFAULT_CASES_TABLE_STATE.queryParams, + ...{ perPage: 100 }, }); - - mockLocation.search = ''; }); it('validate spelling of localStorage sortOrder', () => { - localStorage.setItem(LOCALSTORAGE_QUERY_PARAMS_KEY, JSON.stringify({ sortOrder: 'foobar' })); + const existingLocalStorageValues = { + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, sortOrder: 'foobar' }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); const { result } = renderHook(() => useAllCasesState(), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(result.current.queryParams).toMatchObject({ - ...LOCAL_STORAGE_QUERY_PARAMS_DEFAULTS, - }); + expect(result.current.queryParams).toMatchObject({ sortOrder: 'desc' }); }); it('validate spelling of url sortOrder', () => { - mockLocation.search = stringifyToURL({ sortOrder: 'foobar' }); + // @ts-expect-error: testing invalid sortOrder + mockLocation.search = stringifyUrlParams({ sortOrder: 'foobar' }); + + const { result } = renderHook(() => useAllCasesState(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toMatchObject({ sortOrder: 'desc' }); + }); + }); + + describe('Modal', () => { + it('returns default state with empty URL and local storage', () => { + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + it('updates the query params correctly', () => { + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + act(() => { + result.current.setQueryParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + }); + + expect(result.current.queryParams).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + it('updates the filter options correctly', () => { + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + act(() => { + result.current.setFilterOptions({ status: [CaseStatuses.closed] }); + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual({ + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + status: [CaseStatuses.closed], + }); + }); + + it('does not update the URL when changing the state of the table', () => { + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + act(() => { + result.current.setQueryParams({ perPage: 20 }); + }); + + expect(mockPush).not.toHaveBeenCalled(); + }); + + it('does not update the local storage when changing the state of the table', () => { + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + act(() => { + result.current.setQueryParams({ + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }); + }); + + const localStorageState = JSON.parse(localStorage.getItem(LS_KEY) ?? '{}'); + expect(localStorageState).toEqual(DEFAULT_CASES_TABLE_STATE); + }); + + it('does not load the URL from the local storage when the URL is empty on first run', () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); - renderHook(() => useAllCasesState(), { + renderHook(() => useAllCasesState(true), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); - expect(useHistory().replace).toHaveBeenCalledWith({ - search: 'sortOrder=desc&page=1&perPage=10&sortField=createdAt&severity=&status=', + expect(mockPush).not.toHaveBeenCalled(); + }); + + it('does not load the state from the URL', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], }); + + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + it('does not load the state from the local storage', () => { + const existingLocalStorageValues = { + queryParams: { + ...DEFAULT_CASES_TABLE_STATE.queryParams, + perPage: DEFAULT_CASES_TABLE_STATE.queryParams.perPage + 20, + }, + filterOptions: DEFAULT_CASES_TABLE_STATE.filterOptions, + }; + + localStorage.setItem(LS_KEY, JSON.stringify(existingLocalStorageValues)); + + const { result } = renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + expect(result.current.queryParams).toStrictEqual(DEFAULT_CASES_TABLE_STATE.queryParams); + expect(result.current.filterOptions).toStrictEqual(DEFAULT_CASES_TABLE_STATE.filterOptions); + }); + + it('does not update the local storage when navigating to a URL and the query params are not empty', () => { + mockLocation.search = stringifyUrlParams({ + severity: [CaseSeverity.HIGH], + status: [CaseStatuses['in-progress']], + }); + + renderHook(() => useAllCasesState(true), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + + const localStorageState = JSON.parse(localStorage.getItem(LS_KEY) ?? '{}'); + + expect(localStorageState).toEqual(DEFAULT_CASES_TABLE_STATE); }); }); }); diff --git a/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.tsx b/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.tsx index b988cf501cddb..39bac2c05d569 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_all_cases_state.tsx @@ -5,244 +5,202 @@ * 2.0. */ -import { useCallback, useEffect, useRef, useState } from 'react'; +import type { Dispatch, SetStateAction } from 'react'; +import { useEffect, useRef, useCallback, useMemo, useState } from 'react'; import { useLocation, useHistory } from 'react-router-dom'; -import { isEqual } from 'lodash'; - +import deepEqual from 'react-fast-compare'; import useLocalStorage from 'react-use/lib/useLocalStorage'; - -import { removeLegacyValuesFromOptions, getStorableFilters } from './utils/sanitize_filter_options'; -import type { - FilterOptions, - PartialFilterOptions, - LocalStorageQueryParams, - QueryParams, - PartialQueryParams, - ParsedUrlQueryParams, -} from '../../../common/ui/types'; - -import { DEFAULT_FILTER_OPTIONS, DEFAULT_QUERY_PARAMS } from '../../containers/constants'; -import { parseUrlQueryParams } from './utils'; -import { stringifyToURL, parseURL } from '../utils'; +import { isEmpty } from 'lodash'; + +import type { FilterOptions, QueryParams } from '../../../common/ui/types'; +import { + DEFAULT_CASES_TABLE_STATE, + DEFAULT_FILTER_OPTIONS, + DEFAULT_QUERY_PARAMS, +} from '../../containers/constants'; import { LOCAL_STORAGE_KEYS } from '../../../common/constants'; -import { SORT_ORDER_VALUES } from '../../../common/ui/types'; +import type { AllCasesTableState, AllCasesURLState } from './types'; +import { stringifyUrlParams } from './utils/stringify_url_params'; +import { allCasesUrlStateDeserializer } from './utils/all_cases_url_state_deserializer'; +import { allCasesUrlStateSerializer } from './utils/all_cases_url_state_serializer'; +import { parseUrlParams } from './utils/parse_url_params'; import { useCasesContext } from '../cases_context/use_cases_context'; -import { CASES_TABLE_PERPAGE_VALUES } from './types'; -import { parseURLWithFilterOptions } from './utils/parse_url_with_filter_options'; -import { serializeUrlParams } from './utils/serialize_url_params'; +import { sanitizeState } from './utils/sanitize_state'; +import { useGetCaseConfiguration } from '../../containers/configure/use_get_case_configuration'; + +interface UseAllCasesStateReturn { + filterOptions: FilterOptions; + setQueryParams: (queryParam: Partial<QueryParams>) => void; + setFilterOptions: (filterOptions: Partial<FilterOptions>) => void; + queryParams: QueryParams; +} -export const getQueryParamsLocalStorageKey = (appId: string) => { - const filteringKey = LOCAL_STORAGE_KEYS.casesQueryParams; - return `${appId}.${filteringKey}`; -}; +export function useAllCasesState(isModalView: boolean = false): UseAllCasesStateReturn { + const isStateLoadedFromLocalStorage = useRef(false); + const isFirstRun = useRef(false); + const [tableState, setTableState] = useState<AllCasesTableState>(DEFAULT_CASES_TABLE_STATE); + const [urlState, setUrlState] = useAllCasesUrlState(); + const [localStorageState, setLocalStorageState] = useAllCasesLocalStorage(); + const { isFetching: isLoadingCasesConfiguration } = useGetCaseConfiguration(); + + const allCasesTableState: AllCasesTableState = useMemo( + () => (isModalView ? tableState : getAllCasesTableState(urlState, localStorageState)), + [isModalView, tableState, urlState, localStorageState] + ); -export const getFilterOptionsLocalStorageKey = (appId: string) => { - const filteringKey = LOCAL_STORAGE_KEYS.casesFilterOptions; - return `${appId}.${filteringKey}`; -}; + const setState = useCallback( + (state: AllCasesTableState) => { + if (isModalView) { + setTableState(state); + return; + } -const getQueryParams = ( - params: PartialQueryParams, - urlParams: PartialQueryParams, - localStorageQueryParams?: LocalStorageQueryParams -): QueryParams => { - const result = { ...DEFAULT_QUERY_PARAMS }; - - result.perPage = - params.perPage ?? - urlParams.perPage ?? - localStorageQueryParams?.perPage ?? - DEFAULT_QUERY_PARAMS.perPage; - - result.sortField = - params.sortField ?? - urlParams.sortField ?? - localStorageQueryParams?.sortField ?? - DEFAULT_QUERY_PARAMS.sortField; - - result.sortOrder = - params.sortOrder ?? - urlParams.sortOrder ?? - localStorageQueryParams?.sortOrder ?? - DEFAULT_QUERY_PARAMS.sortOrder; - - result.page = params.page ?? urlParams.page ?? DEFAULT_QUERY_PARAMS.page; - - return result; -}; + if (!deepEqual(state, urlState)) { + setUrlState(state); + } -const validateQueryParams = (queryParams: QueryParams): QueryParams => { - const perPage = Math.min( - queryParams.perPage, - CASES_TABLE_PERPAGE_VALUES[CASES_TABLE_PERPAGE_VALUES.length - 1] + if (!deepEqual(state, localStorageState)) { + setLocalStorageState(state); + } + }, + [localStorageState, urlState, isModalView, setLocalStorageState, setUrlState] ); - const sortOrder = !SORT_ORDER_VALUES.includes(queryParams.sortOrder) - ? DEFAULT_QUERY_PARAMS.sortOrder - : queryParams.sortOrder; - - return { ...queryParams, perPage, sortOrder }; -}; -/** - * Previously, 'status' and 'severity' were represented as single options (strings). - * To maintain backward compatibility while transitioning to the new type of string[], - * we map the legacy type to the new type. - */ -const convertToFilterOptionArray = (value: string | string[] | undefined) => { - if (typeof value === 'string') { - return [value]; + // use of useEffect because setUrlState calls history.push + useEffect(() => { + if ( + !isStateLoadedFromLocalStorage.current && + isURLStateEmpty(urlState) && + localStorageState && + !isModalView + ) { + setUrlState(localStorageState, 'replace'); + isStateLoadedFromLocalStorage.current = true; + } + }, [localStorageState, setUrlState, urlState, isModalView]); + + /** + * When navigating for the first time in a URL + * we need to persist the state on the local storage. + * We need to do it only on the first run and only when the URL is not empty. + * Otherwise we may introduce a race condition or loop with the above hook. + */ + if ( + !isFirstRun.current && + !isURLStateEmpty(urlState) && + localStorageState && + !deepEqual(allCasesTableState, localStorageState) && + !isLoadingCasesConfiguration && + !isModalView + ) { + setLocalStorageState(allCasesTableState); + isFirstRun.current = true; } - return value; -}; - -const getFilterOptions = ( - filterOptions: FilterOptions, - params: FilterOptions, - urlParams: PartialFilterOptions, - localStorageFilterOptions?: PartialFilterOptions -): FilterOptions => { - const severity = - params?.severity ?? - urlParams?.severity ?? - convertToFilterOptionArray(localStorageFilterOptions?.severity) ?? - DEFAULT_FILTER_OPTIONS.severity; - - const status = - params?.status ?? - urlParams?.status ?? - convertToFilterOptionArray(localStorageFilterOptions?.status) ?? - DEFAULT_FILTER_OPTIONS.status; return { - ...filterOptions, - ...params, - ...removeLegacyValuesFromOptions({ status, severity }), + ...allCasesTableState, + setQueryParams: (newQueryParams: Partial<QueryParams>) => { + setState({ + filterOptions: allCasesTableState.filterOptions, + queryParams: { ...allCasesTableState.queryParams, ...newQueryParams }, + }); + }, + setFilterOptions: (newFilterOptions: Partial<FilterOptions>) => { + setState({ + filterOptions: { ...allCasesTableState.filterOptions, ...newFilterOptions }, + queryParams: allCasesTableState.queryParams, + }); + }, }; -}; +} -export function useAllCasesState( - isModalView: boolean = false, - initialFilterOptions?: PartialFilterOptions -) { - const { appId } = useCasesContext(); - const location = useLocation(); +const useAllCasesUrlState = (): [ + AllCasesURLState, + (updated: AllCasesTableState, mode?: 'push' | 'replace') => void +] => { const history = useHistory(); - const isFirstRenderRef = useRef(true); + const location = useLocation(); + const { + data: { customFields: customFieldsConfiguration }, + } = useGetCaseConfiguration(); + + const urlParams = parseUrlParams(new URLSearchParams(decodeURIComponent(location.search))); + const parsedUrlParams = allCasesUrlStateDeserializer(urlParams, customFieldsConfiguration); + + const updateQueryParams = useCallback( + (updated: AllCasesTableState, mode: 'push' | 'replace' = 'push') => { + const updatedQuery = allCasesUrlStateSerializer(updated); + const search = stringifyUrlParams(updatedQuery, location.search); + + history[mode]({ + ...location, + search, + }); + }, + [history, location] + ); - const [queryParams, setQueryParams] = useState<QueryParams>({ ...DEFAULT_QUERY_PARAMS }); - const [filterOptions, setFilterOptions] = useState<FilterOptions>({ - ...DEFAULT_FILTER_OPTIONS, - ...initialFilterOptions, - }); + return [parsedUrlParams, updateQueryParams]; +}; - const [localStorageQueryParams, setLocalStorageQueryParams] = - useLocalStorage<LocalStorageQueryParams>(getQueryParamsLocalStorageKey(appId)); +const getAllCasesTableState = ( + urlState: AllCasesURLState, + localStorageState?: AllCasesTableState +): AllCasesTableState => { + if (isURLStateEmpty(urlState)) { + return { + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, ...localStorageState?.queryParams }, + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + ...localStorageState?.filterOptions, + }, + }; + } - const [localStorageFilterOptions, setLocalStorageFilterOptions] = - useLocalStorage<PartialFilterOptions>(getFilterOptionsLocalStorageKey(appId)); + return { + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, ...urlState.queryParams }, + filterOptions: { ...DEFAULT_CASES_TABLE_STATE.filterOptions, ...urlState.filterOptions }, + }; +}; - const persistAndUpdateQueryParams = useCallback( - (params) => { - if (isModalView) { - setQueryParams((prevParams) => ({ ...prevParams, ...params })); - return; - } +const isURLStateEmpty = (urlState: AllCasesURLState) => { + if (isEmpty(urlState)) { + return true; + } - const parsedUrlParams: ParsedUrlQueryParams = parseURL(location.search); - const urlParams: PartialQueryParams = parseUrlQueryParams(parsedUrlParams); + if (isEmpty(urlState.filterOptions) && isEmpty(urlState.queryParams)) { + return true; + } - let newQueryParams: QueryParams = getQueryParams(params, urlParams, localStorageQueryParams); + return false; +}; - newQueryParams = validateQueryParams(newQueryParams); +const useAllCasesLocalStorage = (): [ + AllCasesTableState | undefined, + Dispatch<SetStateAction<AllCasesTableState | undefined>> +] => { + const { appId } = useCasesContext(); - const newLocalStorageQueryParams = { - perPage: newQueryParams.perPage, - sortField: newQueryParams.sortField, - sortOrder: newQueryParams.sortOrder, - }; - setLocalStorageQueryParams(newLocalStorageQueryParams); - setQueryParams(newQueryParams); - }, - [isModalView, location.search, localStorageQueryParams, setLocalStorageQueryParams] + const [state, setState] = useLocalStorage<AllCasesTableState>( + getAllCasesTableStateLocalStorageKey(appId), + { queryParams: DEFAULT_QUERY_PARAMS, filterOptions: DEFAULT_FILTER_OPTIONS } ); - const persistAndUpdateFilterOptions = useCallback( - (params) => { - if (isModalView) { - setFilterOptions((prevParams) => ({ ...prevParams, ...params })); - return; - } + const sanitizedState = sanitizeState(state); - const newFilterOptions: FilterOptions = getFilterOptions( - filterOptions, - params, - parseURLWithFilterOptions(location.search), - localStorageFilterOptions - ); - - const newPersistedFilterOptions: PartialFilterOptions = getStorableFilters(newFilterOptions); - - const newLocalStorageFilterOptions: PartialFilterOptions = { - ...localStorageFilterOptions, - ...newPersistedFilterOptions, - }; - setLocalStorageFilterOptions(newLocalStorageFilterOptions); - setFilterOptions(newFilterOptions); + return [ + { + queryParams: { ...DEFAULT_CASES_TABLE_STATE.queryParams, ...sanitizedState.queryParams }, + filterOptions: { + ...DEFAULT_CASES_TABLE_STATE.filterOptions, + ...sanitizedState.filterOptions, + }, }, - [ - filterOptions, - isModalView, - localStorageFilterOptions, - location.search, - setLocalStorageFilterOptions, - ] - ); - - const updateLocation = useCallback(() => { - const parsedUrlParams = parseURLWithFilterOptions(location.search); - const stateUrlParams = { - ...parsedUrlParams, - ...queryParams, - ...getStorableFilters(filterOptions), - page: queryParams.page.toString(), - perPage: queryParams.perPage.toString(), - }; - - if (!isEqual(parsedUrlParams, stateUrlParams)) { - try { - const urlParams = serializeUrlParams({ - ...parsedUrlParams, - ...stateUrlParams, - }); - - const newHistory = { - ...location, - search: stringifyToURL(urlParams), - }; - history.replace(newHistory); - } catch { - // silently fail - } - } - }, [filterOptions, history, location, queryParams]); - - if (isFirstRenderRef.current) { - persistAndUpdateQueryParams(isModalView ? queryParams : {}); - persistAndUpdateFilterOptions(isModalView ? filterOptions : initialFilterOptions); - - isFirstRenderRef.current = false; - } - - useEffect(() => { - if (!isModalView) { - updateLocation(); - } - }, [isModalView, updateLocation]); + setState, + ]; +}; - return { - queryParams, - setQueryParams: persistAndUpdateQueryParams, - filterOptions, - setFilterOptions: persistAndUpdateFilterOptions, - }; -} +const getAllCasesTableStateLocalStorageKey = (appId: string) => { + const key = LOCAL_STORAGE_KEYS.casesTableState; + return `${appId}.${key}`; +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns_selection.tsx b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns_selection.tsx index a7c32ee939a19..7b81e88c0d383 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns_selection.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns_selection.tsx @@ -12,7 +12,7 @@ import type { CasesColumnSelection } from './types'; import { LOCAL_STORAGE_KEYS } from '../../../common/constants'; import { useCasesContext } from '../cases_context/use_cases_context'; import { useCasesColumnsConfiguration } from './use_cases_columns_configuration'; -import { mergeSelectedColumnsWithConfiguration } from './utils'; +import { mergeSelectedColumnsWithConfiguration } from './utils/merge_selected_columns_with_configuration'; const getTableColumnsLocalStorageKey = (appId: string) => { const filteringKey = LOCAL_STORAGE_KEYS.casesTableColumns; diff --git a/x-pack/plugins/cases/public/components/all_cases/utility_bar.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utility_bar.test.tsx index ce776e77e8304..f58e7aa2698cc 100644 --- a/x-pack/plugins/cases/public/components/all_cases/utility_bar.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/utility_bar.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { act, waitFor, screen } from '@testing-library/react'; +import { act, waitFor, screen, waitForElementToBeRemoved } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import type { AppMockRenderer } from '../../common/mock'; @@ -36,6 +36,8 @@ describe('Severity form field', () => { }, selectedColumns: [], onSelectedColumnsChange: jest.fn(), + onClearFilters: jest.fn(), + showClearFiltersButton: false, }; beforeEach(() => { @@ -44,11 +46,14 @@ describe('Severity form field', () => { it('renders', async () => { appMockRender.render(<CasesTableUtilityBar {...props} />); - expect(screen.getByText('Showing 5 of 5 cases')).toBeInTheDocument(); - expect(screen.getByText('Selected 1 case')).toBeInTheDocument(); - expect(screen.getByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); - expect(screen.getByTestId('all-cases-refresh-link-icon')).toBeInTheDocument(); + + expect(await screen.findByText('Showing 5 of 5 cases')).toBeInTheDocument(); + expect(await screen.findByText('Selected 1 case')).toBeInTheDocument(); + expect(await screen.findByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); + expect(await screen.findByTestId('all-cases-refresh-link-icon')).toBeInTheDocument(); + expect(screen.queryByTestId('all-cases-maximum-limit-warning')).not.toBeInTheDocument(); + expect(screen.queryByTestId('all-cases-clear-filters-link-icon')).not.toBeInTheDocument(); }); it('renders showing cases correctly', async () => { @@ -60,9 +65,11 @@ describe('Severity form field', () => { totalItemCount: 20, }, }; + appMockRender.render(<CasesTableUtilityBar {...updatedProps} />); - expect(screen.getByText('Showing 10 of 20 cases')).toBeInTheDocument(); - expect(screen.getByText('Selected 1 case')).toBeInTheDocument(); + + expect(await screen.findByText('Showing 10 of 20 cases')).toBeInTheDocument(); + expect(await screen.findByText('Selected 1 case')).toBeInTheDocument(); }); it('renders showing cases correctly for second page', async () => { @@ -75,13 +82,16 @@ describe('Severity form field', () => { totalItemCount: 20, }, }; + appMockRender.render(<CasesTableUtilityBar {...updatedProps} />); - expect(screen.getByText('Showing 10 of 20 cases')).toBeInTheDocument(); - expect(screen.getByText('Selected 1 case')).toBeInTheDocument(); + + expect(await screen.findByText('Showing 10 of 20 cases')).toBeInTheDocument(); + expect(await screen.findByText('Selected 1 case')).toBeInTheDocument(); }); it('renders showing cases correctly when no cases available', async () => { const updatedProps = { + ...props, totalCases: 0, selectedCases: [], deselectCases, @@ -90,16 +100,15 @@ describe('Severity form field', () => { pageIndex: 1, totalItemCount: 0, }, - selectedColumns: [], - onSelectedColumnsChange: jest.fn(), }; + appMockRender.render(<CasesTableUtilityBar {...updatedProps} />); - expect(screen.getByText('Showing 0 of 0 cases')).toBeInTheDocument(); + expect(await screen.findByText('Showing 0 of 0 cases')).toBeInTheDocument(); }); it('renders columns popover button when isSelectorView=False', async () => { appMockRender.render(<CasesTableUtilityBar {...props} />); - expect(screen.getByTestId('column-selection-popover-button')).toBeInTheDocument(); + expect(await screen.findByTestId('column-selection-popover-button')).toBeInTheDocument(); }); it('does not render columns popover button when isSelectorView=True', async () => { @@ -110,34 +119,28 @@ describe('Severity form field', () => { it('opens the bulk actions correctly', async () => { appMockRender.render(<CasesTableUtilityBar {...props} />); - userEvent.click(screen.getByTestId('case-table-bulk-actions-link-icon')); + userEvent.click(await screen.findByTestId('case-table-bulk-actions-link-icon')); - await waitFor(() => { - expect(screen.getByTestId('case-table-bulk-actions-context-menu')); - }); + expect(await screen.findByTestId('case-table-bulk-actions-context-menu')); }); it('closes the bulk actions correctly', async () => { appMockRender.render(<CasesTableUtilityBar {...props} />); - userEvent.click(screen.getByTestId('case-table-bulk-actions-link-icon')); + userEvent.click(await screen.findByTestId('case-table-bulk-actions-link-icon')); - await waitFor(() => { - expect(screen.getByTestId('case-table-bulk-actions-context-menu')); - }); + expect(await screen.findByTestId('case-table-bulk-actions-context-menu')); - userEvent.click(screen.getByTestId('case-table-bulk-actions-link-icon')); + userEvent.click(await screen.findByTestId('case-table-bulk-actions-link-icon')); - await waitFor(() => { - expect(screen.queryByTestId('case-table-bulk-actions-context-menu')).toBeFalsy(); - }); + await waitForElementToBeRemoved(screen.queryByTestId('case-table-bulk-actions-context-menu')); }); it('refresh correctly', async () => { appMockRender.render(<CasesTableUtilityBar {...props} />); const queryClientSpy = jest.spyOn(appMockRender.queryClient, 'invalidateQueries'); - userEvent.click(screen.getByTestId('all-cases-refresh-link-icon')); + userEvent.click(await screen.findByTestId('all-cases-refresh-link-icon')); await waitFor(() => { expect(deselectCases).toHaveBeenCalled(); @@ -151,28 +154,44 @@ describe('Severity form field', () => { appMockRender = createAppMockRenderer({ permissions: noCasesPermissions() }); appMockRender.render(<CasesTableUtilityBar {...props} />); - expect(screen.queryByTestId('case-table-bulk-actions-link-icon')).toBeFalsy(); + expect(screen.queryByTestId('case-table-bulk-actions-link-icon')).not.toBeInTheDocument(); }); it('does show the bulk actions with only delete permissions', async () => { appMockRender = createAppMockRenderer({ permissions: onlyDeleteCasesPermission() }); appMockRender.render(<CasesTableUtilityBar {...props} />); - expect(screen.getByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); + expect(await screen.findByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); }); it('does show the bulk actions with update permissions', async () => { appMockRender = createAppMockRenderer({ permissions: writeCasesPermissions() }); appMockRender.render(<CasesTableUtilityBar {...props} />); - expect(screen.getByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); + expect(await screen.findByTestId('case-table-bulk-actions-link-icon')).toBeInTheDocument(); }); it('does not show the bulk actions if there are not selected cases', async () => { appMockRender.render(<CasesTableUtilityBar {...props} selectedCases={[]} />); - expect(screen.queryByTestId('case-table-bulk-actions-link-icon')).toBeFalsy(); - expect(screen.queryByText('Showing 0 cases')).toBeFalsy(); + expect(screen.queryByTestId('case-table-bulk-actions-link-icon')).not.toBeInTheDocument(); + expect(screen.queryByText('Showing 0 cases')).not.toBeInTheDocument(); + }); + + it('shows the clear filter button', async () => { + appMockRender.render(<CasesTableUtilityBar {...props} showClearFiltersButton={true} />); + + expect(await screen.findByTestId('all-cases-clear-filters-link-icon')).toBeInTheDocument(); + }); + + it('clears the filters correctly', async () => { + appMockRender.render(<CasesTableUtilityBar {...props} showClearFiltersButton={true} />); + + userEvent.click(await screen.findByTestId('all-cases-clear-filters-link-icon')); + + await waitFor(() => { + expect(props.onClearFilters).toHaveBeenCalled(); + }); }); describe('Maximum number of cases', () => { @@ -190,7 +209,7 @@ describe('Severity form field', () => { it.each(allCasesPageSize)( `does not show warning when totalCases = ${MAX_DOCS_PER_PAGE} but pageSize(%s) * pageIndex + 1 < ${MAX_DOCS_PER_PAGE}`, - (size) => { + async (size) => { const newPageIndex = MAX_DOCS_PER_PAGE / size - 2; appMockRender.render( @@ -203,15 +222,16 @@ describe('Severity form field', () => { ); expect( - screen.getByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) + await screen.findByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) ).toBeInTheDocument(); + expect(screen.queryByTestId('all-cases-maximum-limit-warning')).not.toBeInTheDocument(); } ); it.each(allCasesPageSize)( `shows warning when totalCases = ${MAX_DOCS_PER_PAGE} but pageSize(%s) * pageIndex + 1 = ${MAX_DOCS_PER_PAGE}`, - (size) => { + async (size) => { const newPageIndex = MAX_DOCS_PER_PAGE / size - 1; appMockRender.render( @@ -224,15 +244,16 @@ describe('Severity form field', () => { ); expect( - screen.getByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) + await screen.findByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) ).toBeInTheDocument(); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); } ); it.each(allCasesPageSize)( `shows warning when totalCases = ${MAX_DOCS_PER_PAGE} but pageSize(%s) * pageIndex + 1 > ${MAX_DOCS_PER_PAGE}`, - (size) => { + async (size) => { const newPageIndex = MAX_DOCS_PER_PAGE / size; appMockRender.render( @@ -245,13 +266,14 @@ describe('Severity form field', () => { ); expect( - screen.getByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) + await screen.findByText(`Showing ${size} of ${MAX_DOCS_PER_PAGE} cases`) ).toBeInTheDocument(); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); } ); - it('should show dismiss and do not show again buttons correctly', () => { + it('should show dismiss and do not show again buttons correctly', async () => { appMockRender.render( <CasesTableUtilityBar {...{ @@ -261,13 +283,12 @@ describe('Severity form field', () => { /> ); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); - expect(screen.getByTestId('dismiss-warning')).toBeInTheDocument(); - - expect(screen.getByTestId('do-not-show-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('dismiss-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('do-not-show-warning')).toBeInTheDocument(); }); - it('should dismiss warning correctly', () => { + it('should dismiss warning correctly', async () => { appMockRender.render( <CasesTableUtilityBar {...{ @@ -277,10 +298,10 @@ describe('Severity form field', () => { /> ); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); - expect(screen.getByTestId('dismiss-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('dismiss-warning')).toBeInTheDocument(); - userEvent.click(screen.getByTestId('dismiss-warning')); + userEvent.click(await screen.findByTestId('dismiss-warning')); expect(screen.queryByTestId('all-cases-maximum-limit-warning')).not.toBeInTheDocument(); }); @@ -303,7 +324,7 @@ describe('Severity form field', () => { jest.clearAllMocks(); }); - it('should set storage key correctly', () => { + it('should set storage key correctly', async () => { appMockRender.render( <CasesTableUtilityBar {...{ @@ -313,13 +334,13 @@ describe('Severity form field', () => { /> ); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); - expect(screen.getByTestId('do-not-show-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('do-not-show-warning')).toBeInTheDocument(); expect(localStorage.getItem(localStorageKey)).toBe(null); }); - it('should hide warning correctly when do not show button clicked', () => { + it('should hide warning correctly when do not show button clicked', async () => { appMockRender.render( <CasesTableUtilityBar {...{ @@ -329,10 +350,10 @@ describe('Severity form field', () => { /> ); - expect(screen.getByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); - expect(screen.getByTestId('do-not-show-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('all-cases-maximum-limit-warning')).toBeInTheDocument(); + expect(await screen.findByTestId('do-not-show-warning')).toBeInTheDocument(); - userEvent.click(screen.getByTestId('do-not-show-warning')); + userEvent.click(await screen.findByTestId('do-not-show-warning')); act(() => { jest.advanceTimersByTime(1000); diff --git a/x-pack/plugins/cases/public/components/all_cases/utility_bar.tsx b/x-pack/plugins/cases/public/components/all_cases/utility_bar.tsx index ee80e0ffb38b1..afd9398d91cce 100644 --- a/x-pack/plugins/cases/public/components/all_cases/utility_bar.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/utility_bar.tsx @@ -38,6 +38,8 @@ interface Props { pagination: Pagination; selectedColumns: CasesColumnSelection[]; onSelectedColumnsChange: (columns: CasesColumnSelection[]) => void; + onClearFilters: () => void; + showClearFiltersButton: boolean; } export const CasesTableUtilityBar: FunctionComponent<Props> = React.memo( @@ -49,6 +51,8 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = React.memo( pagination, selectedColumns, onSelectedColumnsChange, + onClearFilters, + showClearFiltersButton, }) => { const { euiTheme } = useEuiTheme(); const refreshCases = useRefreshCases(); @@ -212,6 +216,20 @@ export const CasesTableUtilityBar: FunctionComponent<Props> = React.memo( {i18n.REFRESH} </EuiButtonEmpty> </EuiFlexItem> + {showClearFiltersButton ? ( + <EuiFlexItem grow={false}> + <EuiButtonEmpty + onClick={onClearFilters} + size="xs" + iconSide="left" + iconType="cross" + flush="left" + data-test-subj="all-cases-clear-filters-link-icon" + > + {i18n.CLEAR_FILTERS} + </EuiButtonEmpty> + </EuiFlexItem> + ) : null} </EuiFlexGroup> </EuiFlexItem> </EuiFlexGroup> diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.test.ts b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.test.ts new file mode 100644 index 0000000000000..0b46456204dd2 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.test.ts @@ -0,0 +1,217 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CustomFieldTypes } from '../../../../common/types/domain'; +import { DEFAULT_CASES_TABLE_STATE } from '../../../containers/constants'; + +import { allCasesUrlStateDeserializer } from './all_cases_url_state_deserializer'; + +describe('allCasesUrlStateDeserializer', () => { + const { customFields, ...filterOptionsWithoutCustomFields } = + DEFAULT_CASES_TABLE_STATE.filterOptions; + + const defaultMap = { + ...filterOptionsWithoutCustomFields, + ...DEFAULT_CASES_TABLE_STATE.queryParams, + }; + + it('parses defaults correctly', () => { + expect(allCasesUrlStateDeserializer(defaultMap)).toMatchInlineSnapshot(` + Object { + "filterOptions": Object { + "assignees": Array [], + "category": Array [], + "owner": Array [], + "reporters": Array [], + "search": "", + "searchFields": Array [ + "title", + "description", + ], + "severity": Array [], + "status": Array [], + "tags": Array [], + }, + "queryParams": Object { + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + }, + } + `); + }); + + it('parses an empty object correctly', () => { + expect(allCasesUrlStateDeserializer({})).toMatchInlineSnapshot(` + Object { + "filterOptions": Object {}, + "queryParams": Object {}, + } + `); + }); + + it('does not return unknown values', () => { + // @ts-expect-error: testing unknown values + expect(allCasesUrlStateDeserializer({ foo: 'bar' })).toMatchInlineSnapshot(` + Object { + "filterOptions": Object {}, + "queryParams": Object {}, + } + `); + }); + + it('converts page to integer correctly', () => { + // @ts-expect-error: testing integer conversion + expect(allCasesUrlStateDeserializer({ page: '1' }).queryParams.page).toBe(1); + }); + + it('sets perPage to the maximum allowed value if it is set to over the limit', () => { + // @ts-expect-error: testing integer conversion + expect(allCasesUrlStateDeserializer({ perPage: '1000' }).queryParams.perPage).toBe(100); + }); + + it('converts perPage to integer correctly', () => { + // @ts-expect-error: testing integer conversion + expect(allCasesUrlStateDeserializer({ perPage: '2' }).queryParams.perPage).toBe(2); + }); + + it('sets the defaults to page and perPage correctly if they are not numbers', () => { + // @ts-expect-error: testing integer conversion + expect(allCasesUrlStateDeserializer({ page: 'foo', perPage: 'bar' }).queryParams.page).toBe( + DEFAULT_CASES_TABLE_STATE.queryParams.page + ); + + // @ts-expect-error: testing integer conversion + expect(allCasesUrlStateDeserializer({ page: 'foo', perPage: 'bar' }).queryParams.perPage).toBe( + DEFAULT_CASES_TABLE_STATE.queryParams.perPage + ); + }); + + it('does not return the page and perPage if they are not defined', () => { + expect(allCasesUrlStateDeserializer({})).toMatchInlineSnapshot(` + Object { + "filterOptions": Object {}, + "queryParams": Object {}, + } + `); + }); + + it('sets the sortOrder correctly', () => { + expect(allCasesUrlStateDeserializer({ sortOrder: 'asc' }).queryParams.sortOrder).toBe('asc'); + }); + + it('parses custom fields correctly', () => { + expect( + allCasesUrlStateDeserializer( + { + customFields: { + 'my-custom-field-1': ['foo', 'qux'], + 'my-custom-field-2': ['bar', 'baz'], + 'my-custom-field-4': [], + }, + }, + [ + { + key: 'my-custom-field-1', + type: CustomFieldTypes.TOGGLE, + required: false, + label: 'foo', + }, + { + key: 'my-custom-field-2', + type: CustomFieldTypes.TOGGLE, + required: false, + label: 'foo', + }, + { + key: 'my-custom-field-4', + type: CustomFieldTypes.TOGGLE, + required: false, + label: 'foo', + }, + ] + ) + ).toMatchInlineSnapshot(` + Object { + "filterOptions": Object { + "customFields": Object { + "my-custom-field-1": Object { + "options": Array [ + "foo", + "qux", + ], + "type": "toggle", + }, + "my-custom-field-2": Object { + "options": Array [ + "bar", + "baz", + ], + "type": "toggle", + }, + "my-custom-field-4": Object { + "options": Array [], + "type": "toggle", + }, + }, + }, + "queryParams": Object {}, + } + `); + }); + + it('removes unknown custom fields', () => { + expect( + allCasesUrlStateDeserializer( + { + customFields: { + 'my-custom-field-1': ['foo', 'qux'], + 'my-custom-field-2': ['bar', 'baz'], + }, + }, + [ + { + key: 'my-custom-field-1', + type: CustomFieldTypes.TOGGLE, + required: false, + label: 'foo', + }, + ] + ) + ).toMatchInlineSnapshot(` + Object { + "filterOptions": Object { + "customFields": Object { + "my-custom-field-1": Object { + "options": Array [ + "foo", + "qux", + ], + "type": "toggle", + }, + }, + }, + "queryParams": Object {}, + } + `); + }); + + it('parses none assignees correctly', () => { + expect(allCasesUrlStateDeserializer({ assignees: ['none', 'elastic'] })).toMatchInlineSnapshot(` + Object { + "filterOptions": Object { + "assignees": Array [ + null, + "elastic", + ], + }, + "queryParams": Object {}, + } + `); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.ts b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.ts new file mode 100644 index 0000000000000..d07f693f2907c --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_deserializer.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty } from 'lodash'; +import { NO_ASSIGNEES_FILTERING_KEYWORD } from '../../../../common/constants'; +import type { QueryParams, FilterOptions, CasesConfigurationUI } from '../../../../common/ui'; +import { DEFAULT_CASES_TABLE_STATE } from '../../../containers/constants'; +import type { AllCasesURLQueryParams, AllCasesURLState } from '../types'; +import { sanitizeState } from './sanitize_state'; +import { stringToIntegerWithDefault } from '.'; + +export const allCasesUrlStateDeserializer = ( + urlParamsMap: AllCasesURLQueryParams, + customFieldsConfiguration: CasesConfigurationUI['customFields'] = [] +): AllCasesURLState => { + const queryParams: Partial<QueryParams> & Record<string, unknown> = {}; + const filterOptions: Partial<FilterOptions> & Record<string, unknown> = {}; + + for (const [key, value] of Object.entries(urlParamsMap)) { + if (Object.hasOwn(DEFAULT_CASES_TABLE_STATE.queryParams, key)) { + queryParams[key] = value; + } + + if (Object.hasOwn(DEFAULT_CASES_TABLE_STATE.filterOptions, key)) { + filterOptions[key] = value; + } + } + + const { page, perPage, ...restQueryParams } = queryParams; + const { assignees, customFields, ...restFilterOptions } = filterOptions; + + const queryParamsParsed: Partial<QueryParams> = { + ...restQueryParams, + }; + + const filterOptionsParsed: Partial<FilterOptions> = { + ...restFilterOptions, + }; + + if (page) { + queryParamsParsed.page = stringToIntegerWithDefault( + page, + DEFAULT_CASES_TABLE_STATE.queryParams.page + ); + } + + if (perPage) { + queryParamsParsed.perPage = stringToIntegerWithDefault( + perPage, + DEFAULT_CASES_TABLE_STATE.queryParams.perPage + ); + } + + if (assignees) { + filterOptionsParsed.assignees = assignees.map((assignee) => + assignee === NO_ASSIGNEES_FILTERING_KEYWORD ? null : assignee + ); + } + + const customFieldsParams = Object.entries(customFields ?? {}).reduce((acc, [key, value]) => { + const foundCustomField = customFieldsConfiguration.find((cf) => cf.key === key); + + if (!foundCustomField) { + return acc; + } + + return { ...acc, [key]: { type: foundCustomField.type, options: value } }; + }, {}); + + const state: AllCasesURLState = { + queryParams: queryParamsParsed, + filterOptions: { + ...filterOptionsParsed, + ...(!isEmpty(customFieldsParams) && { + customFields: customFieldsParams, + }), + }, + }; + + return sanitizeState(state); +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.test.ts b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.test.ts new file mode 100644 index 0000000000000..0e129cdc69489 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.test.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CustomFieldTypes } from '../../../../common/types/domain'; +import { DEFAULT_QUERY_PARAMS, DEFAULT_FILTER_OPTIONS } from '../../../containers/constants'; + +import { allCasesUrlStateSerializer } from './all_cases_url_state_serializer'; + +describe('allCasesUrlStateSerializer', () => { + it('serializes correctly with default values', () => { + expect( + allCasesUrlStateSerializer({ + filterOptions: DEFAULT_FILTER_OPTIONS, + queryParams: DEFAULT_QUERY_PARAMS, + }) + ).toMatchInlineSnapshot(` + Object { + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + } + `); + }); + + it('serializes custom fields correctly', () => { + expect( + allCasesUrlStateSerializer({ + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + customFields: { + foo: { type: CustomFieldTypes.TEXT, options: ['bar'] }, + bar: { type: CustomFieldTypes.TEXT, options: ['foo'] }, + }, + }, + queryParams: DEFAULT_QUERY_PARAMS, + }) + ).toMatchInlineSnapshot(` + Object { + "customFields": Object { + "bar": Array [ + "foo", + ], + "foo": Array [ + "bar", + ], + }, + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + } + `); + }); + + it('removes unsupported filter options', () => { + expect( + allCasesUrlStateSerializer({ + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + searchFields: ['title'], + reporters: [{ username: 'elastic', email: null, full_name: null }], + owner: ['cases'], + }, + queryParams: DEFAULT_QUERY_PARAMS, + }) + ).toMatchInlineSnapshot(` + Object { + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + } + `); + }); + + it('removes empty values', () => { + expect( + allCasesUrlStateSerializer({ + filterOptions: { ...DEFAULT_FILTER_OPTIONS, status: [], search: '', customFields: {} }, + queryParams: DEFAULT_QUERY_PARAMS, + }) + ).toMatchInlineSnapshot(` + Object { + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + } + `); + }); + + it('converts null assignees correctly', () => { + expect( + allCasesUrlStateSerializer({ + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + assignees: [null, 'elastic'], + }, + queryParams: DEFAULT_QUERY_PARAMS, + }) + ).toMatchInlineSnapshot(` + Object { + "assignees": Array [ + "none", + "elastic", + ], + "page": 1, + "perPage": 10, + "sortField": "createdAt", + "sortOrder": "desc", + } + `); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.ts b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.ts new file mode 100644 index 0000000000000..e5faeb6f36f90 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/all_cases_url_state_serializer.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty, pick, isNumber } from 'lodash'; +import { NO_ASSIGNEES_FILTERING_KEYWORD } from '../../../../common/constants'; +import type { AllCasesURLQueryParams, AllCasesTableState } from '../types'; + +export const allCasesUrlStateSerializer = (state: AllCasesTableState): AllCasesURLQueryParams => { + const supportedFilterOptions = pick(state.filterOptions, [ + 'search', + 'severity', + 'status', + 'tags', + 'assignees', + 'category', + ]); + + const customFieldsAsQueryParams = Object.entries(state.filterOptions.customFields).reduce( + (acc, [key, value]) => { + if (isEmpty(value.options)) { + return acc; + } + + return { ...acc, [key]: value.options }; + }, + {} + ); + + const combinedState = { + ...state.queryParams, + page: state.queryParams.page, + perPage: state.queryParams.perPage, + ...supportedFilterOptions, + assignees: supportedFilterOptions.assignees.map((assignee) => + assignee === null ? NO_ASSIGNEES_FILTERING_KEYWORD : assignee + ), + customFields: customFieldsAsQueryParams, + }; + + // filters empty values + return Object.entries(combinedState).reduce((acc, [key, value]) => { + // isEmpty returns true for numbers + if (isEmpty(value) && !isNumber(value)) { + return acc; + } + + return Object.assign(acc, { [key]: value }); + }, {}); +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/index.test.ts b/x-pack/plugins/cases/public/components/all_cases/utils/index.test.ts new file mode 100644 index 0000000000000..98eeef78f9765 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/index.test.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + isFlattenCustomField, + flattenCustomFieldKey, + deflattenCustomFieldKey, + stringToInteger, + stringToIntegerWithDefault, +} from '.'; + +describe('utils', () => { + describe('isFlattenCustomField', () => { + it('returns true if the key is prefixed with cf_', () => { + expect(isFlattenCustomField('cf_foo')).toBe(true); + }); + + it('returns false if the key is not prefixed with cf_', () => { + expect(isFlattenCustomField('foo')).toBe(false); + }); + }); + + describe('flattenCustomFieldKey', () => { + it('flattens a custom field key correctly', () => { + expect(flattenCustomFieldKey('foo')).toBe('cf_foo'); + }); + }); + + describe('deflattenCustomFieldKey', () => { + it('deflattens a custom field key correctly', () => { + expect(deflattenCustomFieldKey('cf_foo')).toBe('foo'); + }); + }); + + describe('stringToInteger', () => { + it('converts a number correctly', () => { + expect(stringToInteger(5)).toBe(5); + }); + + it('converts a string to a number correctly', () => { + expect(stringToInteger('5')).toBe(5); + }); + + it('returns undefined if the value cannot converted to a number', () => { + expect(stringToInteger('foo')).toBe(undefined); + }); + }); + + describe('stringToIntegerWithDefault', () => { + it('converts a string to a number correctly', () => { + expect(stringToIntegerWithDefault('5', 10)).toBe(5); + }); + + it('sets the default value correctly if the number is zero', () => { + expect(stringToIntegerWithDefault(0, 10)).toBe(10); + }); + + it('sets the default value correctly if the value is not a number', () => { + expect(stringToIntegerWithDefault('foo', 10)).toBe(10); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/index.ts b/x-pack/plugins/cases/public/components/all_cases/utils/index.ts index bbc48210bfaa2..762882834b8ee 100644 --- a/x-pack/plugins/cases/public/components/all_cases/utils/index.ts +++ b/x-pack/plugins/cases/public/components/all_cases/utils/index.ts @@ -5,71 +5,31 @@ * 2.0. */ -import { difference } from 'lodash'; -import type { ParsedUrlQueryParams, PartialQueryParams } from '../../../../common/ui/types'; -import type { CasesColumnSelection } from '../types'; -import type { CasesColumnsConfiguration } from '../use_cases_columns_configuration'; +import { CUSTOM_FIELD_KEY_PREFIX } from '../constants'; -export const parseUrlQueryParams = (parsedUrlParams: ParsedUrlQueryParams): PartialQueryParams => { - const urlParams: PartialQueryParams = { - ...(parsedUrlParams.sortField && { sortField: parsedUrlParams.sortField }), - ...(parsedUrlParams.sortOrder && { sortOrder: parsedUrlParams.sortOrder }), - }; +export const isFlattenCustomField = (key: string): boolean => + key.startsWith(CUSTOM_FIELD_KEY_PREFIX); - const intPage = parsedUrlParams.page && parseInt(parsedUrlParams.page, 10); - const intPerPage = parsedUrlParams.perPage && parseInt(parsedUrlParams.perPage, 10); +export const flattenCustomFieldKey = (key: string): string => `${CUSTOM_FIELD_KEY_PREFIX}${key}`; - // page=0 is deliberately ignored - if (intPage) { - urlParams.page = intPage; - } +export const deflattenCustomFieldKey = (key: string): string => + key.replace(CUSTOM_FIELD_KEY_PREFIX, ''); + +export const stringToInteger = (value?: string | number): number | undefined => { + const num = Number(value); - // perPage=0 is deliberately ignored - if (intPerPage) { - urlParams.perPage = intPerPage; + if (isNaN(num)) { + return; } - return urlParams; + return num; }; -export const mergeSelectedColumnsWithConfiguration = ({ - selectedColumns, - casesColumnsConfig, -}: { - selectedColumns: CasesColumnSelection[]; - casesColumnsConfig: CasesColumnsConfiguration; -}): CasesColumnSelection[] => { - const result = selectedColumns.reduce((accumulator, { field, isChecked }) => { - if ( - field in casesColumnsConfig && - casesColumnsConfig[field].field !== '' && - casesColumnsConfig[field].canDisplay - ) { - accumulator.push({ - field: casesColumnsConfig[field].field, - name: casesColumnsConfig[field].name, - isChecked, - }); - } - return accumulator; - }, [] as CasesColumnSelection[]); - - // This will include any new customFields and/or changes to the case attributes - const missingColumns = difference( - Object.keys(casesColumnsConfig), - selectedColumns.map(({ field }) => field) - ); - - missingColumns.forEach((field) => { - // can be an empty string - if (casesColumnsConfig[field].field && casesColumnsConfig[field].canDisplay) { - result.push({ - field: casesColumnsConfig[field].field, - name: casesColumnsConfig[field].name, - isChecked: casesColumnsConfig[field].isCheckedDefault, - }); - } - }); +export const stringToIntegerWithDefault = ( + value: string | number, + defaultValue: number +): number | undefined => { + const valueAsInteger = stringToInteger(value); - return result; + return valueAsInteger && valueAsInteger > 0 ? valueAsInteger : defaultValue; }; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/merge_selected_columns_with_configuration.ts b/x-pack/plugins/cases/public/components/all_cases/utils/merge_selected_columns_with_configuration.ts new file mode 100644 index 0000000000000..c56c5e70aed7e --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/merge_selected_columns_with_configuration.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { difference } from 'lodash'; +import type { CasesColumnSelection } from '../types'; +import type { CasesColumnsConfiguration } from '../use_cases_columns_configuration'; + +export const mergeSelectedColumnsWithConfiguration = ({ + selectedColumns, + casesColumnsConfig, +}: { + selectedColumns: CasesColumnSelection[]; + casesColumnsConfig: CasesColumnsConfiguration; +}): CasesColumnSelection[] => { + const result = selectedColumns.reduce((accumulator, { field, isChecked }) => { + if ( + field in casesColumnsConfig && + casesColumnsConfig[field].field !== '' && + casesColumnsConfig[field].canDisplay + ) { + accumulator.push({ + field: casesColumnsConfig[field].field, + name: casesColumnsConfig[field].name, + isChecked, + }); + } + return accumulator; + }, [] as CasesColumnSelection[]); + + // This will include any new customFields and/or changes to the case attributes + const missingColumns = difference( + Object.keys(casesColumnsConfig), + selectedColumns.map(({ field }) => field) + ); + + missingColumns.forEach((field) => { + // can be an empty string + if (casesColumnsConfig[field].field && casesColumnsConfig[field].canDisplay) { + result.push({ + field: casesColumnsConfig[field].field, + name: casesColumnsConfig[field].name, + isChecked: casesColumnsConfig[field].isCheckedDefault, + }); + } + }); + + return result; +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.test.tsx new file mode 100644 index 0000000000000..7daa7166f051b --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.test.tsx @@ -0,0 +1,254 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { encode } from '@kbn/rison'; +import { DEFAULT_FILTER_OPTIONS, DEFAULT_QUERY_PARAMS } from '../../../containers/constants'; + +import { parseUrlParams } from './parse_url_params'; + +describe('parseUrlParams', () => { + const defaultValuesAsURL = new URLSearchParams({ + cases: encode({ + ...DEFAULT_FILTER_OPTIONS, + ...DEFAULT_QUERY_PARAMS, + }), + }); + + it('parses the default filter options and query params correctly', () => { + expect(parseUrlParams(defaultValuesAsURL)).toMatchInlineSnapshot(` + Object { + "assignees": Array [], + "category": Array [], + "customFields": Object {}, + "page": 1, + "perPage": 10, + "search": "", + "severity": Array [], + "sortField": "createdAt", + "sortOrder": "desc", + "status": Array [], + "tags": Array [], + } + `); + }); + + it('parses a mix of fields correctly', () => { + const state = { + assignees: ['elastic'], + tags: ['a', 'b'], + category: [], + status: ['open'], + search: 'My title', + owner: ['cases'], + customFields: { my_field: ['foo'] }, + }; + + const url = `cases=${encode(state)}`; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "assignees": Array [ + "elastic", + ], + "category": Array [], + "customFields": Object { + "my_field": Array [ + "foo", + ], + }, + "search": "My title", + "status": Array [ + "open", + ], + "tags": Array [ + "a", + "b", + ], + } + `); + }); + + it('protects against prototype attacks', () => { + const firstUrl = 'cases=(customFields:(__proto__:!(foo)))'; + const secondUrl = 'cases=(customFields:(__proto__:(property:payload)))'; + + // @ts-expect-error: testing prototype attacks + expect(parseUrlParams(new URLSearchParams(firstUrl)).__proto__).toEqual({}); + // @ts-expect-error: testing prototype attacks + expect(parseUrlParams(new URLSearchParams(secondUrl)).__proto__).toEqual({}); + }); + + it('parses empty query params correctly', () => { + expect(parseUrlParams(new URLSearchParams())).toMatchInlineSnapshot(`Object {}`); + }); + + it('parses an empty string correctly', () => { + expect(parseUrlParams(new URLSearchParams(''))).toMatchInlineSnapshot(`Object {}`); + }); + + it('parses an unrecognized query param correctly', () => { + expect(parseUrlParams(new URLSearchParams('foo='))).toMatchInlineSnapshot(`Object {}`); + }); + + it('parses an empty string correctly in the cases object correctly', () => { + expect(parseUrlParams(new URLSearchParams({ cases: '' }))).toMatchInlineSnapshot(`Object {}`); + }); + + it('parses a malformed rison url correctly', () => { + expect(parseUrlParams(new URLSearchParams({ cases: '!' }))).toMatchInlineSnapshot(`Object {}`); + }); + + it('parses a rison url that is not an object correctly', () => { + for (const value of ['foo', true, false, ['bar'], null, 0]) { + expect(parseUrlParams(new URLSearchParams({ cases: encode(value) }))).toEqual({}); + } + }); + + it('validates the query params schema correctly', () => { + expect( + parseUrlParams(new URLSearchParams({ cases: encode({ status: 'foo' }) })) + ).toMatchInlineSnapshot(`Object {}`); + }); + + describe('legacy URLs', () => { + it('parses a legacy url with all legacy supported keys correctly', () => { + const url = 'status=open&severity=low&page=2&perPage=50&sortField=closedAt&sortOrder=asc'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "page": 2, + "perPage": 50, + "severity": Array [ + "low", + ], + "sortField": "closedAt", + "sortOrder": "asc", + "status": Array [ + "open", + ], + } + `); + }); + + it('parses a url with status=open,closed', () => { + const url = 'status=open,closed'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "status": Array [ + "open", + "closed", + ], + } + `); + }); + + it('parses a url with status=in-progress', () => { + const url = 'status=in-progress'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "status": Array [ + "in-progress", + ], + } + `); + }); + + it('parses a url with status=open&status=closed', () => { + const url = 'status=open&status=closed'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "status": Array [ + "open", + "closed", + ], + } + `); + }); + + it('parses a url with status=open,closed&status=in-progress', () => { + const url = 'status=open,closed&status=in-progress'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "status": Array [ + "open", + "closed", + "in-progress", + ], + } + `); + }); + + it('parses a url with severity=low,medium&severity=high,critical', () => { + const url = 'severity=low,medium&severity=high,critical'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "severity": Array [ + "low", + "medium", + "high", + "critical", + ], + } + `); + }); + + it('parses a url with severity=low,medium&severity=high&severity=critical', () => { + const url = 'severity=low,medium&severity=high&severity=critical'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "severity": Array [ + "low", + "medium", + "high", + "critical", + ], + } + `); + }); + + it('parses a url with page=2&page=5&perPage=4&perPage=20', () => { + const url = 'page=2&page=5&perPage=4&perPage=20'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "page": 2, + "perPage": 4, + } + `); + }); + + it('validates the query params schema correctly', () => { + const url = 'status=foo'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(`Object {}`); + }); + + it('sets the defaults to page and perPage correctly if they are not numbers', () => { + const url = 'page=foo&perPage=bar'; + + expect(parseUrlParams(new URLSearchParams(url))).toMatchInlineSnapshot(` + Object { + "page": 1, + "perPage": 10, + } + `); + }); + + it('protects against prototype attacks', () => { + const url = '__proto__[property]=payload'; + + // @ts-expect-error: testing prototype attacks + expect(parseUrlParams(new URLSearchParams(url)).__proto__.property).toEqual(undefined); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.tsx new file mode 100644 index 0000000000000..7e67cdfab89b2 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_params.tsx @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { safeDecode } from '@kbn/rison'; +import { isPlainObject } from 'lodash'; +import type { CaseStatuses } from '@kbn/cases-components'; +import type { CaseSeverity } from '../../../../common'; +import { DEFAULT_CASES_TABLE_STATE } from '../../../containers/constants'; +import { stringToIntegerWithDefault } from '.'; +import { SortFieldCase } from '../../../../common/ui'; +import { LEGACY_SUPPORTED_STATE_KEYS, ALL_CASES_STATE_URL_KEY } from '../constants'; +import { AllCasesURLQueryParamsRt, validateSchema } from '../schema'; +import type { AllCasesURLQueryParams } from '../types'; + +type LegacySupportedKeys = typeof LEGACY_SUPPORTED_STATE_KEYS[number]; + +const legacyDefaultState: Record<LegacySupportedKeys, string | number | string[]> = { + page: 1, + perPage: 10, + sortField: SortFieldCase.createdAt, + sortOrder: 'desc', + status: [], + severity: [], +}; + +/** + * Parses legacy state in URL. + * + * - Parameters in the query string can have multiple formats: + * 1. Comma-separated values (e.g., "status=foo,bar") + * 2. A single value (e.g., "status=foo") + * 3. Repeated keys (e.g., "status=foo&status=bar") + * + */ +const parseLegacyUrl = (urlParams: URLSearchParams): AllCasesURLQueryParams => { + const urlParamsMap = new Map<string, Set<string>>(); + + urlParams.forEach((value, key) => { + if (LEGACY_SUPPORTED_STATE_KEYS.includes(key as LegacySupportedKeys)) { + const values = urlParamsMap.get(key) ?? new Set(); + + value + .split(',') + .filter(Boolean) + .forEach((urlValue) => values.add(urlValue)); + + urlParamsMap.set(key, values); + } + }); + + const entries = new Map( + [...urlParamsMap].map(([key, value]) => [ + key, + parseValue(value, legacyDefaultState[key as LegacySupportedKeys]), + ]) + ); + + const params = Object.fromEntries(entries.entries()); + const allCasesParams: AllCasesURLQueryParams = { ...params }; + + if (params.page) { + allCasesParams.page = stringToIntegerWithDefault( + Array.isArray(params.page) ? params.page[0] : params.page, + DEFAULT_CASES_TABLE_STATE.queryParams.page + ); + } + + if (params.perPage) { + allCasesParams.perPage = stringToIntegerWithDefault( + Array.isArray(params.perPage) ? params.perPage[0] : params.perPage, + DEFAULT_CASES_TABLE_STATE.queryParams.perPage + ); + } + + if (params.status) { + const statusAsArray = Array.isArray(params.status) ? params.status : [params.status]; + allCasesParams.status = statusAsArray.filter(notAll).filter(Boolean) as CaseStatuses[]; + } + + if (params.severity) { + const severityAsArray = Array.isArray(params.severity) ? params.severity : [params.severity]; + allCasesParams.severity = severityAsArray.filter(notAll).filter(Boolean) as CaseSeverity[]; + } + + return allCasesParams; +}; + +const parseValue = (values: Set<string>, defaultValue: unknown): string | string[] => { + const valuesAsArray = Array.from(values.values()); + return Array.isArray(defaultValue) ? valuesAsArray : valuesAsArray[0] ?? ''; +}; + +const notAll = (option: string) => option !== 'all'; + +export function parseUrlParams(urlParams: URLSearchParams): AllCasesURLQueryParams { + const allCasesParams = urlParams.get(ALL_CASES_STATE_URL_KEY); + + if (!allCasesParams) { + return parseAndValidateLegacyUrl(urlParams); + } + + const parsedAllCasesParams = safeDecode(allCasesParams); + + if (!parsedAllCasesParams || !isPlainObject(parsedAllCasesParams)) { + return {}; + } + + const validatedAllCasesParams = validateSchema(parsedAllCasesParams, AllCasesURLQueryParamsRt); + + if (!validatedAllCasesParams) { + return {}; + } + + return validatedAllCasesParams; +} + +const parseAndValidateLegacyUrl = (urlParams: URLSearchParams): AllCasesURLQueryParams => { + const validatedUrlParams = validateSchema(parseLegacyUrl(urlParams), AllCasesURLQueryParamsRt); + + if (!validatedUrlParams) { + return {}; + } + + return validatedUrlParams; +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.test.tsx deleted file mode 100644 index 2cfa14f3af328..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// This file was contributed to by generative AI - -import { parseURLWithFilterOptions } from './parse_url_with_filter_options'; - -describe('parseURLWithFilterOptions', () => { - it('parses a url with search=foo', () => { - const url = 'search=foo'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ search: 'foo' }); - }); - - it('parses a url with status=foo,bar', () => { - const url = 'status=foo,bar'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ status: ['foo', 'bar'] }); - }); - - it('parses a url with status=foo', () => { - const url = 'status=foo'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ status: ['foo'] }); - }); - - it('parses a url with status=foo&status=bar', () => { - const url = 'status=foo&status=bar'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ status: ['foo', 'bar'] }); - }); - - it('parses a url with status=foo,bar&status=baz', () => { - const url = 'status=foo,bar&status=baz'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ status: ['foo', 'bar', 'baz'] }); - }); - - it('parses a url with status=foo,bar&status=baz,qux', () => { - const url = 'status=foo,bar&status=baz,qux'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ - status: ['foo', 'bar', 'baz', 'qux'], - }); - }); - - it('parses a url with status=foo,bar&status=baz,qux&status=quux', () => { - const url = 'status=foo,bar&status=baz,qux&status=quux'; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ - status: ['foo', 'bar', 'baz', 'qux', 'quux'], - }); - }); - - it('parses a url with status=', () => { - const url = 'status='; - expect(parseURLWithFilterOptions(url)).toStrictEqual({ status: [] }); - }); -}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.tsx deleted file mode 100644 index 6467dc99ab440..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/parse_url_with_filter_options.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DEFAULT_FILTER_OPTIONS } from '../../../containers/constants'; - -/** - * Parses filter options from a URL query string. - * - * The behavior is influenced by the predefined DEFAULT_FILTER_OPTIONS: - * - If an option is defined as an array there, it will always be returned as an array. - * - Parameters in the query string can have multiple formats: - * 1. Comma-separated values (e.g., "status=foo,bar") - * 2. A single value (e.g., "status=foo") - * 3. Repeated keys (e.g., "status=foo&status=bar") - * - * This function ensures the output respects the format indicated in DEFAULT_FILTER_OPTIONS. - */ -export const parseURLWithFilterOptions = (search: string) => { - const urlParams = new URLSearchParams(search); - - const paramKeysWithTypeArray = Object.entries(DEFAULT_FILTER_OPTIONS) - .map(([key, val]) => (Array.isArray(val) ? key : undefined)) - .filter(Boolean); - - const parsedUrlParams: { [key in string]: string[] | string } = {}; - for (const [key, value] of urlParams.entries()) { - if (paramKeysWithTypeArray.includes(key)) { - if (!parsedUrlParams[key]) parsedUrlParams[key] = []; - // only applies if the value is separated by commas (e.g., "foo,bar") - const splittedValues = value.split(',').filter(Boolean); - (parsedUrlParams[key] as string[]).push(...splittedValues); - } else { - parsedUrlParams[key] = value; - } - } - - return parsedUrlParams; -}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.test.tsx deleted file mode 100644 index b96dbc40fe668..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.test.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// This file was contributed to by generative AI - -import { CaseStatuses, CaseSeverity } from '../../../../common/types/domain'; -import { removeLegacyValuesFromOptions, getStorableFilters } from './sanitize_filter_options'; - -describe('removeLegacyValuesFromOptions', () => { - it('should remove legacy values from options', () => { - const options: { - status: Array<CaseStatuses | 'all'>; - severity: Array<CaseSeverity | 'all'>; - } = { - status: ['all', CaseStatuses.open, CaseStatuses['in-progress'], 'all'], - severity: ['all', CaseSeverity.LOW, 'all'], - }; - - expect(removeLegacyValuesFromOptions(options)).toEqual({ - status: ['open', 'in-progress'], - severity: ['low'], - }); - }); -}); - -describe('getStorableFilters', () => { - it('should return the filters if provided', () => { - expect( - getStorableFilters({ - status: [CaseStatuses.open, CaseStatuses['in-progress']], - severity: [CaseSeverity.LOW], - }) - ).toEqual({ - status: [CaseStatuses.open, CaseStatuses['in-progress']], - severity: [CaseSeverity.LOW], - }); - }); - - it('should return undefined if no filters are provided', () => { - expect(getStorableFilters({})).toEqual({ status: undefined, severity: undefined }); - }); -}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.tsx deleted file mode 100644 index 498d2998a0a20..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_filter_options.tsx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { FilterOptions } from '../../../../common/ui/types'; -import type { CaseStatuses, CaseSeverity } from '../../../../common/types/domain'; - -const notAll = (option: string) => option !== 'all'; - -/** - * In earlier versions, the options 'status' and 'severity' could have a value of 'all'. - * This function ensures such legacy values are removed from the URL parameters to maintain - * backwards compatibility. - */ -export const removeLegacyValuesFromOptions = ({ - status: legacyStatus, - severity: legacySeverity, -}: { - status: Array<CaseStatuses | 'all'>; - severity: Array<CaseSeverity | 'all'>; -}): { status: CaseStatuses[]; severity: CaseSeverity[] } => { - return { - status: legacyStatus.filter(notAll).filter(Boolean) as CaseStatuses[], - severity: legacySeverity.filter(notAll).filter(Boolean) as CaseSeverity[], - }; -}; - -export const getStorableFilters = ( - filterOptions: Partial<FilterOptions> -): { status: CaseStatuses[] | undefined; severity: CaseSeverity[] | undefined } => { - const { status, severity } = filterOptions; - - return { severity, status }; -}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.test.ts b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.test.ts new file mode 100644 index 0000000000000..a23cbed01f4e2 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CaseStatuses } from '@kbn/cases-components'; +import { CaseSeverity } from '../../../../common'; +import { DEFAULT_CASES_TABLE_STATE } from '../../../containers/constants'; +import { sanitizeState } from './sanitize_state'; + +describe('sanitizeState', () => { + it('sanitize default state correctly', () => { + expect(sanitizeState(DEFAULT_CASES_TABLE_STATE)).toEqual(DEFAULT_CASES_TABLE_STATE); + }); + + it('sanitize perPage query param correctly if it is bigger than 100', () => { + expect(sanitizeState({ queryParams: { perPage: 1000 } })).toEqual({ + filterOptions: {}, + queryParams: { perPage: 100 }, + }); + }); + + it('sanitize sortOrder correctly', () => { + // @ts-expect-error: need to check unrecognized values + expect(sanitizeState({ queryParams: { sortOrder: 'foo' } })).toEqual({ + filterOptions: {}, + queryParams: { sortOrder: 'desc' }, + }); + }); + + it('returns empty state with no arguments', () => { + expect(sanitizeState()).toEqual({ + filterOptions: {}, + queryParams: {}, + }); + }); + + it('sanitize status correctly', () => { + // @ts-expect-error: need to check unrecognized values + expect(sanitizeState({ filterOptions: { status: ['foo', CaseStatuses.open] } })).toEqual({ + filterOptions: { status: ['open'] }, + queryParams: {}, + }); + }); + + it('sanitize severity correctly', () => { + // @ts-expect-error: need to check unrecognized values + expect(sanitizeState({ filterOptions: { severity: ['foo', CaseSeverity.MEDIUM] } })).toEqual({ + filterOptions: { severity: ['medium'] }, + queryParams: {}, + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.ts b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.ts new file mode 100644 index 0000000000000..a0553a5ade632 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/sanitize_state.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CaseStatuses } from '@kbn/cases-components'; +import { CaseSeverity } from '../../../../common'; +import { SORT_ORDER_VALUES } from '../../../../common/ui'; +import { DEFAULT_QUERY_PARAMS } from '../../../containers/constants'; +import type { AllCasesTableState } from '../types'; +import { CASES_TABLE_PER_PAGE_VALUES } from '../types'; + +interface PartialState { + queryParams?: Partial<AllCasesTableState['queryParams']>; + filterOptions?: Partial<AllCasesTableState['filterOptions']>; +} + +interface PartialParams { + queryParams: Partial<AllCasesTableState['queryParams']>; + filterOptions: Partial<AllCasesTableState['filterOptions']>; +} + +export const sanitizeState = (state: PartialState = {}): PartialParams => { + return { + queryParams: sanitizeQueryParams(state.queryParams) ?? {}, + filterOptions: sanitizeFilterOptions(state.filterOptions) ?? {}, + }; +}; + +const sanitizeQueryParams = ( + queryParams: PartialState['queryParams'] = {} +): PartialState['queryParams'] => { + const { perPage, sortOrder, ...restQueryParams } = queryParams; + + const queryParamsSanitized: PartialState['queryParams'] = { + ...restQueryParams, + }; + + if (perPage) { + queryParamsSanitized.perPage = Math.min( + perPage, + CASES_TABLE_PER_PAGE_VALUES[CASES_TABLE_PER_PAGE_VALUES.length - 1] + ); + } + + if (sortOrder) { + queryParamsSanitized.sortOrder = SORT_ORDER_VALUES.includes(sortOrder) + ? sortOrder + : DEFAULT_QUERY_PARAMS.sortOrder; + } + + return queryParamsSanitized; +}; + +const sanitizeFilterOptions = ( + filterOptions: PartialState['filterOptions'] = {} +): PartialState['filterOptions'] => { + const { status, severity, ...restFilterOptions } = filterOptions; + + const filterOptionsSanitized: PartialState['filterOptions'] = { + ...restFilterOptions, + }; + + if (status) { + filterOptionsSanitized.status = filterOutOptions(status, CaseStatuses); + } + + if (severity) { + filterOptionsSanitized.severity = filterOutOptions(severity, CaseSeverity); + } + + return filterOptionsSanitized; +}; + +const filterOutOptions = <T extends string>(collection: T[], validValues: Record<string, T>): T[] => + collection.filter((value) => Object.values(validValues).includes(value)); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.test.tsx deleted file mode 100644 index ace5fdda934ab..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.test.tsx +++ /dev/null @@ -1,77 +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 { serializeUrlParams } from './serialize_url_params'; - -describe('serializeUrlParams', () => { - const commonProps = { - page: '1', - perPage: '5', - sortField: 'createdAt', - sortOrder: 'desc', - }; - - it('empty severity and status', () => { - const urlParams = { - ...commonProps, - status: [], - severity: [], - }; - - expect(serializeUrlParams(urlParams).toString()).toEqual( - 'page=1&perPage=5&sortField=createdAt&sortOrder=desc&status=&severity=' - ); - }); - - it('severity and status with one value', () => { - const urlParams = { - ...commonProps, - status: ['open'], - severity: ['low'], - }; - - expect(serializeUrlParams(urlParams).toString()).toEqual( - 'page=1&perPage=5&sortField=createdAt&sortOrder=desc&status=open&severity=low' - ); - }); - - it('severity and status with multiple values', () => { - const urlParams = { - ...commonProps, - status: ['open', 'closed'], - severity: ['low', 'high'], - }; - - expect(serializeUrlParams(urlParams).toString()).toEqual( - 'page=1&perPage=5&sortField=createdAt&sortOrder=desc&status=open&status=closed&severity=low&severity=high' - ); - }); - - it('severity and status are undefined', () => { - const urlParams = { - ...commonProps, - status: undefined, - severity: undefined, - }; - - expect(serializeUrlParams(urlParams).toString()).toEqual( - 'page=1&perPage=5&sortField=createdAt&sortOrder=desc' - ); - }); - - it('severity and status are undefined but there are more filters to serialize', () => { - const urlParams = { - status: undefined, - severity: undefined, - ...commonProps, - }; - - expect(serializeUrlParams(urlParams).toString()).toEqual( - 'page=1&perPage=5&sortField=createdAt&sortOrder=desc' - ); - }); -}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.tsx deleted file mode 100644 index 4b3e352b894d0..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/serialize_url_params.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export function serializeUrlParams(urlParams: { - [key in string]: string[] | string | undefined; -}) { - const urlSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(urlParams)) { - if (value) { - if (Array.isArray(value)) { - if (value.length === 0) { - urlSearchParams.append(key, ''); - } else { - value.forEach((v) => urlSearchParams.append(key, v)); - } - } else { - urlSearchParams.append(key, value); - } - } - } - - return urlSearchParams; -} diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.test.tsx new file mode 100644 index 0000000000000..4f67764260bb3 --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.test.tsx @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CaseStatuses } from '@kbn/cases-components'; +import { DEFAULT_CASES_TABLE_STATE } from '../../../containers/constants'; +import { CaseSeverity } from '../../../../common'; +import { SortFieldCase } from '../../../../common/ui'; +import { stringifyUrlParams } from './stringify_url_params'; + +describe('stringifyUrlParams', () => { + const commonProps = { + page: 1, + perPage: 5, + sortField: SortFieldCase.createdAt, + sortOrder: 'desc' as const, + }; + + it('empty severity and status', () => { + const urlParams = { + ...commonProps, + status: [], + severity: [], + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(page:1,perPage:5,severity:!(),sortField:createdAt,sortOrder:desc,status:!())"` + ); + }); + + it('severity and status with one value', () => { + const urlParams = { + ...commonProps, + status: [CaseStatuses.open], + severity: [CaseSeverity.LOW], + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(page:1,perPage:5,severity:!(low),sortField:createdAt,sortOrder:desc,status:!(open))"` + ); + }); + + it('severity and status with multiple values', () => { + const urlParams = { + ...commonProps, + status: [CaseStatuses.open, CaseStatuses.closed], + severity: [CaseSeverity.LOW, CaseSeverity.HIGH], + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(page:1,perPage:5,severity:!(low,high),sortField:createdAt,sortOrder:desc,status:!(open,closed))"` + ); + }); + + it('severity and status are undefined', () => { + const urlParams = { + ...commonProps, + status: undefined, + severity: undefined, + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(page:1,perPage:5,sortField:createdAt,sortOrder:desc)"` + ); + }); + + it('severity and status are undefined but there are more filters to serialize', () => { + const urlParams = { + status: undefined, + severity: undefined, + ...commonProps, + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(page:1,perPage:5,sortField:createdAt,sortOrder:desc)"` + ); + }); + + it('encodes defaults correctly', () => { + const { customFields, ...filterOptionsWithoutCustomFields } = + DEFAULT_CASES_TABLE_STATE.filterOptions; + + const urlParams = { + ...filterOptionsWithoutCustomFields, + ...DEFAULT_CASES_TABLE_STATE.queryParams, + customFields: { my_field: ['foo', 'bar'] }, + }; + + expect(stringifyUrlParams(urlParams)).toMatchInlineSnapshot( + `"cases=(assignees:!(),category:!(),customFields:(my_field:!(foo,bar)),owner:!(),page:1,perPage:10,reporters:!(),search:'',searchFields:!(title,description),severity:!(),sortField:createdAt,sortOrder:desc,status:!(),tags:!())"` + ); + }); + + it('replaces the cases query param correctly', () => { + expect( + stringifyUrlParams( + { + perPage: 100, + }, + 'cases=(perPage:5)' + ) + ).toMatchInlineSnapshot(`"cases=(perPage:100)"`); + }); + + it('removes legacy keys from URL', () => { + const search = 'status=foo&severity=foo&page=2&perPage=50&sortField=closedAt&sortOrder=asc'; + + expect( + stringifyUrlParams( + { + perPage: 100, + }, + search + ) + ).toMatchInlineSnapshot(`"cases=(perPage:100)"`); + }); + + it('keeps non cases state', () => { + expect( + stringifyUrlParams( + { + perPage: 100, + }, + 'foo=bar' + ) + ).toMatchInlineSnapshot(`"cases=(perPage:100)&foo=bar"`); + }); +}); diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.tsx new file mode 100644 index 0000000000000..8c43112c093aa --- /dev/null +++ b/x-pack/plugins/cases/public/components/all_cases/utils/stringify_url_params.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { encode } from '@kbn/rison'; +import { ALL_CASES_STATE_URL_KEY, LEGACY_SUPPORTED_STATE_KEYS } from '../constants'; +import type { AllCasesURLQueryParams } from '../types'; + +export function stringifyUrlParams( + allCasesUrlParams: AllCasesURLQueryParams, + currentSearch: string = '' +): string { + const encodedUrlParams = encode({ ...allCasesUrlParams }); + + const searchUrlParams = removeLegacyStateFromUrl( + new URLSearchParams(decodeURIComponent(currentSearch)) + ); + + searchUrlParams.delete(ALL_CASES_STATE_URL_KEY); + const casesQueryParam = `${ALL_CASES_STATE_URL_KEY}=${encodedUrlParams}`; + + return searchUrlParams.size > 0 + ? `${casesQueryParam}&${searchUrlParams.toString()}` + : casesQueryParam; +} + +const removeLegacyStateFromUrl = (urlParams: URLSearchParams): URLSearchParams => { + const newUrlParams = new URLSearchParams(urlParams); + LEGACY_SUPPORTED_STATE_KEYS.forEach((key) => newUrlParams.delete(key)); + + return newUrlParams; +}; diff --git a/x-pack/plugins/cases/public/components/all_cases/utils/utils.test.tsx b/x-pack/plugins/cases/public/components/all_cases/utils/utils.test.tsx deleted file mode 100644 index 3fdb9f035f417..0000000000000 --- a/x-pack/plugins/cases/public/components/all_cases/utils/utils.test.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { parseUrlQueryParams } from '.'; -import { DEFAULT_QUERY_PARAMS } from '../../../containers/constants'; - -const DEFAULT_STRING_QUERY_PARAMS = { - ...DEFAULT_QUERY_PARAMS, - page: String(DEFAULT_QUERY_PARAMS.page), - perPage: String(DEFAULT_QUERY_PARAMS.perPage), -}; - -describe('utils', () => { - describe('parseUrlQueryParams', () => { - it('valid input is processed correctly', () => { - expect(parseUrlQueryParams(DEFAULT_STRING_QUERY_PARAMS)).toStrictEqual(DEFAULT_QUERY_PARAMS); - }); - - it('empty string value for page/perPage is ignored', () => { - expect( - parseUrlQueryParams({ - ...DEFAULT_STRING_QUERY_PARAMS, - page: '', - perPage: '', - }) - ).toStrictEqual({ - sortField: DEFAULT_QUERY_PARAMS.sortField, - sortOrder: DEFAULT_QUERY_PARAMS.sortOrder, - }); - }); - - it('0 value for page/perPage is ignored', () => { - expect( - parseUrlQueryParams({ - ...DEFAULT_STRING_QUERY_PARAMS, - page: '0', - perPage: '0', - }) - ).toStrictEqual({ - sortField: DEFAULT_QUERY_PARAMS.sortField, - sortOrder: DEFAULT_QUERY_PARAMS.sortOrder, - }); - }); - - it('invalid string values for page/perPage are ignored', () => { - expect( - parseUrlQueryParams({ - ...DEFAULT_STRING_QUERY_PARAMS, - page: 'foo', - perPage: 'bar', - }) - ).toStrictEqual({ - sortField: DEFAULT_QUERY_PARAMS.sortField, - sortOrder: DEFAULT_QUERY_PARAMS.sortOrder, - }); - }); - - it('additional URL parameters are ignored', () => { - expect( - parseUrlQueryParams({ - ...DEFAULT_STRING_QUERY_PARAMS, - foo: 'bar', - }) - ).toStrictEqual(DEFAULT_QUERY_PARAMS); - }); - }); -}); diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index 97e84b8bbdc82..72fbbc24c15ec 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -179,6 +179,7 @@ export const removeItemFromSessionStorage = (key: string) => { export const stringifyToURL = (parsedParams: Record<string, string> | URLSearchParams) => new URLSearchParams(parsedParams).toString(); + export const parseURL = (queryString: string) => Object.fromEntries(new URLSearchParams(queryString)); diff --git a/x-pack/plugins/cases/public/containers/constants.ts b/x-pack/plugins/cases/public/containers/constants.ts index 76d95a8bd0375..54e7cebba9025 100644 --- a/x-pack/plugins/cases/public/containers/constants.ts +++ b/x-pack/plugins/cases/public/containers/constants.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { AllCasesTableState } from '../components/all_cases/types'; import type { FilterOptions, QueryParams, SingleCaseMetricsFeature } from './types'; import { SortFieldCase } from './types'; @@ -66,6 +67,7 @@ export const casesMutationsKeys = { const DEFAULT_SEARCH_FIELDS = ['title', 'description']; +// TODO: Remove reporters. Move searchFields to API. export const DEFAULT_FILTER_OPTIONS: FilterOptions = { search: '', searchFields: DEFAULT_SEARCH_FIELDS, @@ -85,3 +87,8 @@ export const DEFAULT_QUERY_PARAMS: QueryParams = { sortField: SortFieldCase.createdAt, sortOrder: 'desc', }; + +export const DEFAULT_CASES_TABLE_STATE: AllCasesTableState = { + filterOptions: DEFAULT_FILTER_OPTIONS, + queryParams: DEFAULT_QUERY_PARAMS, +}; diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index f231a8d69b548..ec596cf815833 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -71,6 +71,7 @@ "@kbn/alerting-plugin", "@kbn/content-management-plugin", "@kbn/index-management-plugin", + "@kbn/rison", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index b35f69de50dbd..0fda2e3915518 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -10999,7 +10999,6 @@ "xpack.cases.allCases.comments": "Commentaires", "xpack.cases.allCases.noCategoriesAvailable": "Pas de catégories disponibles", "xpack.cases.allCases.noTagsAvailable": "Aucune balise disponible", - "xpack.cases.allCasesView.filterAssignees.clearFilters": "Effacer les filtres", "xpack.cases.allCasesView.filterAssignees.noAssigneesLabel": "Aucun utilisateur affecté", "xpack.cases.allCasesView.filterAssigneesAriaLabel": "cliquer pour filtrer les utilisateurs affectés", "xpack.cases.allCasesView.showLessAvatars": "afficher moins", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f1ad2adee7dd7..a18a4202fc850 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -11013,7 +11013,6 @@ "xpack.cases.allCases.comments": "コメント", "xpack.cases.allCases.noCategoriesAvailable": "カテゴリがありません", "xpack.cases.allCases.noTagsAvailable": "利用可能なタグがありません", - "xpack.cases.allCasesView.filterAssignees.clearFilters": "フィルターを消去", "xpack.cases.allCasesView.filterAssignees.noAssigneesLabel": "担当者なし", "xpack.cases.allCasesView.filterAssigneesAriaLabel": "クリックすると、担当者でフィルタリングします", "xpack.cases.allCasesView.showLessAvatars": "縮小表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 16c8656569620..601cef213948a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11107,7 +11107,6 @@ "xpack.cases.allCases.comments": "注释", "xpack.cases.allCases.noCategoriesAvailable": "没有可用类别", "xpack.cases.allCases.noTagsAvailable": "没有可用标签", - "xpack.cases.allCasesView.filterAssignees.clearFilters": "清除筛选", "xpack.cases.allCasesView.filterAssignees.noAssigneesLabel": "无被分配人", "xpack.cases.allCasesView.filterAssigneesAriaLabel": "单击以筛选被分配人", "xpack.cases.allCasesView.showLessAvatars": "显示更少", diff --git a/x-pack/test/functional/services/cases/list.ts b/x-pack/test/functional/services/cases/list.ts index 03d1078ccec2c..f6ec13a492318 100644 --- a/x-pack/test/functional/services/cases/list.ts +++ b/x-pack/test/functional/services/cases/list.ts @@ -5,6 +5,9 @@ * 2.0. */ +import deepEqual from 'react-fast-compare'; +import expect from '@kbn/expect'; +import rison from '@kbn/rison'; import { CaseSeverity, CaseStatuses } from '@kbn/cases-plugin/common/types/domain'; import { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -100,6 +103,15 @@ export function CasesTableServiceProvider( await header.waitUntilLoadingHasFinished(); }, + async waitForNthToBeListed(numberOfCases: number) { + await retry.try(async () => { + await this.refreshTable(); + await this.validateCasesTableHasNthRows(numberOfCases); + }); + + await header.waitUntilLoadingHasFinished(); + }, + async waitForCasesToBeDeleted() { await retry.waitFor('the cases table to be empty', async () => { await this.refreshTable(); @@ -133,6 +145,13 @@ export function CasesTableServiceProvider( return rows[index] ?? null; }, + async verifyCase(caseId: string, index: number) { + const theCaseById = await this.getCaseById(caseId); + const theCaseByIndex = await this.getCaseByIndex(index); + + return (await theCaseById._webElement.getId()) === (await theCaseByIndex._webElement.getId()); + }, + async filterByTag(tag: string) { await common.clickAndValidate( 'options-filter-popover-button-tags', @@ -437,5 +456,54 @@ export function CasesTableServiceProvider( // closes the popover await browser.pressKeys(browser.keys.ESCAPE); }, + + async clearFilters() { + if (await testSubjects.exists('all-cases-clear-filters-link-icon')) { + await testSubjects.click('all-cases-clear-filters-link-icon'); + await header.waitUntilLoadingHasFinished(); + } + }, + + async setAllCasesStateInLocalStorage(state: Record<string, unknown>) { + await browser.setLocalStorageItem('management.cases.list.state', JSON.stringify(state)); + + const currentState = JSON.parse( + (await browser.getLocalStorageItem('management.cases.list.state')) ?? '{}' + ); + + expect(deepEqual(currentState, state)).to.be(true); + }, + + async getAllCasesStateInLocalStorage() { + const currentState = JSON.parse( + (await browser.getLocalStorageItem('management.cases.list.state')) ?? '{}' + ); + + return currentState; + }, + + async setFiltersConfigurationInLocalStorage(state: Array<{ key: string; isActive: boolean }>) { + await browser.setLocalStorageItem( + 'management.cases.list.tableFiltersConfig', + JSON.stringify(state) + ); + + const currentState = JSON.parse( + (await browser.getLocalStorageItem('management.cases.list.tableFiltersConfig')) ?? '{}' + ); + + expect(deepEqual(currentState, state)).to.be(true); + }, + + async expectFiltersToBeActive(filters: string[]) { + for (const filter of filters) { + await testSubjects.existOrFail(`options-filter-popover-button-${filter}`); + } + }, + + async setStateToUrlAndNavigate(state: Record<string, unknown>) { + const encodedUrlParams = rison.encode(state); + await common.navigateToApp('cases', { search: `cases=${encodedUrlParams}` }); + }, }; } diff --git a/x-pack/test/functional/services/cases/navigation.ts b/x-pack/test/functional/services/cases/navigation.ts index f0d4fb52ba5e4..5b827c0287a0f 100644 --- a/x-pack/test/functional/services/cases/navigation.ts +++ b/x-pack/test/functional/services/cases/navigation.ts @@ -12,13 +12,13 @@ export function CasesNavigationProvider({ getPageObject, getService }: FtrProvid const testSubjects = getService('testSubjects'); return { - async navigateToApp(app: string = 'cases', appSelector: string = 'cases-app') { - await common.navigateToApp(app); + async navigateToApp(app: string = 'cases', appSelector: string = 'cases-app', search?: string) { + await common.navigateToApp(app, { search }); await testSubjects.existOrFail(appSelector); }, - async navigateToConfigurationPage(app: string = 'cases', appSelector: string = 'cases-app') { - await this.navigateToApp(app, appSelector); + async navigateToConfigurationPage(app: string = 'cases') { + await this.navigateToApp(app, 'cases-app'); await common.clickAndValidate('configure-case-button', 'case-configure-title'); }, diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/group2/list_view.ts b/x-pack/test/functional_with_es_ssl/apps/cases/group2/list_view.ts index 32a1ef6125b7b..906e571941ff2 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/group2/list_view.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/group2/list_view.ts @@ -6,7 +6,12 @@ */ import expect from '@kbn/expect'; -import { CaseSeverity, CaseStatuses } from '@kbn/cases-plugin/common/types/domain'; +import rison from '@kbn/rison'; +import { + CaseSeverity, + CaseStatuses, + CustomFieldTypes, +} from '@kbn/cases-plugin/common/types/domain'; import { UserProfile } from '@kbn/user-profile-components'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { @@ -24,6 +29,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { describe('cases list', () => { before(async () => { + await cases.api.deleteAllCases(); await cases.navigation.navigateToApp(); }); @@ -280,13 +286,19 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { describe('filtering', () => { const caseTitle = 'matchme'; - const caseIds: string[] = []; - - before(async () => { - await createUsersAndRoles(getService, users, roles); - await cases.api.activateUserProfiles([casesAllUser, casesAllUser2]); - - const profiles = await cases.api.suggestUserProfiles({ name: 'all', owners: ['cases'] }); + let caseIds: string[] = []; + const profiles: UserProfile[] = []; + const customFields = [ + { + key: 'my_field_01', + label: 'My field', + type: CustomFieldTypes.TOGGLE, + required: false, + }, + ]; + + const createCases = async () => { + caseIds = []; const case1 = await cases.api.createCase({ title: caseTitle, @@ -309,18 +321,30 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { caseIds.push(case2.id); caseIds.push(case3.id); caseIds.push(case4.id); + }; + + before(async () => { + await cases.api.deleteAllCases(); + await createUsersAndRoles(getService, users, roles); + await cases.api.activateUserProfiles([casesAllUser, casesAllUser2]); + + profiles.push(...(await cases.api.suggestUserProfiles({ name: 'all', owners: ['cases'] }))); await header.waitUntilLoadingHasFinished(); - await cases.casesTable.waitForCasesToBeListed(); }); beforeEach(async () => { - /** - * There is no easy way to clear the filtering. - * Refreshing the page seems to be easier. - */ await browser.clearLocalStorage(); - await cases.navigation.navigateToApp(); + await cases.api.createConfigWithCustomFields({ customFields, owner: 'cases' }); + await createCases(); + await header.waitUntilLoadingHasFinished(); + await cases.casesTable.waitForCasesToBeListed(); + }); + + afterEach(async () => { + await cases.casesTable.clearFilters(); + await cases.api.deleteAllCases(); + await cases.casesTable.waitForCasesToBeDeleted(); }); after(async () => { @@ -500,6 +524,234 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.casesTable.validateCasesTableHasNthRows(2); }); + it('clears the filters correctly', async () => { + // filter by status first + await cases.casesTable.filterByTag('one'); + await cases.casesTable.validateCasesTableHasNthRows(1); + + await cases.casesTable.clearFilters(); + await cases.casesTable.validateCasesTableHasNthRows(caseIds.length); + }); + + it('loads the state from the local storage when the URL is empty', async () => { + await cases.casesTable.validateCasesTableHasNthRows(caseIds.length); + const lsState = { + filterOptions: { + search: '', + searchFields: ['title', 'description'], + severity: [], + assignees: [], + reporters: [], + status: [], + // filter by tags + tags: ['one'], + owner: [], + category: [], + customFields: {}, + }, + queryParams: { page: 1, perPage: 10, sortField: 'createdAt', sortOrder: 'desc' }, + }; + + await cases.casesTable.setAllCasesStateInLocalStorage(lsState); + + /** + * Clicking to the navigation bar (sidebar) clears out any query params + * added by the cases app. + */ + await testSubjects.click('cases'); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(caseIds[0], 0); + }); + + it('loads the state from the URL with empty filter configuration in local storage', async () => { + const theCase = await cases.api.createCase({ + title: 'url-testing', + assignees: [{ uid: profiles[0].uid }], + description: 'url testing', + category: 'url-testing', + tags: ['url'], + severity: CaseSeverity.CRITICAL, + customFields: [{ key: customFields[0].key, type: CustomFieldTypes.TOGGLE, value: true }], + }); + + const lsState = [ + { key: 'status', isActive: false }, + { key: 'severity', isActive: false }, + { key: 'tags', isActive: false }, + { key: 'assignees', isActive: false }, + { key: 'category', isActive: false }, + { key: `cf_${customFields[0].key}`, isActive: false }, + ]; + + await cases.casesTable.setFiltersConfigurationInLocalStorage(lsState); + await cases.casesTable.waitForNthToBeListed(caseIds.length + 1); + + const casesState = { + search: theCase.title, + severity: [theCase.severity], + status: [theCase.status], + tags: theCase.tags, + assignees: [profiles[0].uid], + category: [theCase.category], + customFields: { [customFields[0].key]: ['on'] }, + }; + + await cases.casesTable.setStateToUrlAndNavigate(casesState); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(theCase.id, 0); + + const currentUrl = decodeURIComponent(await browser.getCurrentUrl()); + expect(new URL(currentUrl).search).to.be(`?cases=${rison.encode(casesState)}`); + + await cases.casesTable.expectFiltersToBeActive([ + 'status', + 'severity', + 'tags', + 'category', + 'assignees', + customFields[0].key, + ]); + + const searchBar = await testSubjects.find('search-cases'); + expect(await searchBar.getAttribute('value')).to.be(casesState.search); + }); + + it('loads the state from the URL with filter configuration in local storage', async () => { + const theCase = await cases.api.createCase({ + title: 'url-testing', + assignees: [{ uid: profiles[0].uid }], + description: 'url testing', + category: 'url-testing', + tags: ['url'], + severity: CaseSeverity.CRITICAL, + customFields: [{ key: customFields[0].key, type: CustomFieldTypes.TOGGLE, value: true }], + }); + + await cases.casesTable.waitForNthToBeListed(caseIds.length + 1); + + const casesState = { + search: theCase.title, + severity: [theCase.severity], + status: [theCase.status], + tags: theCase.tags, + assignees: [profiles[0].uid], + category: [theCase.category], + customFields: { [customFields[0].key]: ['on'] }, + }; + + await cases.casesTable.setStateToUrlAndNavigate(casesState); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(theCase.id, 0); + + const currentUrl = decodeURIComponent(await browser.getCurrentUrl()); + expect(new URL(currentUrl).search).to.be(`?cases=${rison.encode(casesState)}`); + + await cases.casesTable.expectFiltersToBeActive([ + 'status', + 'severity', + 'tags', + 'category', + 'assignees', + customFields[0].key, + ]); + + const searchBar = await testSubjects.find('search-cases'); + expect(await searchBar.getAttribute('value')).to.be(casesState.search); + }); + + it('updates the local storage correctly when navigating to a URL', async () => { + const theCase = await cases.api.createCase({ + title: 'url-testing', + assignees: [{ uid: profiles[0].uid }], + description: 'url testing', + category: 'url-testing', + tags: ['url'], + severity: CaseSeverity.CRITICAL, + customFields: [{ key: customFields[0].key, type: CustomFieldTypes.TOGGLE, value: true }], + }); + + await cases.casesTable.waitForNthToBeListed(caseIds.length + 1); + + const casesState = { + search: theCase.title, + severity: [theCase.severity], + status: [theCase.status], + tags: theCase.tags, + assignees: [profiles[0].uid], + category: [theCase.category], + customFields: { [customFields[0].key]: ['on'] }, + }; + + await cases.casesTable.setStateToUrlAndNavigate(casesState); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(theCase.id, 0); + + const currentState = await cases.casesTable.getAllCasesStateInLocalStorage(); + + expect(currentState).to.eql({ + queryParams: { page: 1, perPage: 10, sortField: 'createdAt', sortOrder: 'desc' }, + filterOptions: { + search: theCase.title, + searchFields: ['title', 'description'], + severity: [theCase.severity], + assignees: [profiles[0].uid], + reporters: [], + status: [theCase.status], + tags: theCase.tags, + owner: [], + category: [theCase.category], + customFields: { my_field_01: { type: CustomFieldTypes.TOGGLE, options: ['on'] } }, + }, + }); + }); + + it('loads the state from a legacy URL', async () => { + const theCase = await cases.api.createCase({ + title: 'url-testing', + description: 'url testing', + severity: CaseSeverity.CRITICAL, + }); + + await cases.casesTable.waitForNthToBeListed(caseIds.length + 1); + + const search = `severity=${theCase.severity}&status=${theCase.status}&page=1&perPage=1sortField=createdAt&sortOrder=desc`; + + await cases.navigation.navigateToApp('cases', 'cases-app', search); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(theCase.id, 0); + + const currentUrl = decodeURIComponent(await browser.getCurrentUrl()); + expect(new URL(currentUrl).search).to.be(`?${search}`); + + await cases.casesTable.expectFiltersToBeActive([ + 'status', + 'severity', + 'tags', + 'category', + 'assignees', + ]); + }); + + it('navigating between pages keeps the state', async () => { + await cases.casesTable.filterByTag('one'); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(caseIds[0], 0); + await cases.casesTable.goToFirstListedCase(); + + await header.waitUntilLoadingHasFinished(); + await testSubjects.click('backToCases'); + + await header.waitUntilLoadingHasFinished(); + await cases.casesTable.waitForCasesToBeListed(); + await cases.casesTable.validateCasesTableHasNthRows(1); + await cases.casesTable.verifyCase(caseIds[0], 0); + }); + + it('loads the initial state correctly', async () => { + await cases.casesTable.validateCasesTableHasNthRows(caseIds.length); + expect(await testSubjects.exists('all-cases-clear-filters-link-icon')).to.be(false); + }); + describe('assignees filtering', () => { it('filters cases by the first cases all user assignee', async () => { await cases.casesTable.filterByAssignee('all'); @@ -554,12 +806,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.casesTable.waitForCasesToBeListed(); }); - beforeEach(async () => { - /** - * There is no easy way to clear the filtering. - * Refreshing the page seems to be easier. - */ - await cases.navigation.navigateToApp(); + afterEach(async () => { + await cases.casesTable.clearFilters(); }); after(async () => { From 6f4fe55eaad3e4d6560205a8f75918107feb89ca Mon Sep 17 00:00:00 2001 From: Jon <jon@elastic.co> Date: Fri, 9 Feb 2024 13:43:12 -0600 Subject: [PATCH 094/104] [build] Use build sha instead of build number for CDN assets (#176186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/elastic/kibana/pull/175898 updates routes to cache bust using the build checksum instead of build number. This updates the directory structure of the CDN assets archive accordingly. ``` kibana-8.13.0-SNAPSHOT-cdn-assets └── e96cc061dd76 ├── bundles │   ├── core │   ├── kbn-monaco │   ├── kbn-ui-shared-deps-npm │   ├── kbn-ui-shared-deps-src │   └── plugin └── ui ├── favicons ├── fonts ├── legacy_dark_theme.css ├── legacy_dark_theme.min.css ├── legacy_light_theme.css └── legacy_light_theme.min.css 11 directories, 4 files ``` --- src/dev/build/lib/build.test.ts | 1 + src/dev/build/lib/config.ts | 7 +++++++ src/dev/build/lib/version_info.ts | 1 + src/dev/build/tasks/create_cdn_assets_task.ts | 6 +++--- src/dev/build/tasks/fetch_agent_versions_list.test.ts | 1 + 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dev/build/lib/build.test.ts b/src/dev/build/lib/build.test.ts index 1292f1439642e..76fa06b04affa 100644 --- a/src/dev/build/lib/build.test.ts +++ b/src/dev/build/lib/build.test.ts @@ -30,6 +30,7 @@ const config = new Config( { buildNumber: 1234, buildSha: 'abcd1234', + buildShaShort: 'abcd', buildVersion: '8.0.0', buildDate: '2023-05-15T23:12:09+0000', }, diff --git a/src/dev/build/lib/config.ts b/src/dev/build/lib/config.ts index 19fbd6ae8bd37..ced8e10afab4b 100644 --- a/src/dev/build/lib/config.ts +++ b/src/dev/build/lib/config.ts @@ -228,6 +228,13 @@ export class Config { return this.versionInfo.buildSha; } + /** + * Get the first 12 digits of the git sha for this build + */ + getBuildShaShort() { + return this.versionInfo.buildShaShort; + } + /** * Get the ISO 8601 date for this build */ diff --git a/src/dev/build/lib/version_info.ts b/src/dev/build/lib/version_info.ts index 305eb54c9a491..3f79f85f8d76b 100644 --- a/src/dev/build/lib/version_info.ts +++ b/src/dev/build/lib/version_info.ts @@ -36,6 +36,7 @@ export async function getVersionInfo({ isRelease, versionQualifier, pkg }: Optio return { buildSha, + buildShaShort: buildSha.slice(0, 12), buildVersion, buildNumber: await getBuildNumber(), buildDate: new Date().toISOString(), diff --git a/src/dev/build/tasks/create_cdn_assets_task.ts b/src/dev/build/tasks/create_cdn_assets_task.ts index e03e1f6775672..a9ec8beb0955c 100644 --- a/src/dev/build/tasks/create_cdn_assets_task.ts +++ b/src/dev/build/tasks/create_cdn_assets_task.ts @@ -23,10 +23,10 @@ export const CreateCdnAssets: Task = { async run(config, log, build) { const buildSource = build.resolvePath(); - const buildNum = config.getBuildNumber(); + const buildSha = config.getBuildShaShort(); const buildVersion = config.getBuildVersion(); const assets = config.resolveFromRepo('build', 'cdn-assets'); - const bundles = resolve(assets, String(buildNum), 'bundles'); + const bundles = resolve(assets, buildSha, 'bundles'); await del(assets); await mkdirp(assets); @@ -83,7 +83,7 @@ export const CreateCdnAssets: Task = { // packages/core/apps/core-apps-server-internal/src/core_app.ts await copyAll( resolve(buildSource, 'node_modules/@kbn/core-apps-server-internal/assets'), - resolve(assets, 'ui') + resolve(assets, buildSha, 'ui') ); await compressTar({ diff --git a/src/dev/build/tasks/fetch_agent_versions_list.test.ts b/src/dev/build/tasks/fetch_agent_versions_list.test.ts index 2604dadf3302e..e27442beff0b4 100644 --- a/src/dev/build/tasks/fetch_agent_versions_list.test.ts +++ b/src/dev/build/tasks/fetch_agent_versions_list.test.ts @@ -34,6 +34,7 @@ const config = new Config( { buildNumber: 1234, buildSha: 'abcd1234', + buildShaShort: 'abcd', buildVersion: '8.0.0', buildDate: '2023-05-15T23:12:09.000Z', }, From 19058ce00792f3e98c5b7fabf9b9c01d0b7de5d6 Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:47:00 -0600 Subject: [PATCH 095/104] [ML] Fix Single Metric Viewer not showing chart for metric functions and mismatch function in tooltip (#176354) ## Summary This PR fixes https://github.com/elastic/kibana/issues/176301. Fixes include: 1) The schema for `getAnomalyRecordsSchema` was updated, but missed the additional parameter `functionDescription `. So the API call was throwing error. 2) The tooltip to showcase the underlying function (min, max, or avg) for metric detector that yields the highest anomaly score was showing the incorrect fallback value. 3) Fix label in Single Metric Viewer to match with the min/max/avg used: After https://github.com/elastic/kibana/assets/43350163/03d8e10b-c4cd-4c28-a28c-7c6a7e108065 <img width="1728" alt="Screenshot 2024-02-06 at 17 11 15" src="https://github.com/elastic/kibana/assets/43350163/47d6eae6-758b-4514-a3d6-a29bc866d1d2"> ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] 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)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] 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)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../timeseries_search_service.ts | 41 ++++++++++++++----- .../timeseriesexplorer/timeseriesexplorer.js | 3 +- .../application/util/chart_config_builder.ts | 19 +++++++-- .../models/results_service/anomaly_charts.ts | 4 +- .../routes/schemas/results_service_schema.ts | 1 + 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts index 044d166ca5efa..05adc2355ef3c 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts @@ -6,6 +6,7 @@ */ import { each, find, get, filter } from 'lodash'; +import type { ES_AGGREGATION } from '@kbn/ml-anomaly-utils'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -15,7 +16,6 @@ import { isModelPlotChartableForDetector, isModelPlotEnabled, } from '../../../common/util/job_utils'; -// @ts-ignore import { buildConfigFromDetector } from '../util/chart_config_builder'; import { mlResultsService } from '../services/results_service'; import { ModelPlotOutput } from '../services/results_service/result_service_rx'; @@ -113,29 +113,48 @@ function getMetricData( } } -// Builds chart detail information (charting function description and entity counts) used -// in the title area of the time series chart. -// Queries Elasticsearch if necessary to obtain the distinct count of entities -// for which data is being plotted. +interface TimeSeriesExplorerChartDetails { + success: boolean; + results: { + functionLabel: string | null; + entityData: { count?: number; entities: Array<{ fieldName: string; cardinality?: number }> }; + }; +} + +/** + * Builds chart detail information (charting function description and entity counts) used + * in the title area of the time series chart. + * Queries Elasticsearch if necessary to obtain the distinct count of entities + * for which data is being plotted. + * @param job Job config info + * @param detectorIndex The index of the detector in the job config + * @param entityFields Array of field name - field value pairs + * @param earliestMs Earliest timestamp in milliseconds + * @param latestMs Latest timestamp in milliseconds + * @param metricFunctionDescription The underlying function (min, max, avg) for "metric" detector type + * @returns chart data to plot for Single Metric Viewer/Time series explorer + */ function getChartDetails( job: Job, detectorIndex: number, - entityFields: any[], + entityFields: MlEntityField[], earliestMs: number, - latestMs: number + latestMs: number, + metricFunctionDescription?: ES_AGGREGATION ) { return new Promise((resolve, reject) => { - const obj: any = { + const obj: TimeSeriesExplorerChartDetails = { success: true, results: { functionLabel: '', entityData: { entities: [] } }, }; - const chartConfig = buildConfigFromDetector(job, detectorIndex); + const chartConfig = buildConfigFromDetector(job, detectorIndex, metricFunctionDescription); + let functionLabel: string | null = chartConfig.metricFunction; if (chartConfig.metricFieldName !== undefined) { - functionLabel += ' '; - functionLabel += chartConfig.metricFieldName; + functionLabel += ` ${chartConfig.metricFieldName}`; } + obj.results.functionLabel = functionLabel; const blankEntityFields = filter(entityFields, (entity) => { diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index ad3f71e5df22d..76c0ffb038971 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -568,7 +568,8 @@ export class TimeSeriesExplorer extends React.Component { detectorIndex, entityControls, searchBounds.min.valueOf(), - searchBounds.max.valueOf() + searchBounds.max.valueOf(), + this.props.functionDescription ) .then((resp) => { stateUpdate.chartDetails = resp.results; diff --git a/x-pack/plugins/ml/public/application/util/chart_config_builder.ts b/x-pack/plugins/ml/public/application/util/chart_config_builder.ts index e9c322d30a6e5..c1057fc335e82 100644 --- a/x-pack/plugins/ml/public/application/util/chart_config_builder.ts +++ b/x-pack/plugins/ml/public/application/util/chart_config_builder.ts @@ -19,9 +19,19 @@ import { Job } from '../../../common/types/anomaly_detection_jobs'; import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; -// Builds the basic configuration to plot a chart of the source data -// analyzed by the the detector at the given index from the specified ML job. -export function buildConfigFromDetector(job: Job, detectorIndex: number) { +/** + * Builds the basic configuration to plot a chart of the source data + * analyzed by the the detector at the given index from the specified ML job. + * @param job Job config info + * @param detectorIndex The index of the detector in the job config + * @param metricFunctionDescription The underlying function (min, max, avg) for "metric" detector type + * @returns + */ +export function buildConfigFromDetector( + job: Job, + detectorIndex: number, + metricFunctionDescription?: ES_AGGREGATION +) { const analysisConfig = job.analysis_config; const detector = analysisConfig.detectors[detectorIndex]; @@ -38,6 +48,9 @@ export function buildConfigFromDetector(job: Job, detectorIndex: number) { datafeedConfig: job.datafeed_config!, summaryCountFieldName: job.analysis_config.summary_count_field_name, }; + if (detector.function === ML_JOB_AGGREGATION.METRIC && metricFunctionDescription !== undefined) { + config.metricFunction = metricFunctionDescription; + } if (detector.field_name !== undefined) { config.metricFieldName = detector.field_name; diff --git a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts index 707a594d5eff3..345b6cf6054af 100644 --- a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts +++ b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts @@ -766,12 +766,12 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu } // Build the tooltip data for the chart info icon, showing further details on what is being plotted. - let functionLabel = `${config.metricFunction}`; + let functionLabel = `${fullSeriesConfig.metricFunction ?? config.metricFunction}`; if ( fullSeriesConfig.metricFieldName !== undefined && fullSeriesConfig.metricFieldName !== null ) { - functionLabel += ` ${fullSeriesConfig.metricFieldName}`; + functionLabel += `(${fullSeriesConfig.metricFieldName})`; } fullSeriesConfig.infoTooltip = { diff --git a/x-pack/plugins/ml/server/routes/schemas/results_service_schema.ts b/x-pack/plugins/ml/server/routes/schemas/results_service_schema.ts index 70fc5098fe3b5..656007b3e1e1c 100644 --- a/x-pack/plugins/ml/server/routes/schemas/results_service_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/results_service_schema.ts @@ -144,4 +144,5 @@ export const getAnomalyRecordsSchema = schema.object({ latestMs: schema.number(), criteriaFields: schema.arrayOf(schema.any()), interval: schema.string(), + functionDescription: schema.maybe(schema.nullable(schema.string())), }); From 4b72c3343ff6ed0973c73a357eae22ce58c1b0ab Mon Sep 17 00:00:00 2001 From: Rodney Norris <rodney.norris@elastic.co> Date: Fri, 9 Feb 2024 14:23:44 -0600 Subject: [PATCH 096/104] fix(embeddable_console): use header offset to calculate max height (#176627) ## Summary Update the docked console max height to use the euiFixedHeadersOffset CSS variable instead of #{$euiSize * 5} ### Screenshot ![image](https://github.com/elastic/kibana/assets/1972968/610f02bf-ca90-4af2-878c-c85de681d87b) --- .../public/application/containers/embeddable/_variables.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/containers/embeddable/_variables.scss b/src/plugins/console/public/application/containers/embeddable/_variables.scss index b987037af4d62..33ecd64b999c9 100644 --- a/src/plugins/console/public/application/containers/embeddable/_variables.scss +++ b/src/plugins/console/public/application/containers/embeddable/_variables.scss @@ -2,7 +2,7 @@ $embeddableConsoleBackground: lightOrDarkTheme($euiColorDarkestShade, $euiColorI $embeddableConsoleText: lighten(makeHighContrastColor($euiColorLightestShade, $embeddableConsoleBackground), 20%); $embeddableConsoleBorderColor: transparentize($euiColorGhost, .8); $embeddableConsoleInitialHeight: $euiSizeXXL; -$embeddableConsoleMaxHeight: calc(100vh - #{$euiSize * 5}); +$embeddableConsoleMaxHeight: calc(100vh - var(--euiFixedHeadersOffset, 0)); // Pixel heights ensure no blurriness caused by half pixel offsets $embeddableConsoleHeights: ( From 80bc424c6ac5daff914834cfa2d018d391772d7a Mon Sep 17 00:00:00 2001 From: Achyut Jhunjhunwala <achyut.jhunjhunwala@elastic.co> Date: Fri, 9 Feb 2024 21:28:00 +0100 Subject: [PATCH 097/104] [Logs Explorer] Fix logic to use fallback for Discover link (#176320) ## Summary Closes https://github.com/elastic/kibana/issues/175127 ### Demo ![Discover Link](https://github.com/elastic/kibana/assets/7416358/87b23726-c574-473b-8af6-6210643bc6f1) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: jennypavlova <jennypavlova94@gmail.com> --- .../observability/locators/logs_explorer.ts | 18 ++++++++- .../get_view_in_app_url.test.ts | 4 +- .../get_view_in_app_url.ts | 4 +- .../register_observability_rule_types.ts | 4 +- .../logs_explorer/common/constants.ts | 31 +++++++++++----- .../common/display_options/types.ts | 12 +++++- .../logs_explorer/common/index.ts | 7 ++++ .../logs_explorer/logs_explorer_locator.ts | 7 +++- .../public/components/common/popover_chip.tsx | 1 + .../components/virtual_columns/resource.tsx | 11 +++--- .../logs_explorer/public/index.ts | 1 + .../utils/convert_discover_app_state.ts | 37 +++++++++++++++---- .../common/locators/locators.test.ts | 10 ++--- .../locators/utils/construct_locator_path.ts | 5 ++- .../common/url_schema/url_schema_v1.ts | 25 ++++++++++++- .../public/components/discover_link.tsx | 4 +- .../columns_selection.ts | 14 +++++-- .../header_menu.ts | 7 ++-- .../columns_selection.ts | 14 +++++-- .../header_menu.ts | 7 ++-- 20 files changed, 171 insertions(+), 52 deletions(-) diff --git a/packages/deeplinks/observability/locators/logs_explorer.ts b/packages/deeplinks/observability/locators/logs_explorer.ts index 13ecd80165217..1442e7afe02cd 100644 --- a/packages/deeplinks/observability/locators/logs_explorer.ts +++ b/packages/deeplinks/observability/locators/logs_explorer.ts @@ -27,6 +27,22 @@ export type ListFilterControl = { export const LOGS_EXPLORER_LOCATOR_ID = 'LOGS_EXPLORER_LOCATOR'; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type DocumentFieldGridColumnOptions = { + type: 'document-field'; + field: string; + width?: number; +}; + +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type SmartFieldGridColumnOptions = { + type: 'smart-field'; + smartField: 'content' | 'resource'; + width?: number; +}; + +export type GridColumnDisplayOptions = DocumentFieldGridColumnOptions | SmartFieldGridColumnOptions; + export interface LogsExplorerNavigationParams extends SerializableRecord { /** * Optionally set the time range in the time picker. @@ -43,7 +59,7 @@ export interface LogsExplorerNavigationParams extends SerializableRecord { /** * Columns displayed in the table */ - columns?: string[]; + columns?: GridColumnDisplayOptions[]; /** * Optionally apply free-form filters. */ diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts index c8e0d9be29784..58cf458dcc682 100644 --- a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts +++ b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import { Aggregators } from './types'; import { LocatorPublic } from '@kbn/share-plugin/common'; +import { LogsExplorerLocatorParams } from '@kbn/deeplinks-observability'; import { getViewInAppUrl, GetViewInAppUrlArgs } from './get_view_in_app_url'; describe('getViewInAppUrl', () => { const logsExplorerLocator = { getRedirectUrl: jest.fn(() => 'mockedGetRedirectUrl'), - } as unknown as LocatorPublic<DiscoverAppLocatorParams>; + } as unknown as LocatorPublic<LogsExplorerLocatorParams>; const startedAt = '2023-12-07T16:30:15.403Z'; const endedAt = '2023-12-07T20:30:15.403Z'; const returnedTimeRange = { diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts index 79e40fcfc65f3..af441fb8069f7 100644 --- a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts +++ b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts @@ -6,9 +6,9 @@ */ import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util'; -import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import type { TimeRange } from '@kbn/es-query'; import type { LocatorPublic } from '@kbn/share-plugin/common'; +import { LogsExplorerLocatorParams } from '@kbn/deeplinks-observability'; import type { CustomThresholdExpressionMetric } from './types'; export interface GetViewInAppUrlArgs { @@ -16,7 +16,7 @@ export interface GetViewInAppUrlArgs { endedAt?: string; startedAt?: string; filter?: string; - logsExplorerLocator?: LocatorPublic<DiscoverAppLocatorParams>; + logsExplorerLocator?: LocatorPublic<LogsExplorerLocatorParams>; metrics?: CustomThresholdExpressionMetric[]; } diff --git a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts index 1915778fc2c4b..67c84960722a9 100644 --- a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts +++ b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts @@ -14,8 +14,8 @@ import { ALERT_START, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, } from '@kbn/rule-data-utils'; -import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import type { LocatorPublic } from '@kbn/share-plugin/common'; +import { LogsExplorerLocatorParams } from '@kbn/deeplinks-observability'; import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { MetricExpression } from '../components/custom_threshold/types'; import type { @@ -91,7 +91,7 @@ const getDataViewId = (searchConfiguration?: SerializedSearchSourceFields) => export const registerObservabilityRuleTypes = async ( observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry, uiSettings: IUiSettingsClient, - logsExplorerLocator?: LocatorPublic<DiscoverAppLocatorParams> + logsExplorerLocator?: LocatorPublic<LogsExplorerLocatorParams> ) => { observabilityRuleTypeRegistry.register({ id: SLO_BURN_RATE_RULE_TYPE_ID, diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts b/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts index 7e546e9863446..7839a5c0654cd 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/constants.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { SmartFieldGridColumnOptions } from './display_options'; + export const LOGS_EXPLORER_PROFILE_ID = 'logs-explorer'; // Fields constants @@ -50,14 +52,25 @@ export const RESOURCE_FIELD = 'resource'; export const DATA_GRID_COLUMN_WIDTH_SMALL = 240; export const DATA_GRID_COLUMN_WIDTH_MEDIUM = 320; export const ACTIONS_COLUMN_WIDTH = 80; + +export const RESOURCE_FIELD_CONFIGURATION: SmartFieldGridColumnOptions = { + type: 'smart-field', + smartField: RESOURCE_FIELD, + fallbackFields: [HOST_NAME_FIELD, SERVICE_NAME_FIELD], + width: DATA_GRID_COLUMN_WIDTH_MEDIUM, +}; + +export const CONTENT_FIELD_CONFIGURATION: SmartFieldGridColumnOptions = { + type: 'smart-field', + smartField: CONTENT_FIELD, + fallbackFields: [MESSAGE_FIELD], +}; + +export const SMART_FALLBACK_FIELDS = { + [CONTENT_FIELD]: CONTENT_FIELD_CONFIGURATION, + [RESOURCE_FIELD]: RESOURCE_FIELD_CONFIGURATION, +}; + // UI preferences -export const DEFAULT_COLUMNS = [ - { - field: RESOURCE_FIELD, - width: DATA_GRID_COLUMN_WIDTH_MEDIUM, - }, - { - field: CONTENT_FIELD, - }, -]; +export const DEFAULT_COLUMNS = [RESOURCE_FIELD_CONFIGURATION, CONTENT_FIELD_CONFIGURATION]; export const DEFAULT_ROWS_PER_PAGE = 100; diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts b/x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts index b4c482d088a54..6251dee26c6ba 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts @@ -11,11 +11,21 @@ export interface ChartDisplayOptions { export type PartialChartDisplayOptions = Partial<ChartDisplayOptions>; -export interface GridColumnDisplayOptions { +export interface DocumentFieldGridColumnOptions { + type: 'document-field'; field: string; width?: number; } +export interface SmartFieldGridColumnOptions { + type: 'smart-field'; + smartField: 'content' | 'resource'; + fallbackFields: string[]; + width?: number; +} + +export type GridColumnDisplayOptions = DocumentFieldGridColumnOptions | SmartFieldGridColumnOptions; + export interface GridRowsDisplayOptions { rowHeight: number; rowsPerPage: number; diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/index.ts b/x-pack/plugins/observability_solution/logs_explorer/common/index.ts index 5466a00ae0caa..0f593cb8ad072 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/index.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/index.ts @@ -30,3 +30,10 @@ export type { PartialGridDisplayOptions, PartialGridRowsDisplayOptions, } from './display_options'; + +export { + CONTENT_FIELD, + CONTENT_FIELD_CONFIGURATION, + RESOURCE_FIELD_CONFIGURATION, + SMART_FALLBACK_FIELDS, +} from './constants'; diff --git a/x-pack/plugins/observability_solution/logs_explorer/common/locators/logs_explorer/logs_explorer_locator.ts b/x-pack/plugins/observability_solution/logs_explorer/common/locators/logs_explorer/logs_explorer_locator.ts index ec8b2df56cb79..c60b0ca74dddb 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/common/locators/logs_explorer/logs_explorer_locator.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/common/locators/logs_explorer/logs_explorer_locator.ts @@ -21,7 +21,7 @@ export class LogsExplorerLocatorDefinition implements LocatorDefinition<LogsExpl constructor(protected readonly deps: LogsExplorerLocatorDependencies) {} public readonly getLocation = (params: LogsExplorerLocatorParams) => { - const { dataset } = params; + const { dataset, columns } = params; const dataViewSpec: DataViewSpec | undefined = dataset ? { id: dataset, @@ -29,8 +29,13 @@ export class LogsExplorerLocatorDefinition implements LocatorDefinition<LogsExpl } : undefined; + const discoverColumns = columns?.map((column) => { + return column.type === 'document-field' ? column.field : column.smartField; + }); + return this.deps.discoverAppLocator?.getLocation({ ...params, + columns: discoverColumns, dataViewId: dataset, dataViewSpec, })!; diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx index bb5d4a5ed85d7..2811bbf5480c4 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/common/popover_chip.tsx @@ -78,6 +78,7 @@ export function ChipWithPopover({ font-size: ${xsFontSize}; display: flex; justify-content: center; + ${shouldRenderPopover && `margin-right: 4px; margin-top: -3px;`} cursor: pointer; `} style={style} diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/resource.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/resource.tsx index e64b9c81c65bc..7cecdeee5ce40 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/resource.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/components/virtual_columns/resource.tsx @@ -7,7 +7,6 @@ import React from 'react'; import type { DataGridCellValueElementProps } from '@kbn/unified-data-table'; -import { first } from 'lodash'; import { AgentName } from '@kbn/elastic-agent-utils'; import { dynamic } from '@kbn/shared-ux-utility'; import { ChipWithPopover } from '../common/popover_chip'; @@ -27,10 +26,12 @@ export const Resource = ({ row }: DataGridCellValueElementProps) => { text={resourceDoc[constants.SERVICE_NAME_FIELD] as string} rightSideIcon="arrowDown" leftSideIcon={ - <AgentIcon - agentName={first((resourceDoc[constants.AGENT_NAME_FIELD] ?? []) as AgentName[])} - size="m" - /> + resourceDoc[constants.AGENT_NAME_FIELD] && ( + <AgentIcon + agentName={resourceDoc[constants.AGENT_NAME_FIELD] as AgentName} + size="m" + /> + ) } /> )} diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/index.ts b/x-pack/plugins/observability_solution/logs_explorer/public/index.ts index d4febf6775416..6e452f8904828 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/index.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/index.ts @@ -25,6 +25,7 @@ export { getDiscoverColumnsFromDisplayOptions, getDiscoverGridFromDisplayOptions, getDiscoverFiltersFromState, + getDiscoverColumnsWithFallbackFieldsFromDisplayOptions, } from './utils/convert_discover_app_state'; export function plugin(context: PluginInitializerContext<LogsExplorerConfig>) { diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts b/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts index 639d4bdb2b0d1..71ca190627f34 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts @@ -10,6 +10,7 @@ import { DiscoverAppState } from '@kbn/discover-plugin/public'; import { ExistsFilter, Filter, FILTERS, PhrasesFilter } from '@kbn/es-query'; import { PhraseFilterValue } from '@kbn/es-query/src/filters/build_filters'; import { cloneDeep } from 'lodash'; +import { CONTENT_FIELD, RESOURCE_FIELD, SMART_FALLBACK_FIELDS } from '../../common/constants'; import { ChartDisplayOptions, DisplayOptions, @@ -21,10 +22,16 @@ import type { ControlOptions, OptionsListControl } from '../controller'; export const getGridColumnDisplayOptionsFromDiscoverAppState = ( discoverAppState: DiscoverAppState ): GridColumnDisplayOptions[] | undefined => - discoverAppState.columns?.map((field) => ({ - field, - width: discoverAppState.grid?.columns?.[field]?.width, - })); + discoverAppState.columns?.map((field) => { + if (field === CONTENT_FIELD || field === RESOURCE_FIELD) { + return SMART_FALLBACK_FIELDS[field]; + } + return { + type: 'document-field', + field, + width: discoverAppState.grid?.columns?.[field]?.width, + }; + }); export const getGridRowsDisplayOptionsFromDiscoverAppState = ( discoverAppState: DiscoverAppState @@ -58,18 +65,32 @@ export const getDiscoverAppStateFromContext = ( filters: cloneDeep(displayOptions.filters), }); +export const getDiscoverColumnsWithFallbackFieldsFromDisplayOptions = ( + displayOptions: DisplayOptions +): DiscoverAppState['columns'] => + displayOptions.grid.columns.flatMap((column) => { + return column.type === 'document-field' + ? column.field + : SMART_FALLBACK_FIELDS[column.smartField].fallbackFields; + }); + export const getDiscoverColumnsFromDisplayOptions = ( displayOptions: DisplayOptions -): DiscoverAppState['columns'] => displayOptions.grid.columns.map(({ field }) => field); +): DiscoverAppState['columns'] => + displayOptions.grid.columns.flatMap((column) => { + return column.type === 'document-field' ? column.field : column.smartField; + }); export const getDiscoverGridFromDisplayOptions = ( displayOptions: DisplayOptions ): DiscoverAppState['grid'] => ({ columns: displayOptions.grid.columns.reduce< NonNullable<NonNullable<DiscoverAppState['grid']>['columns']> - >((gridColumns, { field, width }) => { - if (width != null) { - gridColumns[field] = { width }; + >((gridColumns, column) => { + const key = column.type === 'document-field' ? column.field : column.smartField; + + if (column.width != null) { + gridColumns[key] = { width: column.width }; } return gridColumns; }, {}), diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/locators.test.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/locators.test.ts index 0c4615ad110e0..9da7b798c50b3 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/locators.test.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/locators.test.ts @@ -92,9 +92,9 @@ describe('Observability Logs Explorer Locators', () => { }); }); - it('should allow specifiying columns', async () => { + it('should allow specifying columns', async () => { const params: AllDatasetsLocatorParams = { - columns: ['_source'], + columns: [{ field: '_source', type: 'document-field' }], }; const { allDatasetsLocator } = await setup(); @@ -102,7 +102,7 @@ describe('Observability Logs Explorer Locators', () => { expect(location).toMatchObject({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID, - path: `/?pageState=(columns:!((field:_source)),datasetSelection:(selectionType:all),v:1)`, + path: '/?pageState=(columns:!((field:_source,type:document-field)),datasetSelection:(selectionType:all),v:1)', state: {}, }); }); @@ -214,7 +214,7 @@ describe('Observability Logs Explorer Locators', () => { const params: SingleDatasetLocatorParams = { integration, dataset, - columns: ['_source'], + columns: [{ field: '_source', type: 'document-field' }], }; const { singleDatasetLocator } = await setup(); @@ -222,7 +222,7 @@ describe('Observability Logs Explorer Locators', () => { expect(location).toMatchObject({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID, - path: `/?pageState=(columns:!((field:_source)),datasetSelection:(selection:(dataset:(name:'logs-test-*-*',title:test),name:Test),selectionType:unresolved),v:1)`, + path: `/?pageState=(columns:!((field:_source,type:document-field)),datasetSelection:(selection:(dataset:(name:'logs-test-*-*',title:test),name:Test),selectionType:unresolved),v:1)`, state: {}, }); }); diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/utils/construct_locator_path.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/utils/construct_locator_path.ts index 20245c6f0a72d..949dc6b1fcafe 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/utils/construct_locator_path.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/common/locators/utils/construct_locator_path.ts @@ -15,6 +15,7 @@ import { AvailableControlPanels, availableControlsPanels, DatasetSelectionPlain, + SMART_FALLBACK_FIELDS, } from '@kbn/logs-explorer-plugin/common'; import { OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability'; import { @@ -46,7 +47,9 @@ export const constructLocatorPath = async (params: LocatorPathConstructionParams query, refreshInterval, time: timeRange, - columns: columns?.map((field) => ({ field })), + columns: columns?.map((column) => { + return column.type === 'smart-field' ? SMART_FALLBACK_FIELDS[column.smartField] : column; + }), controls: getControlsPageStateFromFilterControlsParams(filterControls ?? {}), }) ); diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/url_schema_v1.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/url_schema_v1.ts index dbeb3ae1fd274..2cdbe422009f3 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/url_schema_v1.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/common/url_schema/url_schema_v1.ts @@ -8,8 +8,15 @@ import { availableControlsPanels, datasetSelectionPlainRT } from '@kbn/logs-explorer-plugin/common'; import * as rt from 'io-ts'; -export const columnRT = rt.intersection([ +const allowedNamesRT = rt.keyof({ + content: null, + resource: null, +}); + +// Define the runtime type for DocumentFieldGridColumnOptions +const documentFieldColumnRT = rt.intersection([ rt.strict({ + type: rt.literal('document-field'), field: rt.string, }), rt.exact( @@ -19,6 +26,22 @@ export const columnRT = rt.intersection([ ), ]); +// Define the runtime type for SmartFieldGridColumnOptions +const smartFieldColumnRT = rt.intersection([ + rt.strict({ + type: rt.literal('smart-field'), + smartField: allowedNamesRT, + fallbackFields: rt.array(rt.string), + }), + rt.exact( + rt.partial({ + width: rt.number, + }) + ), +]); + +export const columnRT = rt.union([documentFieldColumnRT, smartFieldColumnRT]); + export const columnsRT = rt.array(columnRT); export const optionsListControlRT = rt.strict({ diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx index 7c0b4596b4326..49a50458ba652 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/discover_link.tsx @@ -10,7 +10,7 @@ import { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import { DiscoverStart } from '@kbn/discover-plugin/public'; import { hydrateDatasetSelection } from '@kbn/logs-explorer-plugin/common'; import { - getDiscoverColumnsFromDisplayOptions, + getDiscoverColumnsWithFallbackFieldsFromDisplayOptions, getDiscoverFiltersFromState, } from '@kbn/logs-explorer-plugin/public'; import { getRouterLinkProps } from '@kbn/router-utils'; @@ -57,7 +57,7 @@ export const DiscoverLinkForValidState = React.memo( const index = hydrateDatasetSelection(logsExplorerState.datasetSelection).toDataviewSpec(); return { breakdownField: logsExplorerState.chart.breakdownField ?? undefined, - columns: getDiscoverColumnsFromDisplayOptions(logsExplorerState), + columns: getDiscoverColumnsWithFallbackFieldsFromDisplayOptions(logsExplorerState), filters: getDiscoverFiltersFromState( index.id, logsExplorerState.filters, diff --git a/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts index fae1ecc59c5fe..d61ce9e734eba 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/columns_selection.ts @@ -58,9 +58,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { mode: 'absolute', }, columns: [ - { field: 'resource' }, - { field: 'content' }, - { field: 'data_stream.namespace' }, + { + smartField: 'resource', + type: 'smart-field', + fallbackFields: ['host.name', 'service.name'], + }, + { + smartField: 'content', + type: 'smart-field', + fallbackFields: ['message'], + }, + { field: 'data_stream.namespace', type: 'document-field' }, ], }, }); diff --git a/x-pack/test/functional/apps/observability_logs_explorer/header_menu.ts b/x-pack/test/functional/apps/observability_logs_explorer/header_menu.ts index 9bc4e090fb6cc..f7c45395dd758 100644 --- a/x-pack/test/functional/apps/observability_logs_explorer/header_menu.ts +++ b/x-pack/test/functional/apps/observability_logs_explorer/header_menu.ts @@ -46,7 +46,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await discoverLink.isDisplayed()).to.be(true); }); - it('should navigate to discover keeping the current columns/filters/query/time/data view', async () => { + it('should navigate to discover keeping the current filters/query/time/data view and use fallback columns for virtual columns', async () => { await retry.try(async () => { await testSubjects.existOrFail('superDatePickerstartDatePopoverButton'); await testSubjects.existOrFail('superDatePickerendDatePopoverButton'); @@ -69,8 +69,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { expect(await PageObjects.discover.getColumnHeaders()).to.eql([ '@timestamp', - 'resource', - 'content', + 'host.name', + 'service.name', + 'message', ]); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts index cdc00483b9365..beb1adc25e70c 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/columns_selection.ts @@ -60,9 +60,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { mode: 'absolute', }, columns: [ - { field: 'resource' }, - { field: 'content' }, - { field: 'data_stream.namespace' }, + { + smartField: 'resource', + type: 'smart-field', + fallbackFields: ['host.name', 'service.name'], + }, + { + smartField: 'content', + type: 'smart-field', + fallbackFields: ['message'], + }, + { field: 'data_stream.namespace', type: 'document-field' }, ], }, }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/header_menu.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/header_menu.ts index a4768c4415e4b..e6fe60cf248fc 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/header_menu.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_logs_explorer/header_menu.ts @@ -71,7 +71,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await discoverLink.isDisplayed()).to.be(true); }); - it('should navigate to discover keeping the current columns/filters/query/time/data view', async () => { + it('should navigate to discover keeping the current filters/query/time/data view and use fallback columns for virtual columns', async () => { await retry.try(async () => { await testSubjects.existOrFail('superDatePickerstartDatePopoverButton'); await testSubjects.existOrFail('superDatePickerendDatePopoverButton'); @@ -91,8 +91,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { expect(await PageObjects.discover.getColumnHeaders()).to.eql([ '@timestamp', - 'resource', - 'content', + 'host.name', + 'service.name', + 'message', ]); }); await retry.try(async () => { From 55c40e7902b45320ec63975e8f29334260fec571 Mon Sep 17 00:00:00 2001 From: Alexi Doak <109488926+doakalexi@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:28:38 -0800 Subject: [PATCH 098/104] [ResponseOps][Research] Make the timeout for ES requests match the rule type timeout (#175484) Resolves https://github.com/elastic/kibana-team/issues/722 ## Summary By default ES requests time out after 30s. This PR re-uses the task execution timeout, which can be configured per rule type, to configure the ES request `requestTimeout`. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### To verify - Add the following to `kibana.yml ` ``` xpack.alerting.rules.run.ruleTypeOverrides: - id: '.es-query' timeout: '30s' (any timeout of your choosing) ``` - Add a shard delay to queries types in the ES query rule: ``` aggs: { delay: { shard_delay: { value: '45s', (any delay of your choosing) }, }, }, ``` I was able to update the queries in the following files: Query DSL: `x-pack/plugins/stack_alerts/common/build_sorted_events_query.ts` KQL: `x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts` Note: the way the KQL queries work it was difficult to get the request to timeout. I had to use really short timeouts and delays. Maybe there is a better way to test this, if anyone has ideas pls let me know :) - Start Kibana - Create an ES query rule and verify that timeout is configurable, and that ES will throw an error if the request times out --- .../server/lib/get_es_request_timeout.test.ts | 28 ++ .../server/lib/get_es_request_timeout.ts | 26 ++ .../server/lib/get_rule_task_timeout.ts | 2 +- x-pack/plugins/alerting/server/lib/index.ts | 1 + .../lib/wrap_scoped_cluster_client.test.ts | 251 +++++++++++++++++- .../server/lib/wrap_scoped_cluster_client.ts | 44 ++- .../lib/wrap_search_source_client.test.ts | 29 +- .../server/lib/wrap_search_source_client.ts | 14 +- .../server/task_runner/task_runner.ts | 3 + 9 files changed, 386 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/alerting/server/lib/get_es_request_timeout.test.ts create mode 100644 x-pack/plugins/alerting/server/lib/get_es_request_timeout.ts diff --git a/x-pack/plugins/alerting/server/lib/get_es_request_timeout.test.ts b/x-pack/plugins/alerting/server/lib/get_es_request_timeout.test.ts new file mode 100644 index 0000000000000..deb5dc4d3b0a2 --- /dev/null +++ b/x-pack/plugins/alerting/server/lib/get_es_request_timeout.test.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import { getEsRequestTimeout } from './get_es_request_timeout'; + +describe('getEsRequestTimeout', () => { + const logger = loggingSystemMock.create().get(); + test('should return undefined if the timeout is not passed in', () => { + expect(getEsRequestTimeout(logger)).toBe(undefined); + }); + test('should return timeout in ms', () => { + expect(getEsRequestTimeout(logger, '5s')).toBe(5000); + }); + test('should return timeout that is not > 5m', () => { + expect(getEsRequestTimeout(logger, '10m')).toBe(300000); + }); + test('should log error and return undefined for invalid timeout', () => { + expect(getEsRequestTimeout(logger, '5z')).toBe(undefined); + expect(logger.debug).toBeCalledTimes(1); + expect(logger.debug).toBeCalledWith( + 'Invalid format for the rule ES requestTimeout duration: "5z"' + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/lib/get_es_request_timeout.ts b/x-pack/plugins/alerting/server/lib/get_es_request_timeout.ts new file mode 100644 index 0000000000000..7fb82f55993fc --- /dev/null +++ b/x-pack/plugins/alerting/server/lib/get_es_request_timeout.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 { Logger } from '@kbn/core/server'; +import { parseDuration } from '../../common'; +import { DEFAULT_EXECUTION_TIMEOUT } from './get_rule_task_timeout'; + +export function getEsRequestTimeout(logger: Logger, timeout?: string): number | undefined { + if (!timeout) { + return undefined; + } + + try { + const maxRequestTimeout = parseDuration(DEFAULT_EXECUTION_TIMEOUT); + const requestTimeout = parseDuration(timeout); + // return the ES request timeout in ms that is capped at the default execution timeout (5 min). + return requestTimeout > maxRequestTimeout ? maxRequestTimeout : requestTimeout; + } catch (error) { + logger.debug(`Invalid format for the rule ES requestTimeout duration: "${timeout}"`); + return undefined; + } +} diff --git a/x-pack/plugins/alerting/server/lib/get_rule_task_timeout.ts b/x-pack/plugins/alerting/server/lib/get_rule_task_timeout.ts index e6721d65e309f..52919bd54de0b 100644 --- a/x-pack/plugins/alerting/server/lib/get_rule_task_timeout.ts +++ b/x-pack/plugins/alerting/server/lib/get_rule_task_timeout.ts @@ -7,7 +7,7 @@ import { RulesConfig } from '../config'; -const DEFAULT_EXECUTION_TIMEOUT = '5m'; +export const DEFAULT_EXECUTION_TIMEOUT = '5m'; export const getRuleTaskTimeout = ({ config, diff --git a/x-pack/plugins/alerting/server/lib/index.ts b/x-pack/plugins/alerting/server/lib/index.ts index 4257f3ca916a4..d83cc889015d4 100644 --- a/x-pack/plugins/alerting/server/lib/index.ts +++ b/x-pack/plugins/alerting/server/lib/index.ts @@ -48,3 +48,4 @@ export { getAlertsForNotification } from './get_alerts_for_notification'; export { trimRecoveredAlerts } from './trim_recovered_alerts'; export { createGetAlertIndicesAliasFn } from './create_get_alert_indices_alias'; export type { GetAlertIndicesAlias } from './create_get_alert_indices_alias'; +export { getEsRequestTimeout } from './get_es_request_timeout'; diff --git a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts index 1880db1e69a4e..da0b65f550deb 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts @@ -58,14 +58,19 @@ describe('wrapScopedClusterClient', () => { rule, logger, abortController, + requestTimeout: 5000, }).client(); await wrappedSearchClient.asInternalUser.search(esQuery); expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(esQuery, { signal: abortController.signal, + requestTimeout: 5000, }); expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + `executing query for rule .test-rule-type:abcdefg in space my-space - {\"body\":{\"query\":{\"bool\":{\"filter\":{\"range\":{\"@timestamp\":{\"gte\":0}}}}}}} - with options {} and 5000ms requestTimeout` + ); }); test('uses asCurrentUser when specified', async () => { @@ -78,14 +83,19 @@ describe('wrapScopedClusterClient', () => { rule, logger, abortController, + requestTimeout: 5000, }).client(); await wrappedSearchClient.asCurrentUser.search(esQuery); expect(asCurrentUserWrappedSearchFn).toHaveBeenCalledWith(esQuery, { signal: abortController.signal, + requestTimeout: 5000, }); expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + `executing query for rule .test-rule-type:abcdefg in space my-space - {\"body\":{\"query\":{\"bool\":{\"filter\":{\"range\":{\"@timestamp\":{\"gte\":0}}}}}}} - with options {} and 5000ms requestTimeout` + ); }); test('uses search options when specified', async () => { @@ -98,12 +108,17 @@ describe('wrapScopedClusterClient', () => { rule, logger, abortController, + requestTimeout: 5000, }).client(); - await wrappedSearchClient.asInternalUser.search(esQuery, { ignore: [404] }); + await wrappedSearchClient.asInternalUser.search(esQuery, { + ignore: [404], + requestTimeout: 10000, + }); expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(esQuery, { ignore: [404], signal: abortController.signal, + requestTimeout: 5000, }); expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); @@ -205,6 +220,83 @@ describe('wrapScopedClusterClient', () => { }); describe('eql.search', () => { + test('uses asInternalUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.eql.search; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + + await wrappedSearchClient.asInternalUser.eql.search(eqlQuery); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(eqlQuery, { + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'executing eql query for rule .test-rule-type:abcdefg in space my-space - {"index":"foo","query":"process where process.name == \\"regsvr32.exe\\""} - with options {} and 5000ms requestTimeout' + ); + }); + + test('uses asCurrentUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(true); + + const asCurrentUserWrappedSearchFn = childClient.eql.search; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asCurrentUser.eql.search(eqlQuery); + + expect(asCurrentUserWrappedSearchFn).toHaveBeenCalledWith(eqlQuery, { + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'executing eql query for rule .test-rule-type:abcdefg in space my-space - {"index":"foo","query":"process where process.name == \\"regsvr32.exe\\""} - with options {} and 5000ms requestTimeout' + ); + }); + + test('uses search options when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.eql.search; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asInternalUser.eql.search(eqlQuery, { + ignore: [404], + requestTimeout: 10000, + }); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(eqlQuery, { + ignore: [404], + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + }); + test('re-throws error when an error is thrown', async () => { const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); @@ -278,6 +370,83 @@ describe('wrapScopedClusterClient', () => { describe('transport.request', () => { describe('ES|QL', () => { + test('uses asInternalUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + + await wrappedSearchClient.asInternalUser.transport.request(esqlQueryRequest); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(esqlQueryRequest, { + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'executing ES|QL query for rule .test-rule-type:abcdefg in space my-space - {"method":"POST","path":"/_query","body":{"query":"from .kibana_task_manager"}} - with options {} and 5000ms requestTimeout' + ); + }); + + test('uses asCurrentUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(true); + + const asCurrentUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asCurrentUser.transport.request(esqlQueryRequest); + + expect(asCurrentUserWrappedSearchFn).toHaveBeenCalledWith(esqlQueryRequest, { + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'executing ES|QL query for rule .test-rule-type:abcdefg in space my-space - {"method":"POST","path":"/_query","body":{"query":"from .kibana_task_manager"}} - with options {} and 5000ms requestTimeout' + ); + }); + + test('uses search options when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asInternalUser.transport.request(esqlQueryRequest, { + ignore: [404], + requestTimeout: 10000, + }); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith(esqlQueryRequest, { + ignore: [404], + signal: abortController.signal, + requestTimeout: 5000, + }); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + }); + test('re-throws error when an error is thrown', async () => { const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); @@ -352,6 +521,86 @@ describe('wrapScopedClusterClient', () => { }); }); + test('uses asInternalUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + + await wrappedSearchClient.asInternalUser.transport.request({ method: '', path: '' }); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith( + { method: '', path: '' }, + { + requestTimeout: 5000, + } + ); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + }); + + test('uses asCurrentUser when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(true); + + const asCurrentUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asCurrentUser.transport.request({ method: '', path: '' }); + + expect(asCurrentUserWrappedSearchFn).toHaveBeenCalledWith( + { method: '', path: '' }, + { + requestTimeout: 5000, + } + ); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + }); + + test('uses search options when specified', async () => { + const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); + + const asInternalUserWrappedSearchFn = childClient.transport.request; + + const wrappedSearchClient = createWrappedScopedClusterClientFactory({ + scopedClusterClient, + rule, + logger, + abortController, + requestTimeout: 5000, + }).client(); + await wrappedSearchClient.asInternalUser.transport.request( + { method: '', path: '' }, + { + ignore: [404], + requestTimeout: 10000, + } + ); + + expect(asInternalUserWrappedSearchFn).toHaveBeenCalledWith( + { method: '', path: '' }, + { + ignore: [404], + requestTimeout: 5000, + } + ); + expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); + expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); + }); + test('re-throws error when an error is thrown', async () => { const { abortController, scopedClusterClient, childClient } = getMockClusterClients(); diff --git a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.ts b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.ts index 55f9d7f4a7c07..2150f415f1039 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.ts @@ -32,6 +32,7 @@ interface WrapScopedClusterClientFactoryOpts { rule: RuleInfo; logger: Logger; abortController: AbortController; + requestTimeout?: number; } type WrapScopedClusterClientOpts = WrapScopedClusterClientFactoryOpts & { @@ -105,6 +106,7 @@ function wrapEsClient(opts: WrapEsClientOpts): ElasticsearchClient { function getWrappedTransportRequestFn(opts: WrapEsClientOpts) { const originalRequestFn = opts.esClient.transport.request; + const requestTimeout = opts.requestTimeout; // A bunch of overloads to make TypeScript happy async function request<TResponse = unknown>( @@ -131,10 +133,17 @@ function getWrappedTransportRequestFn(opts: WrapEsClientOpts) { opts.logger.debug( `executing ES|QL query for rule ${opts.rule.alertTypeId}:${opts.rule.id} in space ${ opts.rule.spaceId - } - ${JSON.stringify(params)} - with options ${JSON.stringify(requestOptions)}` + } - ${JSON.stringify(params)} - with options ${JSON.stringify(requestOptions)}${ + requestTimeout ? ` and ${requestTimeout}ms requestTimeout` : '' + }` ); const result = (await originalRequestFn.call(opts.esClient.transport, params, { ...requestOptions, + ...(requestTimeout + ? { + requestTimeout, + } + : {}), signal: opts.abortController.signal, })) as Promise<TResponse> | TransportResult<TResponse, TContext>; @@ -152,11 +161,14 @@ function getWrappedTransportRequestFn(opts: WrapEsClientOpts) { } // No wrap - return (await originalRequestFn.call( - opts.esClient.transport, - params, - options - )) as Promise<TResponse>; + return (await originalRequestFn.call(opts.esClient.transport, params, { + ...options, + ...(requestTimeout + ? { + requestTimeout, + } + : {}), + })) as Promise<TResponse>; } return request; @@ -164,6 +176,7 @@ function getWrappedTransportRequestFn(opts: WrapEsClientOpts) { function getWrappedEqlSearchFn(opts: WrapEsClientOpts) { const originalEqlSearch = opts.esClient.eql.search; + const requestTimeout = opts.requestTimeout; // A bunch of overloads to make TypeScript happy async function search<TEvent = unknown>( @@ -188,10 +201,17 @@ function getWrappedEqlSearchFn(opts: WrapEsClientOpts) { opts.logger.debug( `executing eql query for rule ${opts.rule.alertTypeId}:${opts.rule.id} in space ${ opts.rule.spaceId - } - ${JSON.stringify(params)} - with options ${JSON.stringify(searchOptions)}` + } - ${JSON.stringify(params)} - with options ${JSON.stringify(searchOptions)}${ + requestTimeout ? ` and ${requestTimeout}ms requestTimeout` : '' + }` ); const result = (await originalEqlSearch.call(opts.esClient, params, { ...searchOptions, + ...(requestTimeout + ? { + requestTimeout, + } + : {}), signal: opts.abortController.signal, })) as TransportResult<EqlSearchResponse<TEvent>, unknown> | EqlSearchResponse<TEvent>; @@ -222,6 +242,7 @@ function getWrappedEqlSearchFn(opts: WrapEsClientOpts) { function getWrappedSearchFn(opts: WrapEsClientOpts) { const originalSearch = opts.esClient.search; + const requestTimeout = opts.requestTimeout; // A bunch of overloads to make TypeScript happy async function search< @@ -261,10 +282,17 @@ function getWrappedSearchFn(opts: WrapEsClientOpts) { opts.logger.debug( `executing query for rule ${opts.rule.alertTypeId}:${opts.rule.id} in space ${ opts.rule.spaceId - } - ${JSON.stringify(params)} - with options ${JSON.stringify(searchOptions)}` + } - ${JSON.stringify(params)} - with options ${JSON.stringify(searchOptions)}${ + requestTimeout ? ` and ${requestTimeout}ms requestTimeout` : '' + }` ); const result = (await originalSearch.call(opts.esClient, params, { ...searchOptions, + ...(requestTimeout + ? { + requestTimeout, + } + : {}), signal: opts.abortController.signal, })) as | TransportResult<SearchResponse<TDocument, TAggregations>, unknown> diff --git a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts index f3187eddc9d9a..21fe0e7ecb02f 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts @@ -64,6 +64,31 @@ describe('wrapSearchSourceClient', () => { }); }); + test('searches with provided request timeout', async () => { + const abortController = new AbortController(); + const { searchSourceMock, searchSourceClientMock } = createSearchSourceClientMock(); + + const { searchSourceClient } = wrapSearchSourceClient({ + logger, + rule, + searchSourceClient: searchSourceClientMock, + abortController, + requestTimeout: 5000, + }); + const wrappedSearchSource = await searchSourceClient.createEmpty(); + await wrappedSearchSource.fetch(); + + expect(searchSourceMock.fetch$).toHaveBeenCalledWith({ + abortSignal: abortController.signal, + transport: { + requestTimeout: 5000, + }, + }); + expect(logger.debug).toHaveBeenCalledWith( + `executing query for rule .test-rule-type:abcdefg in space my-space - with options {} and 5000ms requestTimeout` + ); + }); + test('uses search options when specified', async () => { const abortController = new AbortController(); const { searchSourceMock, searchSourceClientMock } = createSearchSourceClientMock(); @@ -73,13 +98,15 @@ describe('wrapSearchSourceClient', () => { rule, searchSourceClient: searchSourceClientMock, abortController, + requestTimeout: 5000, }); const wrappedSearchSource = await searchSourceClient.create(); - await wrappedSearchSource.fetch({ isStored: true }); + await wrappedSearchSource.fetch({ isStored: true, transport: { requestTimeout: 10000 } }); expect(searchSourceMock.fetch$).toHaveBeenCalledWith({ isStored: true, abortSignal: abortController.signal, + transport: { requestTimeout: 5000 }, }); }); diff --git a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts index 442f0c3e292bf..00577d39aaa97 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts @@ -21,6 +21,7 @@ interface Props { rule: RuleInfo; abortController: AbortController; searchSourceClient: ISearchStartSearchSource; + requestTimeout?: number; } interface WrapParams<T extends ISearchSource | SearchSource> { @@ -29,6 +30,7 @@ interface WrapParams<T extends ISearchSource | SearchSource> { abortController: AbortController; pureSearchSource: T; logMetrics: (metrics: LogSearchMetricsOpts) => void; + requestTimeout?: number; } export function wrapSearchSourceClient({ @@ -36,6 +38,7 @@ export function wrapSearchSourceClient({ rule, abortController, searchSourceClient: pureSearchSourceClient, + requestTimeout, }: Props) { let numSearches: number = 0; let esSearchDurationMs: number = 0; @@ -52,6 +55,7 @@ export function wrapSearchSourceClient({ logger, rule, abortController, + requestTimeout, }; const wrappedSearchSourceClient: ISearchStartSearchSource = Object.create(pureSearchSourceClient); @@ -137,6 +141,7 @@ function wrapFetch$({ abortController, pureSearchSource, logMetrics, + requestTimeout, }: WrapParams<ISearchSource>) { return (options?: ISearchOptions) => { const searchOptions = options ?? {}; @@ -145,12 +150,19 @@ function wrapFetch$({ logger.debug( `executing query for rule ${rule.alertTypeId}:${rule.id} in space ${ rule.spaceId - } - with options ${JSON.stringify(searchOptions)}` + } - with options ${JSON.stringify(searchOptions)}${ + requestTimeout ? ` and ${requestTimeout}ms requestTimeout` : '' + }` ); return pureSearchSource .fetch$({ ...searchOptions, + ...(requestTimeout + ? { + transport: { requestTimeout }, + } + : {}), abortSignal: abortController.signal, }) .pipe( diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 93f655965e92a..2733521eab88f 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -30,6 +30,7 @@ import { isRuleSnoozed, lastRunFromError, ruleExecutionStatusToRaw, + getEsRequestTimeout, } from '../lib'; import { IntervalSchedule, @@ -403,6 +404,8 @@ export class TaskRunner< }, logger: this.logger, abortController: this.searchAbortController, + // Set the ES request timeout to the rule task timeout + requestTimeout: getEsRequestTimeout(this.logger, this.ruleType.ruleTaskTimeout), }; const scopedClusterClient = this.context.elasticsearch.client.asScoped(fakeRequest); const wrappedScopedClusterClient = createWrappedScopedClusterClientFactory({ From 70489a648aa9a382fa88758d2ed3309acbf94d46 Mon Sep 17 00:00:00 2001 From: Jared Burgett <147995946+jaredburgettelastic@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:19:25 -0600 Subject: [PATCH 099/104] Add `keep_` to persisted project names created in CI builds (#176193) ## Summary This PR fixes an issue whereby the `ci:project-persist-deployment` doesn't prevent _all_ types of cleanup activities for serverless projects. In this case, one mechanism is in place today that deletes QA and Staging serverless projects after they are three days old, unless the project name is prepended with `keep_`. Therefore, this PR simply prepends with that prefix when the `ci:project-persist-deployment` label exists on the corresponding PR. ## Testing performed - [X] A positive test, to ensure that after 3 days, the desired persisted environment is not destroyed To test this, I simply left the environment up for about 5 days **without rerunning the CI build**, and observed that it was never killed. Further proof of that can be seen from `cat`ing the index creation dates directly from the console, and seeing that index creation dates (February 4th) were many days before the date they were retrieved (February 9th): <img width="1728" alt="Screenshot 2024-02-09 at 12 51 01 PM" src="https://github.com/elastic/kibana/assets/147995946/d4d85b28-a58a-4a10-9922-bfbf19bb827d"> - [x] A negative test, to ensure that **not** including the relevant `*persist*` label will result in the project name not prepended with `keep_` <img width="1173" alt="Screenshot 2024-02-09 at 3 58 41 PM" src="https://github.com/elastic/kibana/assets/147995946/e7edc678-71c9-4ba8-bf5b-100b5f6bef48"> --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .buildkite/scripts/steps/cloud/purge_projects.ts | 2 +- .buildkite/scripts/steps/serverless/build_and_deploy.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.buildkite/scripts/steps/cloud/purge_projects.ts b/.buildkite/scripts/steps/cloud/purge_projects.ts index c3c427c6a3885..dbf0060fe8a45 100644 --- a/.buildkite/scripts/steps/cloud/purge_projects.ts +++ b/.buildkite/scripts/steps/cloud/purge_projects.ts @@ -10,7 +10,7 @@ import { execSync } from 'child_process'; import axios from 'axios'; async function getPrProjects() { - const match = /^kibana-pr-([0-9]+)-(elasticsearch|security|observability)$/; + const match = /^(keep.?)?kibana-pr-([0-9]+)-(elasticsearch|security|observability)$/; try { return ( await Promise.all([ diff --git a/.buildkite/scripts/steps/serverless/build_and_deploy.sh b/.buildkite/scripts/steps/serverless/build_and_deploy.sh index b195d7ad36ea5..3301959d71ef0 100644 --- a/.buildkite/scripts/steps/serverless/build_and_deploy.sh +++ b/.buildkite/scripts/steps/serverless/build_and_deploy.sh @@ -22,6 +22,7 @@ deploy() { esac PROJECT_NAME="kibana-pr-$BUILDKITE_PULL_REQUEST-$PROJECT_TYPE" + is_pr_with_label "ci:project-persist-deployment" && PROJECT_NAME="keep_$PROJECT_NAME" PROJECT_CREATE_CONFIGURATION='{ "name": "'"$PROJECT_NAME"'", "region_id": "aws-eu-west-1", From 3646e8308e107f14038c85850b42cef1a3852250 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Sat, 10 Feb 2024 01:05:41 -0500 Subject: [PATCH 100/104] [api-docs] 2024-02-10 Daily api_docs build (#176648) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/609 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_observability.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 15 + api_docs/alerting.mdx | 4 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 4 + api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.devdocs.json | 4 + api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 6 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.devdocs.json | 90 +++++ api_docs/discover.mdx | 4 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_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/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.devdocs.json | 28 ++ api_docs/index_management.mdx | 4 +- api_docs/infra.mdx | 2 +- api_docs/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- .../kbn_alerting_api_integration_helpers.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_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- .../kbn_apm_synthtrace_client.devdocs.json | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_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_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_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 +- ...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 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- 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_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_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_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_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- .../kbn_deeplinks_observability.devdocs.json | 68 +++- api_docs/kbn_deeplinks_observability.mdx | 4 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_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.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_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_utils.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 +- .../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_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_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 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...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_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_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_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.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_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.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_library.mdx | 2 +- api_docs/kbn_presentation_publishing.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_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_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_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 +- api_docs/kbn_rison.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_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.devdocs.json | 85 +++++ api_docs/kbn_search_connectors.mdx | 4 +- 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_security_hardening.devdocs.json | 126 +++++++ api_docs/kbn_security_hardening.mdx | 30 ++ 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 +- 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 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_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_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_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_eui_helpers.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.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.devdocs.json | 228 ++++++++++++- api_docs/kbn_unified_data_table.mdx | 4 +- 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_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_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_explorer.devdocs.json | 314 +++++++++++++++--- api_docs/logs_explorer.mdx | 4 +- 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.mdx | 2 +- .../observability_a_i_assistant.devdocs.json | 10 - api_docs/observability_a_i_assistant.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 | 23 +- 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 +- .../saved_objects_management.devdocs.json | 42 +++ api_docs/saved_objects_management.mdx | 4 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 131 ++++++-- 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.mdx | 2 +- 665 files changed, 1773 insertions(+), 745 deletions(-) create mode 100644 api_docs/kbn_security_hardening.devdocs.json create mode 100644 api_docs/kbn_security_hardening.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 115f4386aef48..385bace06af5c 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-02-09 +date: 2024-02-10 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 019bd15d3c325..5734ae5e9beb4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index 42c4c6692a2f9..81bbb9eec6157 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index b5aac507e2bc6..e3c7fb1b34421 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-02-09 +date: 2024-02-10 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 97a8f45bb01b5..52baff9a29b68 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 2d02c951d2e79..a8744d59e78f1 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -11455,6 +11455,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RuleTypeMetaData", + "type": "Type", + "tags": [], + "label": "RuleTypeMetaData", + "description": [], + "signature": [ + "{ [x: string]: unknown; }" + ], + "path": "x-pack/plugins/alerting/common/rule.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleTypeParams", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index e251380a6e34a..3f58abbc34425 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 835 | 1 | 804 | 51 | +| 836 | 1 | 805 | 51 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 90bbd56a8b528..073c749dbaf0f 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-02-09 +date: 2024-02-10 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 f569b025a53d1..5fe323732a208 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 26e4b3d1f1295..26b95529e8e26 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 94c523989c981..a457f71e8152a 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-02-09 +date: 2024-02-10 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 dfba05dd87628..9903660e5fe92 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-02-09 +date: 2024-02-10 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 dd38559e6ac22..ef8952788418d 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-02-09 +date: 2024-02-10 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 1982280402cd7..51c8b686da324 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-02-09 +date: 2024-02-10 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 5116e22a5bb19..8662e11cc0b62 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-02-09 +date: 2024-02-10 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 42c64e2a21d52..8aecbad4d755b 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-02-09 +date: 2024-02-10 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 b658f61b0ab24..55eadee9af118 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-02-09 +date: 2024-02-10 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 3c785379ddab5..5239c88744810 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 42481abc23db6..2859e6ad0d3de 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 9e19fe61e9b9f..3e8c34896e442 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-02-09 +date: 2024-02-10 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 6daef6dae1c72..ef57dbe135be7 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-02-09 +date: 2024-02-10 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 063190e1275d6..ede55af292d72 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-02-09 +date: 2024-02-10 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 fad05eb06b5f6..20f2a4ff40aff 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-02-09 +date: 2024-02-10 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 9d8e1861c2b9f..73f9b520cb963 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-02-09 +date: 2024-02-10 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 5b73b2cd7e084..43d323614e724 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-02-09 +date: 2024-02-10 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 c132a96596292..3c102e384fdb5 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 48315db6ab3eb..d9c469084784c 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -3939,6 +3939,10 @@ "plugin": "alerting", "path": "x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts" }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts" + }, { "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type.test.ts" diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 05d8e7ccb8511..d392a2eaa6de3 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index a9e51e62bad4f..30f1279e2463d 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index d05fccecd35ff..4a605c11c427d 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -10448,6 +10448,10 @@ "plugin": "alerting", "path": "x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts" }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts" + }, { "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type.test.ts" diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index b46338404c5ca..cdef05f30954b 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index b62b7e22f2a87..730b676ca2340 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-02-09 +date: 2024-02-10 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 b93b69758028d..73cf10c137023 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-02-09 +date: 2024-02-10 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 0806b5b3e3085..7898b51c52ca3 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-02-09 +date: 2024-02-10 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 00dc6ebb0e065..385631c40e4cc 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-02-09 +date: 2024-02-10 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 bec2c355c602d..c0621eb6049da 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-02-09 +date: 2024-02-10 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 b45fb5963c7ce..82b645c4f7a3a 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-02-09 +date: 2024-02-10 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 a6831274020f7..a73f304c5640f 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 23a002e9e0158..20ccee017d4c6 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -358,11 +358,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts#:~:text=create) | - | -| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | - | +| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | - | | <DocLink id="kibDataPluginApi" section="def-public.SavedObject.migrationVersion" text="migrationVersion"/> | [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion) | - | | <DocLink id="kibDataPluginApi" section="def-common.SavedObject.migrationVersion" text="migrationVersion"/> | [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion), [retrieve_migrated_legacy_actions.mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock.ts#:~:text=migrationVersion)+ 10 more | - | | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts#:~:text=create) | - | -| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | - | +| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | - | | <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getKibanaFeatures" text="getKibanaFeatures"/> | [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/plugin.test.ts#:~:text=getKibanaFeatures) | 8.8.0 | | <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaThemeProvider" text="KibanaThemeProvider"/> | [maintenance_windows.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/public/application/maintenance_windows.tsx#:~:text=KibanaThemeProvider), [maintenance_windows.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/public/application/maintenance_windows.tsx#:~:text=KibanaThemeProvider), [maintenance_windows.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/public/application/maintenance_windows.tsx#:~:text=KibanaThemeProvider) | - | | <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/plugin.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24) | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 1270524fcc80b..8268c82e8b3d7 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 037d373715e25..8aac3a6f3b46f 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 0671ccf421cf3..60885dad84dc3 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -72,6 +72,96 @@ } ], "interfaces": [ + { + "parentPluginId": "discover", + "id": "def-public.DataDocumentsMsg", + "type": "Interface", + "tags": [], + "label": "DataDocumentsMsg", + "description": [], + "signature": [ + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.DataDocumentsMsg", + "text": "DataDocumentsMsg" + }, + " extends ", + "DataMsg" + ], + "path": "src/plugins/discover/public/application/main/services/discover_data_state_container.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DataDocumentsMsg.result", + "type": "Array", + "tags": [], + "label": "result", + "description": [], + "signature": [ + "DataTableRecord", + "[] | undefined" + ], + "path": "src/plugins/discover/public/application/main/services/discover_data_state_container.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DataDocumentsMsg.textBasedQueryColumns", + "type": "Array", + "tags": [], + "label": "textBasedQueryColumns", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.DatatableColumn", + "text": "DatatableColumn" + }, + "[] | undefined" + ], + "path": "src/plugins/discover/public/application/main/services/discover_data_state_container.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DataDocumentsMsg.textBasedHeaderWarning", + "type": "string", + "tags": [], + "label": "textBasedHeaderWarning", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/discover/public/application/main/services/discover_data_state_container.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DataDocumentsMsg.interceptedWarnings", + "type": "Array", + "tags": [], + "label": "interceptedWarnings", + "description": [], + "signature": [ + "SearchResponseIncompleteWarning", + "[] | undefined" + ], + "path": "src/plugins/discover/public/application/main/services/discover_data_state_container.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.DiscoverAppState", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index f434343e332e2..9dd4510a41dac 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 151 | 0 | 104 | 22 | +| 156 | 0 | 109 | 23 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index d5f7d8d841fae..27d0e5d0fd8c3 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index b6a0f43059884..42d6e47ce507e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 647b512be90ca..6d7a2905a27eb 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index da131042b7f00..003522e0f9da7 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-02-09 +date: 2024-02-10 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 458a49dc4576f..d687aea7596fe 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-02-09 +date: 2024-02-10 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 660f63491f660..94b2eae124249 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-02-09 +date: 2024-02-10 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 690c1dc9867f6..7d8023458a887 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index cd3829569f92a..194930dcde554 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 19ec9e3ad6569..eca9aadb77c3d 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-02-09 +date: 2024-02-10 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 9650bb4ef17ea..c68eb28a03abc 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-02-09 +date: 2024-02-10 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 c3ab21ffe81ba..46f771ff07dc1 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-02-09 +date: 2024-02-10 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 ff3c3ca179435..e9f05619a8dd3 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-02-09 +date: 2024-02-10 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 d81a36f9bafdc..7aecfd92d86d6 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-02-09 +date: 2024-02-10 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 06e9f6e9e81a8..deb9c5c6d549a 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-02-09 +date: 2024-02-10 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 a71631695a985..707689b79f325 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-02-09 +date: 2024-02-10 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 3df160887b6cf..b278d5a2cb1a9 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-02-09 +date: 2024-02-10 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 67be9823478cb..3ff1b3b40985d 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-02-09 +date: 2024-02-10 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 d8c286d4ce4d3..2a5faba1310bb 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-02-09 +date: 2024-02-10 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 157ffba8020d8..c10ad2a572013 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-02-09 +date: 2024-02-10 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 1cd75f9f63cdc..570e60ec1385b 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-02-09 +date: 2024-02-10 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 17ef809d3d559..c5fe43d2d2e02 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-02-09 +date: 2024-02-10 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 9c6500812fa1b..ab32d9a193695 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-02-09 +date: 2024-02-10 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 f54bec29cb634..6ea64173bfd47 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-02-09 +date: 2024-02-10 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 22b3345eab76c..5978901522114 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-02-09 +date: 2024-02-10 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 78e0702f056da..32e35b30b4405 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-02-09 +date: 2024-02-10 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 f466543b12002..7f3c3ab3d9aa7 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-02-09 +date: 2024-02-10 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 75b19c5e1f8a7..66a8d7ac10e0c 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-02-09 +date: 2024-02-10 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 6cd1d8e033548..44cc417be8e3a 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index b35505afaed9a..c3f78beaa3dc8 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-02-09 +date: 2024-02-10 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 fc6f0f3b05ecc..7cd528bfd6806 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-02-09 +date: 2024-02-10 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 201c6e551838a..a113b757d4230 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-02-09 +date: 2024-02-10 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 928790bcaf80b..71a1488267568 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-02-09 +date: 2024-02-10 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 270fbb4bb8353..da2511ef2e085 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-02-09 +date: 2024-02-10 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 c2c90ef74c41a..9ba4c3632a097 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-02-09 +date: 2024-02-10 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 9b9d0e634a94c..c811bf4bbd5fd 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-02-09 +date: 2024-02-10 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 754bedf184518..90f6feadffa18 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 32705d1648210..266deabab25bf 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.devdocs.json b/api_docs/index_management.devdocs.json index d22836d359b90..f8c8586ef5d98 100644 --- a/api_docs/index_management.devdocs.json +++ b/api_docs/index_management.devdocs.json @@ -2766,6 +2766,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "indexManagement", + "id": "def-common.TemplateDeserialized.ignoreMissingComponentTemplates", + "type": "Array", + "tags": [], + "label": "ignoreMissingComponentTemplates", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/templates.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "indexManagement", "id": "def-common.TemplateDeserialized.version", @@ -3223,6 +3237,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "indexManagement", + "id": "def-common.TemplateSerialized.ignore_missing_component_templates", + "type": "Array", + "tags": [], + "label": "ignore_missing_component_templates", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/templates.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "indexManagement", "id": "def-common.TemplateSerialized.version", diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 3a768e9967fb3..d4fbbc6f8bf3c 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 224 | 0 | 219 | 4 | +| 226 | 0 | 221 | 4 | ## Client diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 0ec57d3bcd354..1f7a532261ba4 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-02-09 +date: 2024-02-10 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 ae98136b761f6..c7bfd305adcec 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-02-09 +date: 2024-02-10 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 853138009d5b5..f9c4a9d60d719 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 08702c811890d..295c7178e61bd 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index f91d33074701f..f1eeacedbb20c 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 5a78384eace86..36183318e0f30 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 4ca8e049e499e..393b9c4e201a8 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 455bafc674a7a..064f89eaed226 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 86710beeb4c81..5b7c96246091e 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-02-09 +date: 2024-02-10 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_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index d57a7feb85b32..2f9646e08c988 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-02-09 +date: 2024-02-10 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 4183413afad5a..7c53292350518 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-02-09 +date: 2024-02-10 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 1fc684bd544bc..e6bd9400e916b 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 0ba0b2620abb2..8715e94ca938c 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-02-09 +date: 2024-02-10 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 bb46d2676e515..5a81d02650139 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 9a8c352cc395e..d2407c6a00f8e 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index cd1d33b6ffd8e..dc98e3f1031da 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 54b348796dd46..903d5f709db6c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 20073dce81e16..2ed519c7c509d 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index e0ef711289a41..571cd44598eca 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index e320a6b3510f8..9993c04d8306c 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 7b43a1afd58fc..9db415a0f553d 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index a37531a769212..991c7c658d887 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-02-09 +date: 2024-02-10 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.devdocs.json b/api_docs/kbn_apm_synthtrace_client.devdocs.json index 7c7c53d407261..a84b8813a4500 100644 --- a/api_docs/kbn_apm_synthtrace_client.devdocs.json +++ b/api_docs/kbn_apm_synthtrace_client.devdocs.json @@ -2622,7 +2622,7 @@ "label": "LogDocument", "description": [], "signature": [ - "{ '@timestamp'?: number | undefined; } & Partial<{ 'input.type': string; 'log.file.path'?: string | undefined; 'service.name'?: string | undefined; 'data_stream.namespace': string; 'data_stream.type': string; 'data_stream.dataset': string; message?: string | undefined; 'error.message'?: string | undefined; 'event.original'?: string | undefined; 'event.dataset': string; 'log.level'?: string | undefined; 'host.name'?: string | undefined; 'trace.id'?: string | undefined; 'agent.id'?: string | undefined; 'agent.name'?: string | undefined; 'orchestrator.cluster.name'?: string | undefined; 'orchestrator.cluster.id'?: string | undefined; 'orchestrator.resource.id'?: string | undefined; 'orchestrator.namespace'?: string | undefined; 'container.name'?: string | undefined; 'cloud.provider'?: string | undefined; 'cloud.region'?: string | undefined; 'cloud.availability_zone'?: string | undefined; 'cloud.project.id'?: string | undefined; 'cloud.instance.id'?: string | undefined; }>" + "{ '@timestamp'?: number | undefined; } & Partial<{ 'input.type': string; 'log.file.path'?: string | undefined; 'service.name'?: string | undefined; 'data_stream.namespace': string; 'data_stream.type': string; 'data_stream.dataset': string; message?: string | undefined; 'error.message'?: string | undefined; 'event.original'?: string | undefined; 'event.dataset': string; 'log.level'?: string | undefined; 'host.name'?: string | undefined; 'trace.id'?: string | undefined; 'agent.id'?: string | undefined; 'agent.name'?: string | undefined; 'orchestrator.cluster.name'?: string | undefined; 'orchestrator.cluster.id'?: string | undefined; 'orchestrator.resource.id'?: string | undefined; 'orchestrator.namespace'?: string | undefined; 'container.name'?: string | undefined; 'cloud.provider'?: string | undefined; 'cloud.region'?: string | undefined; 'cloud.availability_zone'?: string | undefined; 'cloud.project.id'?: string | undefined; 'cloud.instance.id'?: string | undefined; 'error.stack_trace'?: string | undefined; 'error.exception.stacktrace'?: string | undefined; 'error.log.stacktrace'?: string | undefined; }>" ], "path": "packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts", "deprecated": false, diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 557ba7d958a56..be5f8a74f544e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 04080a1dc6294..c117496622630 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index a0f0b3ea219ba..7388f586fd99e 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-02-09 +date: 2024-02-10 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 a57184782862a..924255022d659 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-02-09 +date: 2024-02-10 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 2a00f975cc1b8..d5dad96ca9487 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-02-09 +date: 2024-02-10 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 620fe0d81ee7a..ed41a608c2cfe 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-02-09 +date: 2024-02-10 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 d409d4dff41ee..37c4588f5af95 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 1ea558d1c0fe0..09aed137aebe3 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-02-09 +date: 2024-02-10 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 298730948f679..4df8356b2ea5e 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-02-09 +date: 2024-02-10 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 c6742a81d759c..bdee9298139c5 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-02-09 +date: 2024-02-10 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 4d9b4ddb42cdb..341b80db560be 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-02-09 +date: 2024-02-10 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 5c7538b48e25f..ca0e8165aa69b 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-02-09 +date: 2024-02-10 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 7853d329c44cd..71f560eba2896 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-02-09 +date: 2024-02-10 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 c0d42c521e8ae..86feb7c0db9ae 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index d2bf8edbb215d..d86b8602c204a 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-02-09 +date: 2024-02-10 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 9e1d5657ac9ee..8aae4cc7da1cc 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-02-09 +date: 2024-02-10 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 771065ee21a7a..2b978b8bca133 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-02-09 +date: 2024-02-10 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 38598c5806820..16a510b5f493f 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-02-09 +date: 2024-02-10 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 98d8920cb1742..d9115d0c2cf16 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-02-09 +date: 2024-02-10 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 d24ad40a1c4ab..0ef3138330707 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-02-09 +date: 2024-02-10 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 04f71faabdb8c..939a7867fa46f 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-02-09 +date: 2024-02-10 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 32d4045f30fd2..acc66e6975c3e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index f70c70ab7759f..f9709d3c5b4a1 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-02-09 +date: 2024-02-10 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 a03dfbcadec25..0a95998371bd4 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-02-09 +date: 2024-02-10 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 fb71a63ef5225..787f450b21f24 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-02-09 +date: 2024-02-10 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 34dd186d926a8..b99fd3702fdde 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 549bb2feb6b94..5878bb149fa68 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 3926d5e25fed3..1902da366b1e3 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-02-09 +date: 2024-02-10 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 3215bb87f5926..de0cb33baabe7 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-02-09 +date: 2024-02-10 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 721124b4b77fc..eec32019b79b5 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index f0f6680eb7959..937613c5a8557 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-02-09 +date: 2024-02-10 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 a032d14985995..2966b582c7378 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-02-09 +date: 2024-02-10 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 e0fecfbb149e7..ab7819913bf7e 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-02-09 +date: 2024-02-10 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 ad08f59c4f9cc..0b9418d473ed6 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-02-09 +date: 2024-02-10 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 2da9061231c2c..dc7b32770eb0f 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-02-09 +date: 2024-02-10 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 9a31b8d50eb72..4a05c83be1775 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-02-09 +date: 2024-02-10 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 fcf53dae6e5f8..f81c1ec314a42 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-02-09 +date: 2024-02-10 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 9ab432d212789..bb10a729ebae7 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-02-09 +date: 2024-02-10 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 ece12e4c90739..ba349fbfdb853 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-02-09 +date: 2024-02-10 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 36256d83d3945..ccf53d45f6a40 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-02-09 +date: 2024-02-10 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 78712eef526ae..523b1c8107eeb 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-02-09 +date: 2024-02-10 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 179383d10382f..8feb1db2cf147 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-02-09 +date: 2024-02-10 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 9431b2fd4e656..07ecf91a4c42e 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-02-09 +date: 2024-02-10 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 e9aaaee4327bd..759df6adf3ea5 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-02-09 +date: 2024-02-10 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 a188198b4e65a..ce66a7d77cd00 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-02-09 +date: 2024-02-10 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 c52b13ffc8c48..35109e0feced4 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-02-09 +date: 2024-02-10 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 2e5d216f9a75c..7a702564cb4f2 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-02-09 +date: 2024-02-10 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 f71762235774c..c7d059754d0c4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 59e557067b445..8134214a2ea4e 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-02-09 +date: 2024-02-10 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 88537178c2361..c5eed9334e92a 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-02-09 +date: 2024-02-10 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 741948997874d..9b59973ac6bf5 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-02-09 +date: 2024-02-10 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 b134ded6593c1..b0efc51397f58 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-02-09 +date: 2024-02-10 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 86f6394a55002..5a03985977ded 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-02-09 +date: 2024-02-10 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 05043323e4a66..5cdbf567386d0 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-02-09 +date: 2024-02-10 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 037d8f6cd1264..a267385219fcf 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-02-09 +date: 2024-02-10 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 db199721b502d..cffc7f422d36d 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-02-09 +date: 2024-02-10 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 91b14abb2b14e..fe182cc8a7c8f 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-02-09 +date: 2024-02-10 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 de58bc1a17dee..772e457b019c7 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-02-09 +date: 2024-02-10 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 db905326022ba..35bb11a528db6 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-02-09 +date: 2024-02-10 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 6b2428410abf4..8b31794f54a11 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-02-09 +date: 2024-02-10 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 28ef5672af61c..8f051aae78749 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-02-09 +date: 2024-02-10 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 df802ff949c9e..61649bb1b8142 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-02-09 +date: 2024-02-10 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 36fecd26abcf3..11f9add6c507d 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-02-09 +date: 2024-02-10 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 39779844c22de..fc3710f36b04e 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-02-09 +date: 2024-02-10 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 f89980ad40395..e8989b93c296d 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-02-09 +date: 2024-02-10 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 ed53110d28841..27a309c42f5c4 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-02-09 +date: 2024-02-10 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 acb646eb7df7d..19821de0267bf 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-02-09 +date: 2024-02-10 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 ad742f24447d6..a9a168afb1ef7 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-02-09 +date: 2024-02-10 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 3df137049f5cf..7381f962b4feb 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-02-09 +date: 2024-02-10 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 46f0408843556..ca2cf8b282ff5 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-02-09 +date: 2024-02-10 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 74b7d2a56b9c6..397e8fda55e92 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-02-09 +date: 2024-02-10 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 7a74e136b28b2..6b5435b15b17f 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-02-09 +date: 2024-02-10 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 0684ee5f25010..4b80b31e2f9be 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-02-09 +date: 2024-02-10 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 1c1311a46cf70..3cdb305df92eb 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-02-09 +date: 2024-02-10 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 4fccd42c66a51..7f11b0532937d 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-02-09 +date: 2024-02-10 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 49729176401fe..20351accd4c36 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-02-09 +date: 2024-02-10 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 eec37cda36f8c..3183542db20c4 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-02-09 +date: 2024-02-10 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 d5f6f29f47082..89ed95c29ef1b 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-02-09 +date: 2024-02-10 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 6e28ddfdcb30b..238de24f9ccab 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-02-09 +date: 2024-02-10 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 169e776b9b921..3b266e5293b15 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-02-09 +date: 2024-02-10 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 6488421234530..631db8084cd76 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-02-09 +date: 2024-02-10 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 5679ce0a19b48..b54a45840bd36 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-02-09 +date: 2024-02-10 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 3eef2e014d239..6bf7cca624cfa 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-02-09 +date: 2024-02-10 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 b181e9e577e90..9735265dd33ba 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-02-09 +date: 2024-02-10 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 4909257a2057f..81e5b6b9b3c55 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 96127c88f1674..942b52f3098cd 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-02-09 +date: 2024-02-10 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 c44ce193a5555..7d90946cab1bd 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-02-09 +date: 2024-02-10 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 155d3a416f6d5..72c6ebe96708b 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-02-09 +date: 2024-02-10 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 26de513980693..62f1e5d762a64 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-02-09 +date: 2024-02-10 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 07f0b3a64377b..21219eefda9a5 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-02-09 +date: 2024-02-10 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 0ea61e132a342..c9e3f32ce8438 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-02-09 +date: 2024-02-10 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 38c7833b394b7..93781ec36eca3 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-02-09 +date: 2024-02-10 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 6973f29ce606b..c0ea6831350b4 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-02-09 +date: 2024-02-10 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 ba0f75ac4ff7e..266c2ebd7dd2b 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-02-09 +date: 2024-02-10 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 090643b7a3add..164507696e107 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-02-09 +date: 2024-02-10 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 7db0224162ae7..c752470fce9ec 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 164d8a2f63807..7e26a285432ba 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-02-09 +date: 2024-02-10 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 06ba81eb1e681..815a8b2c4b777 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-02-09 +date: 2024-02-10 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 838b18e3259ad..97b5079457d95 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-02-09 +date: 2024-02-10 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 fbea4395a9efa..afa686edf71a4 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-02-09 +date: 2024-02-10 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 d39c5b096f786..f7f3971751506 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-02-09 +date: 2024-02-10 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 3f6c3f7513069..045f2498b6446 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-02-09 +date: 2024-02-10 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 0fe3e0bd9dbe0..c126972883b7b 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-02-09 +date: 2024-02-10 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 305abf2116b7f..6a47c1c26cc09 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-02-09 +date: 2024-02-10 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 121fc65b893f8..4fa95fc2cf606 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-02-09 +date: 2024-02-10 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 af5ce48ece29c..ab93441e8da46 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-02-09 +date: 2024-02-10 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 61c681743d11c..60a5bbe0a846f 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-02-09 +date: 2024-02-10 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 6aa40c5376992..ae35d2ed85e19 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-02-09 +date: 2024-02-10 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 644d4785a4068..0df896bda210d 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-02-09 +date: 2024-02-10 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 17e9f15ce7541..3e3a3dc391f41 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-02-09 +date: 2024-02-10 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 3e5a308d98c4a..aba33bff6d31f 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-02-09 +date: 2024-02-10 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 38f1ce3e8da21..e6495b961442a 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-02-09 +date: 2024-02-10 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 baa95ebf354d9..776cb38e8283a 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-02-09 +date: 2024-02-10 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 fe99caeafa0d9..fde5f7a2f01bc 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-02-09 +date: 2024-02-10 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 f1d3d0bcfe842..e71ceb01ac7ab 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-02-09 +date: 2024-02-10 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 79dc33320d520..965ab641cc59f 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-02-09 +date: 2024-02-10 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 3b55b56aa9a2d..90cfc709b801b 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-02-09 +date: 2024-02-10 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 cdf2cd510154f..00410c3af99bf 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-02-09 +date: 2024-02-10 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 39bdac22a4417..3ef5c8a0f7380 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-02-09 +date: 2024-02-10 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 ad81b9d80215e..3b717e577e6b5 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-02-09 +date: 2024-02-10 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 1b8ba4628c55c..a9fa3cc078672 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-02-09 +date: 2024-02-10 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 6e9fd81c053eb..85d7b44679526 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-02-09 +date: 2024-02-10 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 5dec14f1bcdf3..d719bf928f140 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-02-09 +date: 2024-02-10 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 c6979b3c692c6..e454a0a9b9454 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-02-09 +date: 2024-02-10 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 135648aa4ca1e..de391fbda8537 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-02-09 +date: 2024-02-10 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 13530b487ca38..32547fcfb42ae 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-02-09 +date: 2024-02-10 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 ca94dd5d0dbf4..6688150902809 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-02-09 +date: 2024-02-10 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 be8ce3c257010..eef75e992f7fb 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-02-09 +date: 2024-02-10 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 51697b434c7c0..989599138061b 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-02-09 +date: 2024-02-10 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 0dc144b888cf2..e855ae4e38644 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-02-09 +date: 2024-02-10 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 cdc66b902f4d7..7e2ea15f45a96 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-02-09 +date: 2024-02-10 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 7f2e4c0092d01..7701b3dd886bb 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-02-09 +date: 2024-02-10 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 628e2a2271362..71219cb242432 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-02-09 +date: 2024-02-10 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 9c71bbfcf8020..f29dcfb55ae81 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-02-09 +date: 2024-02-10 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 fdeefddaa5224..0ef955671242e 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-02-09 +date: 2024-02-10 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 57ff37290f3b9..4efbdad0e2747 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-02-09 +date: 2024-02-10 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 0ccc818ea2b74..dbde40fcc73b5 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-02-09 +date: 2024-02-10 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 ca5c6fede86a6..b3ee3839939c5 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-02-09 +date: 2024-02-10 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 82f332ce95c36..bb7f38d3b6e13 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-02-09 +date: 2024-02-10 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 e5930f159137f..557854da25915 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-02-09 +date: 2024-02-10 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 ca862bafd9098..d39ecc895ad4c 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-02-09 +date: 2024-02-10 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 d94caa14c08e7..9f700f97c289b 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-02-09 +date: 2024-02-10 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 6bc07bde6e37d..4a62c1724c8ad 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-02-09 +date: 2024-02-10 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 b3cb7976fd1b8..9ceb806ba76a2 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-02-09 +date: 2024-02-10 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 b9b8fb0061e11..275e1ba19060d 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-02-09 +date: 2024-02-10 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 a0881f056f5a8..712bbcd67e7e0 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-02-09 +date: 2024-02-10 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 d0292510f0938..c5ba1f3b3513b 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-02-09 +date: 2024-02-10 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 dd046a7eb50b8..dc91d6647528a 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-02-09 +date: 2024-02-10 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 d0371c3351ea3..d5736d527411b 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-02-09 +date: 2024-02-10 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 19e1ecdf93383..af41c951d61c9 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-02-09 +date: 2024-02-10 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 438065b0806bd..2532cf0b42d1b 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-02-09 +date: 2024-02-10 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 5b062b88dc643..d98b89ce8926a 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-02-09 +date: 2024-02-10 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 110326acbce69..cbc8d55e7d8b7 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-02-09 +date: 2024-02-10 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 bbb694f4aab14..fed1e77f2466e 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-02-09 +date: 2024-02-10 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 de9470a5565a7..346cc4f47eebf 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-02-09 +date: 2024-02-10 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 a190ee5a379e1..e0d1ab00dbed6 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-02-09 +date: 2024-02-10 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 a746d4ba451ae..da8dd4e70576c 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-02-09 +date: 2024-02-10 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 7bc2b8c957867..9a16ba0f67f34 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-02-09 +date: 2024-02-10 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 41e3e34710bd1..04d7e364e1c97 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-02-09 +date: 2024-02-10 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 4dc9d755faf02..e179632b24033 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 649a6ffb06e95..b0a7a2a0ad1ad 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-02-09 +date: 2024-02-10 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 637e6dfb7dbac..867337b0818d0 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-02-09 +date: 2024-02-10 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 10da6e76e9204..cffb76324bdd8 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-02-09 +date: 2024-02-10 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 aa23dbbc647a6..68e833c0eefb7 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-02-09 +date: 2024-02-10 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 4b4b87fb68cb6..7747b56e0065c 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-02-09 +date: 2024-02-10 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 4b90da9f68263..52e07c7423a9d 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-02-09 +date: 2024-02-10 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 c73e5ec0d18a4..27e7c486236fe 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-02-09 +date: 2024-02-10 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 4840d82595729..56c0bbc5c9d28 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-02-09 +date: 2024-02-10 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 4c041e86ae8be..308ec720b09d9 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-02-09 +date: 2024-02-10 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 e2615cea23202..5b8219fd130ae 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-02-09 +date: 2024-02-10 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 31d8fdb184af5..56d810c8b9d4d 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-02-09 +date: 2024-02-10 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 219afd3592a34..01ba055003c58 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-02-09 +date: 2024-02-10 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 7b5f61237f6b3..03b406dd53618 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-02-09 +date: 2024-02-10 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 81678e0102d2b..c3a318fdd8506 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-02-09 +date: 2024-02-10 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 fbfe4a6552b0a..21e53212f1a9b 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-02-09 +date: 2024-02-10 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 c9db37f430de7..129e221381f71 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-02-09 +date: 2024-02-10 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 4bf085ebc208b..0151abd60c96d 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-02-09 +date: 2024-02-10 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 4a389f2898ae4..05375848de0a8 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-02-09 +date: 2024-02-10 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 d424d2962ab17..e6e92e1ddb15b 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-02-09 +date: 2024-02-10 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 efe4f84af141c..f4ff48ee2390f 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-02-09 +date: 2024-02-10 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 93c4d56f40bde..5d44cd1340411 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-02-09 +date: 2024-02-10 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 bf6ebbdfd47ed..7ca4dfc2af7f6 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-02-09 +date: 2024-02-10 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 97389e4d22d49..55fc147bb51b1 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 5b4115cac027c..7baffd9a337dd 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 75cdce9b521fb..beeb43494f56d 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 6f56a7755e053..955bab1c0907f 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-02-09 +date: 2024-02-10 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 4715f12fc898f..8382b8b7211c5 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-02-09 +date: 2024-02-10 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 bbcb348c42f2f..2b5db318bbf8f 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-02-09 +date: 2024-02-10 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 57e748d0e694f..ef4bc5ca86c54 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-02-09 +date: 2024-02-10 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 d50514650aea1..7401acb07f77f 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-02-09 +date: 2024-02-10 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 18d7e6c7c8cf1..242813d24b42a 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-02-09 +date: 2024-02-10 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 6f339d1160567..abf0fc99e6675 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-02-09 +date: 2024-02-10 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 e4d95b99fe97d..1d140c39438c2 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-02-09 +date: 2024-02-10 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 9ad6e7f84fef9..4666c49629ff7 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-02-09 +date: 2024-02-10 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 974f54465d54e..c226bd958f071 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-02-09 +date: 2024-02-10 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 d3adf40c8b6b3..7c1b33236f042 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-02-09 +date: 2024-02-10 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 4889f73413526..7df5aff22f019 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-02-09 +date: 2024-02-10 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 6e955779ed799..8d4f6e607057b 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index e7dfe6c394eec..23726b5256c23 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-02-09 +date: 2024-02-10 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 5f1e20e5f7a75..bc89b167d2fb1 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.devdocs.json b/api_docs/kbn_deeplinks_observability.devdocs.json index d98b4ba490885..8283e29631a8a 100644 --- a/api_docs/kbn_deeplinks_observability.devdocs.json +++ b/api_docs/kbn_deeplinks_observability.devdocs.json @@ -182,7 +182,14 @@ "\nColumns displayed in the table" ], "signature": [ - "string[] | undefined" + { + "pluginId": "@kbn/deeplinks-observability", + "scope": "common", + "docId": "kibKbnDeeplinksObservabilityPluginApi", + "section": "def-common.GridColumnDisplayOptions", + "text": "GridColumnDisplayOptions" + }, + "[] | undefined" ], "path": "packages/deeplinks/observability/locators/logs_explorer.ts", "deprecated": false, @@ -502,6 +509,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/deeplinks-observability", + "id": "def-common.DocumentFieldGridColumnOptions", + "type": "Type", + "tags": [], + "label": "DocumentFieldGridColumnOptions", + "description": [], + "signature": [ + "{ type: \"document-field\"; field: string; width?: number | undefined; }" + ], + "path": "packages/deeplinks/observability/locators/logs_explorer.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/deeplinks-observability", "id": "def-common.FilterControls", @@ -525,6 +547,35 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/deeplinks-observability", + "id": "def-common.GridColumnDisplayOptions", + "type": "Type", + "tags": [], + "label": "GridColumnDisplayOptions", + "description": [], + "signature": [ + { + "pluginId": "@kbn/deeplinks-observability", + "scope": "common", + "docId": "kibKbnDeeplinksObservabilityPluginApi", + "section": "def-common.DocumentFieldGridColumnOptions", + "text": "DocumentFieldGridColumnOptions" + }, + " | ", + { + "pluginId": "@kbn/deeplinks-observability", + "scope": "common", + "docId": "kibKbnDeeplinksObservabilityPluginApi", + "section": "def-common.SmartFieldGridColumnOptions", + "text": "SmartFieldGridColumnOptions" + } + ], + "path": "packages/deeplinks/observability/locators/logs_explorer.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/deeplinks-observability", "id": "def-common.ListFilterControl", @@ -659,6 +710,21 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/deeplinks-observability", + "id": "def-common.SmartFieldGridColumnOptions", + "type": "Type", + "tags": [], + "label": "SmartFieldGridColumnOptions", + "description": [], + "signature": [ + "{ type: \"smart-field\"; smartField: \"resource\" | \"content\"; width?: number | undefined; }" + ], + "path": "packages/deeplinks/observability/locators/logs_explorer.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false } ], "objects": [] diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 7f56fac1bf2f7..0aa020795fc6e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 31 | 0 | 21 | 0 | +| 34 | 0 | 24 | 0 | ## Common diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index 0dd14ff590145..934fb73f600ab 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index bf24f7bda0859..d8b00b3414c98 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-02-09 +date: 2024-02-10 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 644a61188b0c6..1f118459d856b 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-02-09 +date: 2024-02-10 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 d7d9e2cfc5b90..6320bf7d18323 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-02-09 +date: 2024-02-10 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 596b634de26e9..a00814e7c3c34 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-02-09 +date: 2024-02-10 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 c10b7d64cc687..512a88036b08a 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-02-09 +date: 2024-02-10 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 f6872868fc1b5..9feb9ca85abee 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-02-09 +date: 2024-02-10 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 fee77dc627bc7..84d2b407e1c43 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-02-09 +date: 2024-02-10 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 9a121b7f37f1d..c2879ebfe52c8 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 23b0fcf2d7472..0f258bf4ca1f0 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-02-09 +date: 2024-02-10 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 dacdafd0d7933..a9126f067853c 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-02-09 +date: 2024-02-10 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 832fd32f4c0e3..15e83084ea426 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-02-09 +date: 2024-02-10 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 433c22857f16a..fc644d967dfcf 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-02-09 +date: 2024-02-10 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 3e71821e69440..c0794e88e5525 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 340b7a8f82eea..a6bed31af50f5 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 0019af3c0b3e3..8e642b6ec5664 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-02-09 +date: 2024-02-10 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 3c343b5e649da..052ef3400ee5b 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-02-09 +date: 2024-02-10 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 6a715ffc42ee8..b5ca26607e577 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-02-09 +date: 2024-02-10 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 6845221fe0690..818ec2c3f6c3d 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 9e4242719e17c..83abbd1cc51c5 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-02-09 +date: 2024-02-10 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 dfaee0807c644..4efc5364c8bc7 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-02-09 +date: 2024-02-10 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 1670a936a123d..36149a69b2837 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-02-09 +date: 2024-02-10 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 7bc0a39300a47..a3ab6e0049fb2 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 82ac58554ea3a..1d9ca732a6b97 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-02-09 +date: 2024-02-10 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 a182a48b1df15..1c05716c6e91e 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-02-09 +date: 2024-02-10 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_utils.mdx b/api_docs/kbn_esql_utils.mdx index b7d1ae017993f..011047050c9b4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index ae04a3e63b504..f1bb33842488a 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-02-09 +date: 2024-02-10 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 a50b28c3fd8bc..c4ac6cc29456e 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-02-09 +date: 2024-02-10 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 6830e740cb539..25f3648f36f01 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-02-09 +date: 2024-02-10 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 9b698333817f8..3ce0842a1c2d5 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-02-09 +date: 2024-02-10 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 860dac5479cef..d12a4434a634c 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-02-09 +date: 2024-02-10 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 3a86c1288dca9..b78352b547a7a 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index e43f17049f58c..058d20814bc55 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-02-09 +date: 2024-02-10 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 f6e883fc5fc30..2bdcee8425ca3 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-02-09 +date: 2024-02-10 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 0c691111495b9..790280c86d5d5 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-02-09 +date: 2024-02-10 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 81303fb5bfdb5..8968068f83f77 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-02-09 +date: 2024-02-10 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 f57873ff5cc13..19753a377151c 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index f58d0a99cc952..c0f9a940d0ae5 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-02-09 +date: 2024-02-10 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 e31d2633e8caf..bf63f73ac1b56 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-02-09 +date: 2024-02-10 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 8f5ea622d0c23..ff261138ec12a 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-02-09 +date: 2024-02-10 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 3b7917c4114f9..b8ba063f387a1 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-02-09 +date: 2024-02-10 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 5e1c688419154..962dd3f0f2400 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-02-09 +date: 2024-02-10 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 724597fb023b8..f525c42a8bdd6 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-02-09 +date: 2024-02-10 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 aa1d392350d5c..08aff73759d83 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-02-09 +date: 2024-02-10 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 54761ab07b92a..0c6644fcfa7d3 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-02-09 +date: 2024-02-10 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 e10b74b3a9ea4..e811b00965b2e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 9453bed176fe7..8d8b03f15d933 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-02-09 +date: 2024-02-10 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 80081f5a58c47..8f354f520e2b6 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index abd58762cf676..05adcf6fe8298 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index ea92d30647b04..9b54d20bf6cf9 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-02-09 +date: 2024-02-10 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 f5453250cae94..98a56b90e57d9 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-02-09 +date: 2024-02-10 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 acb470ccf8bbf..b94b252c606d4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 3ce69024d5af7..51f7f2e32d903 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index a9a23030bce58..695c4dedae298 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index f895243486d91..b977cf3c01d7d 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-02-09 +date: 2024-02-10 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 14d319659f955..205a95e9d80eb 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-02-09 +date: 2024-02-10 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 c3e43c4d9eb07..ba179a1fe1c06 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-02-09 +date: 2024-02-10 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 9013c0a06c2af..6e9184f0ce678 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-02-09 +date: 2024-02-10 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 6ce15ed5d3ba1..d2cda667bac15 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-02-09 +date: 2024-02-10 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 e2b0cb397ed18..35e236ba517e1 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-02-09 +date: 2024-02-10 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 49fbd2bb35d4c..0c3d4785ce496 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-02-09 +date: 2024-02-10 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 54bcf7fe38852..86b54a21a7f93 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-02-09 +date: 2024-02-10 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 7b4191fd5c974..687e93dbbcd78 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-02-09 +date: 2024-02-10 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 09757628406a8..0c2e809bd7e0f 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-02-09 +date: 2024-02-10 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 c03b60b5dc8a8..706876b0d3857 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-02-09 +date: 2024-02-10 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 356c59938594f..b9ca77e10d5b2 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-02-09 +date: 2024-02-10 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 67d4191caa010..1790f4a97c4c8 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-02-09 +date: 2024-02-10 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.mdx b/api_docs/kbn_management_settings_ids.mdx index 5cbf2abc0637d..9f2c54cc5dc22 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index c3f80eae37345..3cd3348ddfa1f 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-02-09 +date: 2024-02-10 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 d4a8c96a4a094..8f1c9745f4d20 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-02-09 +date: 2024-02-10 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 3c4410b2d931a..b38258156ed37 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-02-09 +date: 2024-02-10 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 bd5d0d5def8cc..668c94ab6f258 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index a80e8f0636d52..97554495430d0 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-02-09 +date: 2024-02-10 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 91de893be38d5..6198eac496a8e 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-02-09 +date: 2024-02-10 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 0b8e91eb61e57..7c6b7ebb9d338 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-02-09 +date: 2024-02-10 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 74d8ea24672a3..c9b94b0b97af3 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-02-09 +date: 2024-02-10 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 0d186e4183b11..f268440bd46b9 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-02-09 +date: 2024-02-10 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 edc7012c2448e..c1084c844450b 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-02-09 +date: 2024-02-10 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 428d38e28c5ff..159f2dbd176f8 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-02-09 +date: 2024-02-10 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 68eee9bd8281e..5d3b339dffd75 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-02-09 +date: 2024-02-10 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 1c6f0b034bd33..e7f9428b214e8 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-02-09 +date: 2024-02-10 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 4dadf76fabd07..e000cb82bc771 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-02-09 +date: 2024-02-10 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 68d3df41c4e93..9688805069f98 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-02-09 +date: 2024-02-10 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 d28ad43347891..d02f42eced206 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-02-09 +date: 2024-02-10 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_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index aae6decdaf4fd..46a140c0520e9 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-02-09 +date: 2024-02-10 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 50c46a4d04dfc..55ad680335d21 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-02-09 +date: 2024-02-10 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 290364bf33f4b..a8ffbc4bebbb5 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-02-09 +date: 2024-02-10 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 1c29d414162fc..3b6ee11285fa3 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-02-09 +date: 2024-02-10 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 925da237c7270..77fa8ae08cfba 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-02-09 +date: 2024-02-10 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 c359f7cea57ec..59fd41f0dbcdb 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-02-09 +date: 2024-02-10 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 42ad74d1ab9a6..158bd60ffa7eb 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index e31fcd3eac71b..d2a6724c33f2a 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-02-09 +date: 2024-02-10 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 7c41ac7618bcf..2595c9db2e066 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-02-09 +date: 2024-02-10 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 6c2129a7b0056..1f631dfe493d7 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-02-09 +date: 2024-02-10 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 90cdcf3ebdfad..111bf54098d87 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-02-09 +date: 2024-02-10 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 9f23fd4b7a52e..189ec038c08da 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 1ee0417cbafda..e0707814522cb 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-02-09 +date: 2024-02-10 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 e7fae22d79324..968bf0d72211b 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-02-09 +date: 2024-02-10 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 d5b86983d2ce1..59ec3a3ef1969 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 42e1d77db95c9..4215bb823eb35 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-02-09 +date: 2024-02-10 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 46479d9620064..ddaa4905a318d 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-02-09 +date: 2024-02-10 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 cd3ad9877f2d4..2e4f88186d4bd 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 27cc471ac1dd9..0abbf6a51f8de 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-02-09 +date: 2024-02-10 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_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 28ace32bbf314..fe148199e70aa 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-02-09 +date: 2024-02-10 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 4cb49328e1acc..87728b189ea5d 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-02-09 +date: 2024-02-10 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_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 67b1a0995b9b5..d046ad1c93a8e 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-02-09 +date: 2024-02-10 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 f96e4f7376401..33bc02522f8d4 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-02-09 +date: 2024-02-10 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 2fa8e11cfa5f3..09a96e2dfe0e4 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-02-09 +date: 2024-02-10 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 f15e1b04be33b..9bdbe18c0ae2e 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-02-09 +date: 2024-02-10 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 3d98ef63326ec..1f70b3342fc1e 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-02-09 +date: 2024-02-10 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 e7fe358e8f0e1..280819206e26f 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-02-09 +date: 2024-02-10 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 f691c9367f949..90230c7906759 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-02-09 +date: 2024-02-10 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 2edcef082754d..99c290f7234f4 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-02-09 +date: 2024-02-10 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 71acc06032cab..30f48800a0423 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-02-09 +date: 2024-02-10 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 956eb7cf98306..b6b18dee5978b 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-02-09 +date: 2024-02-10 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 1c9ee92a203dc..ebde4221eb0e4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_library.mdx b/api_docs/kbn_presentation_library.mdx index 75a6f0986e1ac..4a8c7460ae054 100644 --- a/api_docs/kbn_presentation_library.mdx +++ b/api_docs/kbn_presentation_library.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-library title: "@kbn/presentation-library" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-library plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-library'] --- import kbnPresentationLibraryObj from './kbn_presentation_library.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 920475b2095d8..5160067389323 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 27cd3c7362bd7..797749b0e41e0 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-02-09 +date: 2024-02-10 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 90d4eb015bd77..d7912433887f4 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-02-09 +date: 2024-02-10 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 3ab1b0e9664eb..14381ae2eb47e 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 3e5624a9ba203..f9c20e824c385 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-02-09 +date: 2024-02-10 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 9dcbe35e729ae..61e79a1fa9168 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-02-09 +date: 2024-02-10 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 e1e320be960c9..91fefdd53e498 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-02-09 +date: 2024-02-10 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 78cf3f5edab55..777e948bd7c6e 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-02-09 +date: 2024-02-10 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 91ec11254eeba..a9002ab027896 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-02-09 +date: 2024-02-10 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 fe5ecd360abc4..b3c050c9138e5 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index c7d9c52aa1bc0..e503bda96dd3b 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-02-09 +date: 2024-02-10 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 0e84c518a81da..5b0eedc55e72f 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-02-09 +date: 2024-02-10 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 c7e9953315746..36c36b2245870 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-02-09 +date: 2024-02-10 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 0a688e60215c3..cf49d9ec19918 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-02-09 +date: 2024-02-10 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 c6546d91721a9..9e4262bf99042 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 6f282553f9064..08d740683e785 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-02-09 +date: 2024-02-10 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 fd520d768996e..fefa6d5828c06 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-02-09 +date: 2024-02-10 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 eeed542b7c4c3..6601e65822069 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-02-09 +date: 2024-02-10 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 58e5c952e70b4..56345c7d7d4bd 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-02-09 +date: 2024-02-10 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 e1245c4fdde09..158f03dc2762d 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-02-09 +date: 2024-02-10 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 567d170dcf8ee..05475e832743e 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-02-09 +date: 2024-02-10 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 8738e6fc2e6d8..5cab7969c027f 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-02-09 +date: 2024-02-10 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 ea6d388d61028..ee4523660b339 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-02-09 +date: 2024-02-10 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 0be10a6c9bdca..ce4caba182d10 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-02-09 +date: 2024-02-10 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 10e14055a71af..baab6589fab12 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 26f9c1ddab44c..4085bc9e8e4bd 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index a923785179c9c..bd3ae3ace1e7b 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-02-09 +date: 2024-02-10 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 8a008f9ec306b..041c9a18773d4 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-02-09 +date: 2024-02-10 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 2f351c8679c4e..62e9f6f6f4d7b 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-02-09 +date: 2024-02-10 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 206564c557df7..43d77d6e0ba65 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 3c29b75b23734..92ff4fae172f7 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-02-09 +date: 2024-02-10 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.devdocs.json b/api_docs/kbn_search_connectors.devdocs.json index 17607f6d88980..818eea8ba852b 100644 --- a/api_docs/kbn_search_connectors.devdocs.json +++ b/api_docs/kbn_search_connectors.devdocs.json @@ -2224,6 +2224,91 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.updateConnectorSecret", + "type": "Function", + "tags": [], + "label": "updateConnectorSecret", + "description": [], + "signature": [ + "(client: ", + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "common", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-common.ElasticsearchClient", + "text": "ElasticsearchClient" + }, + ", value: string, secretId: string) => Promise<", + { + "pluginId": "@kbn/search-connectors", + "scope": "common", + "docId": "kibKbnSearchConnectorsPluginApi", + "section": "def-common.ConnectorsAPIUpdateResponse", + "text": "ConnectorsAPIUpdateResponse" + }, + ">" + ], + "path": "packages/kbn-search-connectors/lib/update_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.updateConnectorSecret.$1", + "type": "Object", + "tags": [], + "label": "client", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "common", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-common.ElasticsearchClient", + "text": "ElasticsearchClient" + } + ], + "path": "packages/kbn-search-connectors/lib/update_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.updateConnectorSecret.$2", + "type": "string", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-search-connectors/lib/update_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.updateConnectorSecret.$3", + "type": "string", + "tags": [], + "label": "secretId", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-search-connectors/lib/update_connector_secret.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/search-connectors", "id": "def-common.updateConnectorServiceType", diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 1d0f6b2a1be27..7d79b235a9c15 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2808 | 0 | 2808 | 0 | +| 2812 | 0 | 2812 | 0 | ## Common diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 72cde44afdf93..3f0595f32ea9e 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-02-09 +date: 2024-02-10 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 67f42a7f70395..ea9763da09aba 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-02-09 +date: 2024-02-10 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 86c4b13c37584..3ae094a63f7d9 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.devdocs.json b/api_docs/kbn_security_hardening.devdocs.json new file mode 100644 index 0000000000000..b7a4222c46515 --- /dev/null +++ b/api_docs/kbn_security_hardening.devdocs.json @@ -0,0 +1,126 @@ +{ + "id": "@kbn/security-hardening", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [ + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole", + "type": "Object", + "tags": [], + "label": "unsafeConsole", + "description": [], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.debug", + "type": "Function", + "tags": [], + "label": "debug", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.error", + "type": "Function", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.info", + "type": "Function", + "tags": [], + "label": "info", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.log", + "type": "Function", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.trace", + "type": "Function", + "tags": [], + "label": "trace", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-hardening", + "id": "def-common.unsafeConsole.warn", + "type": "Function", + "tags": [], + "label": "warn", + "description": [], + "signature": [ + "{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }" + ], + "path": "packages/kbn-security-hardening/console.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ] + } +} \ No newline at end of file diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx new file mode 100644 index 0000000000000..d88829625de28 --- /dev/null +++ b/api_docs/kbn_security_hardening.mdx @@ -0,0 +1,30 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnSecurityHardeningPluginApi +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-02-10 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] +--- +import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; + + + +Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 7 | 0 | 7 | 0 | + +## Common + +### Objects +<DocDefinitionList data={kbnSecurityHardeningObj.common.objects}/> + diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 9cad86b1a78fe..3733e78b32a0e 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-02-09 +date: 2024-02-10 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 cb3bf6aab0b13..f79cef4b22730 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-02-09 +date: 2024-02-10 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 a038ad956ea4d..ee1355b181534 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-02-09 +date: 2024-02-10 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_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 5cc0918e330da..9209444c8a9e0 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-02-09 +date: 2024-02-10 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 7c699ebbc46b5..7013b3c3fcd38 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-02-09 +date: 2024-02-10 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 acd84283b362a..74078a35b9d17 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-02-09 +date: 2024-02-10 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 24638c19bbf63..19a947d642051 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 7310f90f44660..8c3c9ee7232aa 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-02-09 +date: 2024-02-10 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 a2fc7a19cc55b..872dbee27ac58 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-02-09 +date: 2024-02-10 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 7e3626771820c..5465d86157cfa 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-02-09 +date: 2024-02-10 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 510d4eb34422b..0b3ed6e9a67fe 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-02-09 +date: 2024-02-10 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 10d25c2402388..a518caf295db7 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 17b907e4d4a46..9d1794cad210c 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index ad66efdb05ee0..c25aa57cb5618 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-02-09 +date: 2024-02-10 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 d4e516c74b824..5294c9188bc24 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-02-09 +date: 2024-02-10 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 2e62f802f819a..af817aa9da5b8 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-02-09 +date: 2024-02-10 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 f25508fcab162..fb1e7f50a2dda 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-02-09 +date: 2024-02-10 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 0490e602cb1ce..6bbf503b4d610 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-02-09 +date: 2024-02-10 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 12e859629150a..b963816eee64e 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-02-09 +date: 2024-02-10 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 dd5112c1cf932..b02395114d732 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-02-09 +date: 2024-02-10 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 5bf87a9774813..f32368d1d08eb 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-02-09 +date: 2024-02-10 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 337925fef6f6f..eebf6ef3ce518 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-02-09 +date: 2024-02-10 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 8b9dad87e8003..c32bdac640db3 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-02-09 +date: 2024-02-10 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 2dc140f925cc4..86188a30d22ec 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-02-09 +date: 2024-02-10 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 b97f1e8f7bf13..97957363f75d9 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-02-09 +date: 2024-02-10 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 b9dbd270ce52e..a6a1558db978e 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-02-09 +date: 2024-02-10 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 7feaf19a95e8b..285f274931ff2 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index f018a2e3b9656..0f2bcb534eb5e 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-02-09 +date: 2024-02-10 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 3f3d901c7cf75..db28108c40f51 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-02-09 +date: 2024-02-10 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 64795324e792e..998be680fb299 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-02-09 +date: 2024-02-10 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 88d1a01b04be3..9da769f36cb4e 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-02-09 +date: 2024-02-10 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 064175db7f4fe..2e704e72a3674 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-02-09 +date: 2024-02-10 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 34a0a94e1ed2b..8c03522fa48e4 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-02-09 +date: 2024-02-10 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 22043f8e8c03f..08cb723d908e8 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-02-09 +date: 2024-02-10 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 5ba189e377bb2..942aa9a9d8cf8 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-02-09 +date: 2024-02-10 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 f1184f3cfb24d..481e54346dd17 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-02-09 +date: 2024-02-10 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 b6dde00e8894c..a43fe3947dce0 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-02-09 +date: 2024-02-10 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 830337cda693a..7108b7963db99 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-02-09 +date: 2024-02-10 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 ce80864d20ac7..783942c433702 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-02-09 +date: 2024-02-10 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 d8e299e235cd6..72eaebb5b2a03 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-02-09 +date: 2024-02-10 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 c7ffb75058f20..af8b68046204d 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-02-09 +date: 2024-02-10 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 54c1b10171ec6..780fe057c3cc2 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-02-09 +date: 2024-02-10 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 cd66c18326c9e..a56aac2b72456 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-02-09 +date: 2024-02-10 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 28bc960da99a3..b2337293a5549 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-02-09 +date: 2024-02-10 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 21169e23a6ecf..eefc69a2eab39 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-02-09 +date: 2024-02-10 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 9b8384b75561e..024c046908c33 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-02-09 +date: 2024-02-10 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 ecb1385323bba..9db12104e66cf 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-02-09 +date: 2024-02-10 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 c09747ae9c41f..34cf453918145 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-02-09 +date: 2024-02-10 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 22108696eb39e..2b539369d561a 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-02-09 +date: 2024-02-10 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 8c4d3b7415419..8e92d3fce205a 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-02-09 +date: 2024-02-10 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 aca11de2a9402..07b8df381c03c 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-02-09 +date: 2024-02-10 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 f6cf68cddae21..7fcc99f13fef2 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-02-09 +date: 2024-02-10 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 997540a9e15e2..f3ac3591ff4a9 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-02-09 +date: 2024-02-10 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 e632593c9f1a5..7391f0cf0d5d9 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-02-09 +date: 2024-02-10 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 7910921c7735c..1713e0e61b08e 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-02-09 +date: 2024-02-10 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 a29cc08b66b72..70a818437cc7d 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-02-09 +date: 2024-02-10 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 5a88e00a52dc8..ba0de8e44c895 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-02-09 +date: 2024-02-10 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 de58330840431..9efaa97399fc5 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-02-09 +date: 2024-02-10 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 a3ec366c136e4..078091817add3 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-02-09 +date: 2024-02-10 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 e0c1c06a45e7a..a7ec5a3edcbd2 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-02-09 +date: 2024-02-10 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 c530b568e9778..c211ae32e1183 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-02-09 +date: 2024-02-10 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 716f08306abb8..b2b36c0424070 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-02-09 +date: 2024-02-10 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 a799d6796e1a4..381c7abe62f1a 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-02-09 +date: 2024-02-10 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 57460b637ce96..990af928cc8d4 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-02-09 +date: 2024-02-10 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 86df3a12667ea..7adb2fc25c589 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-02-09 +date: 2024-02-10 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 89da3d1e37a7c..b942c8385b5f3 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-02-09 +date: 2024-02-10 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 5dd3b3f126c79..0d6f75c6469e6 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-02-09 +date: 2024-02-10 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 1b90310eb4165..f31c58311be68 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-02-09 +date: 2024-02-10 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 522b22ee840bf..0d2a50f59170c 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-02-09 +date: 2024-02-10 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 30a9f9a6fd175..b906e60922db4 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-02-09 +date: 2024-02-10 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 c7c14d7bdf28c..9dce5849c23e4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 48d8a1fac87c3..3a6b988861051 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-02-09 +date: 2024-02-10 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 5d5bcfcfe8bd1..ffc90e9830a0b 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-02-09 +date: 2024-02-10 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 bd8d1177c366a..906f0fd5b6a47 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-02-09 +date: 2024-02-10 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 6273163237752..941a784e1512b 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 885961a8ce008..bdb53b2c1b290 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-02-09 +date: 2024-02-10 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 9d34f76f45c24..3c2ae61b11562 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-02-09 +date: 2024-02-10 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 333e0c02d1f2b..9b56d45a9f44c 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index d51561586eae3..00c9119b0b4c5 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-02-09 +date: 2024-02-10 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 5decb133671ed..f0ef93fc76ebc 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-02-09 +date: 2024-02-10 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 9a36f2b93d427..5af7b356ab439 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-02-09 +date: 2024-02-10 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.mdx b/api_docs/kbn_test_jest_helpers.mdx index a1819a2c16a1a..9c2903d91f91c 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index fd2dc01162d1d..d38c501ad593b 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index c5dba70544f5c..923893333dde2 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 80818df04b78f..1b53de5031815 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 3f55a6e3760da..14e0b3890f382 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index b44cebad7cefb..c5574a2ad15ad 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index bd28ce25b703f..db661be012636 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index aefed1ce38c87..a33dc1ce1c211 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 476641692bc2a..7103f3295b384 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index d0bd82faf9f07..e08779f896105 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.devdocs.json b/api_docs/kbn_unified_data_table.devdocs.json index d6e88999bd256..8c9ffa9f3c1e4 100644 --- a/api_docs/kbn_unified_data_table.devdocs.json +++ b/api_docs/kbn_unified_data_table.devdocs.json @@ -19,6 +19,51 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.DataTableRowControl", + "type": "Function", + "tags": [], + "label": "DataTableRowControl", + "description": [], + "signature": [ + "({ children }: { children: React.ReactNode; }) => JSX.Element" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table_row_control.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.DataTableRowControl.$1", + "type": "Object", + "tags": [], + "label": "{ children }", + "description": [], + "path": "packages/kbn-unified-data-table/src/components/data_table_row_control.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.DataTableRowControl.$1.children", + "type": "CompoundType", + "tags": [], + "label": "children", + "description": [], + "signature": [ + "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table_row_control.tsx", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.getDisplayedColumns", @@ -326,7 +371,7 @@ "label": "UnifiedDataTable", "description": [], "signature": [ - "({ ariaLabelledBy, columns, columnTypes, showColumnTokens, headerRowHeight, controlColumnIds, dataView, loadingState, onFilter, onResize, onSetColumns, onSort, rows, searchDescription, searchTitle, settings, showTimeCol, showFullScreenButton, sort, useNewFieldsApi, isSortEnabled, isPaginationEnabled, cellActionsTriggerId, className, rowHeightState, onUpdateRowHeight, maxAllowedSampleSize, sampleSizeState, onUpdateSampleSize, isPlainRecord, rowsPerPageState, onUpdateRowsPerPage, onFieldEdited, services, renderCustomGridBody, renderCustomToolbar, trailingControlColumns, totalHits, onFetchMoreRecords, renderDocumentView, setExpandedDoc, expandedDoc, configRowHeight, showMultiFields, maxDocFieldsDisplayed, externalControlColumns, externalAdditionalControls, rowsPerPageOptions, visibleCellActions, externalCustomRenderers, consumer, componentsTourSteps, gridStyleOverride, rowLineHeightOverride, customGridColumnsConfiguration, }: ", + "({ ariaLabelledBy, columns, columnTypes, showColumnTokens, headerRowHeight, controlColumnIds, dataView, loadingState, onFilter, onResize, onSetColumns, onSort, rows, searchDescription, searchTitle, settings, showTimeCol, showFullScreenButton, sort, useNewFieldsApi, isSortEnabled, isPaginationEnabled, cellActionsTriggerId, className, rowHeightState, onUpdateRowHeight, maxAllowedSampleSize, sampleSizeState, onUpdateSampleSize, isPlainRecord, rowsPerPageState, onUpdateRowsPerPage, onFieldEdited, services, renderCustomGridBody, renderCustomToolbar, trailingControlColumns, totalHits, onFetchMoreRecords, renderDocumentView, setExpandedDoc, expandedDoc, configRowHeight, showMultiFields, maxDocFieldsDisplayed, externalControlColumns, externalAdditionalControls, rowsPerPageOptions, visibleCellActions, externalCustomRenderers, consumer, componentsTourSteps, gridStyleOverride, rowLineHeightOverride, customGridColumnsConfiguration, customControlColumnsConfiguration, }: ", { "pluginId": "@kbn/unified-data-table", "scope": "common", @@ -345,7 +390,7 @@ "id": "def-common.UnifiedDataTable.$1", "type": "Object", "tags": [], - "label": "{\n ariaLabelledBy,\n columns,\n columnTypes,\n showColumnTokens,\n headerRowHeight,\n controlColumnIds = CONTROL_COLUMN_IDS_DEFAULT,\n dataView,\n loadingState,\n onFilter,\n onResize,\n onSetColumns,\n onSort,\n rows,\n searchDescription,\n searchTitle,\n settings,\n showTimeCol,\n showFullScreenButton = true,\n sort,\n useNewFieldsApi,\n isSortEnabled = true,\n isPaginationEnabled = true,\n cellActionsTriggerId,\n className,\n rowHeightState,\n onUpdateRowHeight,\n maxAllowedSampleSize,\n sampleSizeState,\n onUpdateSampleSize,\n isPlainRecord = false,\n rowsPerPageState,\n onUpdateRowsPerPage,\n onFieldEdited,\n services,\n renderCustomGridBody,\n renderCustomToolbar,\n trailingControlColumns,\n totalHits,\n onFetchMoreRecords,\n renderDocumentView,\n setExpandedDoc,\n expandedDoc,\n configRowHeight,\n showMultiFields = true,\n maxDocFieldsDisplayed = 50,\n externalControlColumns,\n externalAdditionalControls,\n rowsPerPageOptions,\n visibleCellActions,\n externalCustomRenderers,\n consumer = 'discover',\n componentsTourSteps,\n gridStyleOverride,\n rowLineHeightOverride,\n customGridColumnsConfiguration,\n}", + "label": "{\n ariaLabelledBy,\n columns,\n columnTypes,\n showColumnTokens,\n headerRowHeight,\n controlColumnIds = CONTROL_COLUMN_IDS_DEFAULT,\n dataView,\n loadingState,\n onFilter,\n onResize,\n onSetColumns,\n onSort,\n rows,\n searchDescription,\n searchTitle,\n settings,\n showTimeCol,\n showFullScreenButton = true,\n sort,\n useNewFieldsApi,\n isSortEnabled = true,\n isPaginationEnabled = true,\n cellActionsTriggerId,\n className,\n rowHeightState,\n onUpdateRowHeight,\n maxAllowedSampleSize,\n sampleSizeState,\n onUpdateSampleSize,\n isPlainRecord = false,\n rowsPerPageState,\n onUpdateRowsPerPage,\n onFieldEdited,\n services,\n renderCustomGridBody,\n renderCustomToolbar,\n trailingControlColumns,\n totalHits,\n onFetchMoreRecords,\n renderDocumentView,\n setExpandedDoc,\n expandedDoc,\n configRowHeight,\n showMultiFields = true,\n maxDocFieldsDisplayed = 50,\n externalControlColumns,\n externalAdditionalControls,\n rowsPerPageOptions,\n visibleCellActions,\n externalCustomRenderers,\n consumer = 'discover',\n componentsTourSteps,\n gridStyleOverride,\n rowLineHeightOverride,\n customGridColumnsConfiguration,\n customControlColumnsConfiguration,\n}", "description": [], "signature": [ { @@ -400,6 +445,82 @@ } ], "interfaces": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.ControlColumns", + "type": "Interface", + "tags": [], + "label": "ControlColumns", + "description": [], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.ControlColumns.select", + "type": "Object", + "tags": [], + "label": "select", + "description": [], + "signature": [ + "EuiDataGridControlColumn" + ], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.ControlColumns.openDetails", + "type": "Object", + "tags": [], + "label": "openDetails", + "description": [], + "signature": [ + "EuiDataGridControlColumn" + ], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.ControlColumnsProps", + "type": "Interface", + "tags": [], + "label": "ControlColumnsProps", + "description": [], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.ControlColumnsProps.controlColumns", + "type": "Object", + "tags": [], + "label": "controlColumns", + "description": [], + "signature": [ + { + "pluginId": "@kbn/unified-data-table", + "scope": "common", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-common.ControlColumns", + "text": "ControlColumns" + } + ], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.CustomGridColumnProps", @@ -1687,6 +1808,29 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.UnifiedDataTableProps.customControlColumnsConfiguration", + "type": "Function", + "tags": [], + "label": "customControlColumnsConfiguration", + "description": [ + "\nAn optional settings to control which columns to render as trailing and leading control columns" + ], + "signature": [ + { + "pluginId": "@kbn/unified-data-table", + "scope": "common", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-common.CustomControlColumnConfiguration", + "text": "CustomControlColumnConfiguration" + }, + " | undefined" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.UnifiedDataTableProps.consumer", @@ -1904,6 +2048,56 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.CustomControlColumnConfiguration", + "type": "Type", + "tags": [], + "label": "CustomControlColumnConfiguration", + "description": [], + "signature": [ + "(props: ", + { + "pluginId": "@kbn/unified-data-table", + "scope": "common", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-common.ControlColumnsProps", + "text": "ControlColumnsProps" + }, + ") => { leadingControlColumns: ", + "EuiDataGridControlColumn", + "[]; trailingControlColumns?: ", + "EuiDataGridControlColumn", + "[] | undefined; }" + ], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.CustomControlColumnConfiguration.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + { + "pluginId": "@kbn/unified-data-table", + "scope": "common", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-common.ControlColumnsProps", + "text": "ControlColumnsProps" + } + ], + "path": "packages/kbn-unified-data-table/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.CustomGridColumnsConfiguration", @@ -1980,6 +2174,36 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.OPEN_DETAILS", + "type": "string", + "tags": [], + "label": "OPEN_DETAILS", + "description": [], + "signature": [ + "\"openDetails\"" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table_columns.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.SELECT_ROW", + "type": "string", + "tags": [], + "label": "SELECT_ROW", + "description": [], + "signature": [ + "\"select\"" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table_columns.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.UnifiedDataTableRenderCustomToolbar", diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 8efc0907d12f8..90e17a97cf6dc 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 117 | 0 | 55 | 1 | +| 130 | 0 | 67 | 1 | ## Common diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 0997d3e5b491d..186b6fe35aa5d 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 3f0bb7b6eb169..f316be3a7e67a 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index dc399e490d595..fd4d51478839d 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 4f0f914cbc28f..5098c4717034c 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 3bf0853bf5cfd..a9da12a7d7ade 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 8c91b96db58c8..61378fd987822 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 5f54692963633..c88bab58de0aa 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 4ee5c359123d9..f531e9e46bc5c 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index d6f66d5dfcce2..2cec32430fd7c 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 5421e51a45e70..fb80422cdef1d 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 9f881b8d3b8f9..2d7506371babc 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 3ed9f16993c07..39c91bea84533 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index c939ddaf42b91..cca8d7a7b53f2 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 00f079c1cec35..60d04ffbdeffb 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index c3e14a5ad511d..ef399818d32b7 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 6040c26ab1283..823e51b002e3b 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 3efe37426e656..e5f03b11acb4a 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 27f646f8e2888..61da592cbf51f 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 5e034defbda14..5dce57f42059f 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 1f1d43b4efd6e..2f6b82142d973 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 310f7471591ff..8e387241f6294 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 8daa7853d911a..cd406d297c6d5 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index b39f38ec83a2c..21eecce4ef28b 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_explorer.devdocs.json b/api_docs/logs_explorer.devdocs.json index 24910c48f35bc..34497e0d2ceb0 100644 --- a/api_docs/logs_explorer.devdocs.json +++ b/api_docs/logs_explorer.devdocs.json @@ -50,6 +50,53 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "logsExplorer", + "id": "def-public.getDiscoverColumnsWithFallbackFieldsFromDisplayOptions", + "type": "Function", + "tags": [], + "label": "getDiscoverColumnsWithFallbackFieldsFromDisplayOptions", + "description": [], + "signature": [ + "(displayOptions: ", + { + "pluginId": "logsExplorer", + "scope": "common", + "docId": "kibLogsExplorerPluginApi", + "section": "def-common.DisplayOptions", + "text": "DisplayOptions" + }, + ") => string[] | undefined" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "logsExplorer", + "id": "def-public.getDiscoverColumnsWithFallbackFieldsFromDisplayOptions.$1", + "type": "Object", + "tags": [], + "label": "displayOptions", + "description": [], + "signature": [ + { + "pluginId": "logsExplorer", + "scope": "common", + "docId": "kibLogsExplorerPluginApi", + "section": "def-common.DisplayOptions", + "text": "DisplayOptions" + } + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "logsExplorer", "id": "def-public.getDiscoverFiltersFromState", @@ -58,7 +105,7 @@ "label": "getDiscoverFiltersFromState", "description": [], "signature": [ - "(filters?: ", + "(index: string, filters?: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -85,6 +132,21 @@ { "parentPluginId": "logsExplorer", "id": "def-public.getDiscoverFiltersFromState.$1", + "type": "string", + "tags": [], + "label": "index", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/public/utils/convert_discover_app_state.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "logsExplorer", + "id": "def-public.getDiscoverFiltersFromState.$2", "type": "Array", "tags": [], "label": "filters", @@ -106,7 +168,7 @@ }, { "parentPluginId": "logsExplorer", - "id": "def-public.getDiscoverFiltersFromState.$2", + "id": "def-public.getDiscoverFiltersFromState.$3", "type": "Object", "tags": [], "label": "controls", @@ -329,6 +391,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", ") | (", "WithDatasetSelection", @@ -353,6 +417,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", "), any, ", "LogsExplorerControllerEvent", @@ -447,6 +513,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", ") | (", "WithDatasetSelection", @@ -471,6 +539,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", "), any, ", "LogsExplorerControllerEvent", @@ -725,6 +795,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", ") | (", "WithDatasetSelection", @@ -749,6 +821,8 @@ "text": "DisplayOptions" }, " & ", + "WithDataTableRecord", + " & ", "WithDiscoverStateContainer", ")" ], @@ -1426,45 +1500,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "logsExplorer", - "id": "def-common.GridColumnDisplayOptions", - "type": "Interface", - "tags": [], - "label": "GridColumnDisplayOptions", - "description": [], - "path": "x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "logsExplorer", - "id": "def-common.GridColumnDisplayOptions.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "path": "x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "logsExplorer", - "id": "def-common.GridColumnDisplayOptions.width", - "type": "number", - "tags": [], - "label": "width", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "logsExplorer", "id": "def-common.GridDisplayOptions", @@ -1655,6 +1690,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.CONTENT_FIELD", + "type": "string", + "tags": [], + "label": "CONTENT_FIELD", + "description": [], + "signature": [ + "\"content\"" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "logsExplorer", "id": "def-common.ControlPanels", @@ -1693,6 +1743,23 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.GridColumnDisplayOptions", + "type": "Type", + "tags": [], + "label": "GridColumnDisplayOptions", + "description": [], + "signature": [ + "DocumentFieldGridColumnOptions", + " | ", + "SmartFieldGridColumnOptions" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/display_options/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "logsExplorer", "id": "def-common.PartialChartDisplayOptions", @@ -1771,6 +1838,62 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.CONTENT_FIELD_CONFIGURATION", + "type": "Object", + "tags": [], + "label": "CONTENT_FIELD_CONFIGURATION", + "description": [], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "logsExplorer", + "id": "def-common.CONTENT_FIELD_CONFIGURATION.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"smart-field\"" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.CONTENT_FIELD_CONFIGURATION.smartField", + "type": "string", + "tags": [], + "label": "smartField", + "description": [], + "signature": [ + "\"content\"" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.CONTENT_FIELD_CONFIGURATION.fallbackFields", + "type": "Array", + "tags": [], + "label": "fallbackFields", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "logsExplorer", "id": "def-common.controlPanelConfigs", @@ -2043,6 +2166,115 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.RESOURCE_FIELD_CONFIGURATION", + "type": "Object", + "tags": [], + "label": "RESOURCE_FIELD_CONFIGURATION", + "description": [], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "logsExplorer", + "id": "def-common.RESOURCE_FIELD_CONFIGURATION.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"smart-field\"" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.RESOURCE_FIELD_CONFIGURATION.smartField", + "type": "string", + "tags": [], + "label": "smartField", + "description": [], + "signature": [ + "\"resource\"" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.RESOURCE_FIELD_CONFIGURATION.fallbackFields", + "type": "Array", + "tags": [], + "label": "fallbackFields", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.RESOURCE_FIELD_CONFIGURATION.width", + "type": "number", + "tags": [], + "label": "width", + "description": [], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.SMART_FALLBACK_FIELDS", + "type": "Object", + "tags": [], + "label": "SMART_FALLBACK_FIELDS", + "description": [], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "logsExplorer", + "id": "def-common.SMART_FALLBACK_FIELDS.CONTENT_FIELD", + "type": "Object", + "tags": [], + "label": "[CONTENT_FIELD]", + "description": [], + "signature": [ + "SmartFieldGridColumnOptions" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsExplorer", + "id": "def-common.SMART_FALLBACK_FIELDS.RESOURCE_FIELD", + "type": "Object", + "tags": [], + "label": "[RESOURCE_FIELD]", + "description": [], + "signature": [ + "SmartFieldGridColumnOptions" + ], + "path": "x-pack/plugins/observability_solution/logs_explorer/common/constants.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ] } diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 45c74f3e2bd88..99b565816fe0f 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 87 | 0 | 87 | 16 | +| 101 | 0 | 101 | 19 | ## Client diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index ff2eef1c37860..25dee113085f5 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 2b1cb49d1c497..8bc1438749f6f 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 6fb945cba13d8..bfb31cac136d4 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index fe919f1927551..de46206f3b573 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 2958317d49194..dd046de2dcf8b 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index b020690729abe..6a539d7385f45 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 18ae7b2b8e8c4..6ee5b90743732 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index b8c5491cd823d..409307938f4d9 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 2b300a9f6547c..dd4967ee01306 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 0cb07067798e5..878e6606a410f 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index d0a0472c8d09a..a8ad3b992dfa9 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 14a098785df63..2fed2f2b9e810 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index a4e214e009129..542bc9020df70 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index a7aba7f3a7bf1..8ab3d759c1ce2 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.devdocs.json b/api_docs/observability_a_i_assistant.devdocs.json index 108c6df21a6db..e2b198012b1d1 100644 --- a/api_docs/observability_a_i_assistant.devdocs.json +++ b/api_docs/observability_a_i_assistant.devdocs.json @@ -798,8 +798,6 @@ }, "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", "Readable", - " | ", - "ChatCompletion", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", @@ -1296,8 +1294,6 @@ }, "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", "Readable", - " | ", - "ChatCompletion", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", @@ -2034,8 +2030,6 @@ }, "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", "Readable", - " | ", - "ChatCompletion", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", @@ -2541,8 +2535,6 @@ }, "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", "Readable", - " | ", - "ChatCompletion", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", @@ -3192,8 +3184,6 @@ }, "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", "Readable", - " | ", - "ChatCompletion", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index d5df9f9282a6c..75d3ed6478b61 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index 188f3bd0ebddd..a96733901b891 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-02-09 +date: 2024-02-10 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 f0ad4ee30d757..9fa9cbf2be36b 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-02-09 +date: 2024-02-10 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 b9555c1d41507..f7c0d5fa37814 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-02-09 +date: 2024-02-10 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 1eb3c60c9157a..d5aaea1b4e4f0 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-02-09 +date: 2024-02-10 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 d2eb14b7bec84..659cceb3a8920 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-02-09 +date: 2024-02-10 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 b5ecf96fd46c6..88deeddca3154 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a <br /> public API | Number of teams | |--------------|----------|------------------------| -| 751 | 643 | 40 | +| 752 | 644 | 40 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 79796 | 228 | 68343 | 1736 | +| 79848 | 228 | 68394 | 1740 | ## Plugin Directory @@ -32,7 +32,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibAiAssistantManagementObservabilityPluginApi" text="aiAssistantManagementObservability"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 2 | 0 | 2 | 0 | | <DocLink id="kibAiAssistantManagementSelectionPluginApi" text="aiAssistantManagementSelection"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 2 | 0 | 2 | 0 | | <DocLink id="kibAiopsPluginApi" text="aiops"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 69 | 0 | 4 | 1 | -| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 835 | 1 | 804 | 51 | +| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 836 | 1 | 805 | 51 | | <DocLink id="kibApmPluginApi" text="apm"/> | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | The user interface for Elastic APM | 29 | 0 | 29 | 125 | | <DocLink id="kibApmDataAccessPluginApi" text="apmDataAccess"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 9 | 0 | 9 | 0 | | <DocLink id="kibAssetManagerPluginApi" text="assetManager"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Asset manager plugin for entity assets (inventory, topology, etc) | 9 | 0 | 9 | 2 | @@ -65,7 +65,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibDataVisualizerPluginApi" text="dataVisualizer"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | | <DocLink id="kibDatasetQualityPluginApi" text="datasetQuality"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 10 | 0 | 10 | 5 | | <DocLink id="kibDevToolsPluginApi" text="devTools"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 16 | 0 | 10 | 3 | -| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 151 | 0 | 104 | 22 | +| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 156 | 0 | 109 | 23 | | <DocLink id="kibDiscoverEnhancedPluginApi" text="discoverEnhanced"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | <DocLink id="kibEcsDataQualityDashboardPluginApi" text="ecsDataQualityDashboard"/> | [@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 | | <DocLink id="kibElasticAssistantPluginApi" text="elasticAssistant"/> | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | Server APIs for the Elastic AI Assistant | 41 | 0 | 27 | 0 | @@ -108,7 +108,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibHomePluginApi" text="home"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 151 | 0 | 111 | 1 | | <DocLink id="kibImageEmbeddablePluginApi" text="imageEmbeddable"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 3 | 0 | 3 | 1 | | <DocLink id="kibIndexLifecycleManagementPluginApi" text="indexLifecycleManagement"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | -| <DocLink id="kibIndexManagementPluginApi" text="indexManagement"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 224 | 0 | 219 | 4 | +| <DocLink id="kibIndexManagementPluginApi" text="indexManagement"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 226 | 0 | 221 | 4 | | <DocLink id="kibInfraPluginApi" text="infra"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 32 | 0 | 29 | 8 | | <DocLink id="kibIngestPipelinesPluginApi" text="ingestPipelines"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | | inputControlVis | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 | @@ -125,7 +125,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibLicensingPluginApi" text="licensing"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | | <DocLink id="kibLinksPluginApi" text="links"/> | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | A dashboard panel for creating links to dashboards or external links. | 57 | 0 | 57 | 6 | | <DocLink id="kibListsPluginApi" text="lists"/> | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 226 | 0 | 97 | 52 | -| <DocLink id="kibLogsExplorerPluginApi" text="logsExplorer"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin provides a LogsExplorer component using the Discover customization framework, offering several affordances specifically designed for log consumption. | 87 | 0 | 87 | 16 | +| <DocLink id="kibLogsExplorerPluginApi" text="logsExplorer"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin provides a LogsExplorer component using the Discover customization framework, offering several affordances specifically designed for log consumption. | 101 | 0 | 101 | 19 | | <DocLink id="kibLogsSharedPluginApi" text="logsShared"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes the shared components and APIs to access and visualize logs. | 302 | 0 | 276 | 32 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | <DocLink id="kibManagementPluginApi" text="management"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | @@ -158,7 +158,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibRuntimeFieldsPluginApi" text="runtimeFields"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 24 | 0 | 19 | 2 | | <DocLink id="kibSavedObjectsPluginApi" text="savedObjects"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 129 | 2 | 118 | 4 | | <DocLink id="kibSavedObjectsFinderPluginApi" text="savedObjectsFinder"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 25 | 0 | 25 | 0 | -| <DocLink id="kibSavedObjectsManagementPluginApi" text="savedObjectsManagement"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 161 | 0 | 147 | 2 | +| <DocLink id="kibSavedObjectsManagementPluginApi" text="savedObjectsManagement"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 164 | 0 | 150 | 2 | | <DocLink id="kibSavedObjectsTaggingPluginApi" text="savedObjectsTagging"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 87 | 0 | 81 | 3 | | <DocLink id="kibSavedObjectsTaggingOssPluginApi" text="savedObjectsTaggingOss"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 104 | 0 | 56 | 1 | | <DocLink id="kibSavedSearchPluginApi" text="savedSearch"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 78 | 0 | 77 | 3 | @@ -439,7 +439,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibKbnDeeplinksDevtoolsPluginApi" text="@kbn/deeplinks-devtools"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 5 | 0 | 5 | 0 | | <DocLink id="kibKbnDeeplinksManagementPluginApi" text="@kbn/deeplinks-management"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | | <DocLink id="kibKbnDeeplinksMlPluginApi" text="@kbn/deeplinks-ml"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 3 | 0 | 3 | 0 | -| <DocLink id="kibKbnDeeplinksObservabilityPluginApi" text="@kbn/deeplinks-observability"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 31 | 0 | 21 | 0 | +| <DocLink id="kibKbnDeeplinksObservabilityPluginApi" text="@kbn/deeplinks-observability"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 34 | 0 | 24 | 0 | | <DocLink id="kibKbnDeeplinksSearchPluginApi" text="@kbn/deeplinks-search"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 4 | 0 | 4 | 0 | | <DocLink id="kibKbnDefaultNavAnalyticsPluginApi" text="@kbn/default-nav-analytics"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 8 | 0 | 8 | 0 | | <DocLink id="kibKbnDefaultNavDevtoolsPluginApi" text="@kbn/default-nav-devtools"/> | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 8 | 0 | 8 | 0 | @@ -588,10 +588,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibKbnRuleDataUtilsPluginApi" text="@kbn/rule-data-utils"/> | [@elastic/security-detections-response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 120 | 0 | 117 | 0 | | <DocLink id="kibKbnSavedObjectsSettingsPluginApi" text="@kbn/saved-objects-settings"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | <DocLink id="kibKbnSearchApiPanelsPluginApi" text="@kbn/search-api-panels"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 76 | 0 | 76 | 0 | -| <DocLink id="kibKbnSearchConnectorsPluginApi" text="@kbn/search-connectors"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2808 | 0 | 2808 | 0 | +| <DocLink id="kibKbnSearchConnectorsPluginApi" text="@kbn/search-connectors"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2812 | 0 | 2812 | 0 | | <DocLink id="kibKbnSearchErrorsPluginApi" text="@kbn/search-errors"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 1 | 17 | 1 | | <DocLink id="kibKbnSearchIndexDocumentsPluginApi" text="@kbn/search-index-documents"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 25 | 0 | 25 | 0 | | <DocLink id="kibKbnSearchResponseWarningsPluginApi" text="@kbn/search-response-warnings"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 20 | 0 | 18 | 1 | +| <DocLink id="kibKbnSecurityHardeningPluginApi" text="@kbn/security-hardening"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 7 | 0 | 7 | 0 | | <DocLink id="kibKbnSecurityPluginTypesCommonPluginApi" text="@kbn/security-plugin-types-common"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 82 | 0 | 35 | 0 | | <DocLink id="kibKbnSecurityPluginTypesPublicPluginApi" text="@kbn/security-plugin-types-public"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 44 | 0 | 14 | 0 | | <DocLink id="kibKbnSecurityPluginTypesServerPluginApi" text="@kbn/security-plugin-types-server"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 213 | 0 | 114 | 0 | @@ -683,7 +684,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibKbnUiActionsBrowserPluginApi" text="@kbn/ui-actions-browser"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 42 | 0 | 28 | 0 | | <DocLink id="kibKbnUiSharedDepsSrcPluginApi" text="@kbn/ui-shared-deps-src"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 55 | 0 | 46 | 0 | | <DocLink id="kibKbnUiThemePluginApi" text="@kbn/ui-theme"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 7 | 0 | 6 | 0 | -| <DocLink id="kibKbnUnifiedDataTablePluginApi" text="@kbn/unified-data-table"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the unified data table which can be integrated into apps | 117 | 0 | 55 | 1 | +| <DocLink id="kibKbnUnifiedDataTablePluginApi" text="@kbn/unified-data-table"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the unified data table which can be integrated into apps | 130 | 0 | 67 | 1 | | <DocLink id="kibKbnUnifiedDocViewerPluginApi" text="@kbn/unified-doc-viewer"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 14 | 0 | 13 | 6 | | <DocLink id="kibKbnUnifiedFieldListPluginApi" text="@kbn/unified-field-list"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list and field stats which can be integrated into apps | 291 | 0 | 267 | 10 | | <DocLink id="kibKbnUnsavedChangesBadgePluginApi" text="@kbn/unsaved-changes-badge"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 13 | 0 | 9 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index 1cbe9f66219e5..3de25ffb3c752 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-02-09 +date: 2024-02-10 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 c33fe9dba795b..34e8f063a8b57 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-02-09 +date: 2024-02-10 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 fa0e0d377aac8..44b7623c4c95d 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-02-09 +date: 2024-02-10 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 1778a3d0f2eff..42612160893a9 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-02-09 +date: 2024-02-10 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 79331f765151e..840c85d4f0e2a 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-02-09 +date: 2024-02-10 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 e53111e6cb383..1a1eaa8131d57 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-02-09 +date: 2024-02-10 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 ff43fbc1fd8c3..2d9df35882149 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-02-09 +date: 2024-02-10 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 6d7808fa27342..c23adbb20d60a 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-02-09 +date: 2024-02-10 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 98483807c2012..b8b300d9eb4a3 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-02-09 +date: 2024-02-10 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 709d8717bcc7e..6cc2eb929ca40 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-02-09 +date: 2024-02-10 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 61632c9c3d1f1..ecd23ecf1afc9 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index b76bc8ee29428..48f11e8af68f7 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -1543,6 +1543,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.SavedObjectWithMetadata.managed", + "type": "CompoundType", + "tags": [], + "label": "managed", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/saved_objects_management/common/types/v1.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "savedObjectsManagement", "id": "def-public.SavedObjectWithMetadata.attributes", @@ -2224,6 +2238,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-server.SavedObjectWithMetadata.managed", + "type": "CompoundType", + "tags": [], + "label": "managed", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/saved_objects_management/common/types/v1.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "savedObjectsManagement", "id": "def-server.SavedObjectWithMetadata.attributes", @@ -2726,6 +2754,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-common.SavedObjectWithMetadata.managed", + "type": "CompoundType", + "tags": [], + "label": "managed", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/saved_objects_management/common/types/v1.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "savedObjectsManagement", "id": "def-common.SavedObjectWithMetadata.attributes", diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index a93e05b53a32f..040152eaf31b4 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 161 | 0 | 147 | 2 | +| 164 | 0 | 150 | 2 | ## Client diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 2fe6ea9943582..8bdda4b341bc9 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-02-09 +date: 2024-02-10 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 fd1b3a8a717eb..d5990f78ae086 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-02-09 +date: 2024-02-10 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 09645999bfe41..8b0b2f4d09cc6 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-02-09 +date: 2024-02-10 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 21bbba8cd8614..206586826633c 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-02-09 +date: 2024-02-10 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 9f71cdf86860d..4a943c90dea82 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index a8e082ce22623..3b1bedb288c2b 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-02-09 +date: 2024-02-10 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 9bc95f3f861f1..3b666bcab3973 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-02-09 +date: 2024-02-10 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 17529da5c99d7..27ed013a44264 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-02-09 +date: 2024-02-10 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 d36557e040a7d..0724e1fdbb2fd 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-02-09 +date: 2024-02-10 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 a85ead41c14c4..08473606f3a19 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-02-09 +date: 2024-02-10 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 5d32477f4eac4..e7ec542f369d4 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-02-09 +date: 2024-02-10 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 e33912fbbc1ee..fb516421c5d51 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-02-09 +date: 2024-02-10 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 6943ffb606a7b..5a2607b183d78 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-02-09 +date: 2024-02-10 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 5ffd9c2ebb41d..f0198a49ddad1 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 2561f9a498d45..139fc75a8f530 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-02-09 +date: 2024-02-10 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 5638834710267..bf7a1a6a20cdd 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-02-09 +date: 2024-02-10 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 d0e6474172f12..10e8d93c82c94 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-02-09 +date: 2024-02-10 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 b71322b858533..54101814b7e73 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-02-09 +date: 2024-02-10 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 df77276d04166..4385d61c626ac 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-02-09 +date: 2024-02-10 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 821fde6c89393..328d643f6549e 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-02-09 +date: 2024-02-10 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 1adeabf51c66c..30ad29655d566 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index cc8a901cd3e54..317cfc5bde49d 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index cc074ffd86ab3..1e3f3728bc032 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 3860868eae9f1..5c60c4833efa2 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2024-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 871552ef580ce..20c6c6b43dc66 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-02-09 +date: 2024-02-10 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 62ce6e024de5a..1b82b8daee696 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-02-09 +date: 2024-02-10 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 e78e77f0b683d..8b72157191059 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 4a9016b138d68..e89eb79dd824a 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -4179,6 +4179,16 @@ "tags": [], "label": "RuleDefinitionProps", "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.RuleDefinitionProps", + "text": "RuleDefinitionProps" + }, + "<Params>" + ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false, @@ -4199,15 +4209,7 @@ "section": "def-common.SanitizedRule", "text": "SanitizedRule" }, - "<", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.RuleTypeParams", - "text": "RuleTypeParams" - }, - ">, \"alertTypeId\"> & { ruleTypeId: string; }" + "<Params>, \"alertTypeId\"> & { ruleTypeId: string; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, @@ -7820,11 +7822,43 @@ "label": "getAddRuleFlyout", "description": [], "signature": [ - "(props: Omit<", + "<Params extends ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + " = ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + ", MetaData extends ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeMetaData", + "text": "RuleTypeMetaData" + }, + " = ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeMetaData", + "text": "RuleTypeMetaData" + }, + ">(props: Omit<", "RuleAddProps", - "<Record<string, any>>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">) => React.ReactElement<", + "<Params, MetaData>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">) => React.ReactElement<", "RuleAddProps", - "<Record<string, any>>, string | React.JSXElementConstructor<any>>" + "<Params, MetaData>, string | React.JSXElementConstructor<any>>" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -7840,7 +7874,7 @@ "signature": [ "Omit<", "RuleAddProps", - "<Record<string, any>>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">" + "<Params, MetaData>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -7858,11 +7892,43 @@ "label": "getEditRuleFlyout", "description": [], "signature": [ - "(props: Omit<", + "<Params extends ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + " = ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + ", MetaData extends ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeMetaData", + "text": "RuleTypeMetaData" + }, + " = ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeMetaData", + "text": "RuleTypeMetaData" + }, + ">(props: Omit<", "RuleEditProps", - "<Record<string, any>>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">) => React.ReactElement<", + "<Params, MetaData>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">) => React.ReactElement<", "RuleEditProps", - "<Record<string, any>>, string | React.JSXElementConstructor<any>>" + "<Params, MetaData>, string | React.JSXElementConstructor<any>>" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -7878,7 +7944,7 @@ "signature": [ "Omit<", "RuleEditProps", - "<Record<string, any>>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">" + "<Params, MetaData>, \"actionTypeRegistry\" | \"ruleTypeRegistry\">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -8416,7 +8482,15 @@ "section": "def-public.RuleDefinitionProps", "text": "RuleDefinitionProps" }, - ") => React.ReactElement<", + "<", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + ">) => React.ReactElement<", { "pluginId": "triggersActionsUi", "scope": "public", @@ -8424,7 +8498,15 @@ "section": "def-public.RuleDefinitionProps", "text": "RuleDefinitionProps" }, - ", string | React.JSXElementConstructor<any>>" + "<", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + ">, string | React.JSXElementConstructor<any>>" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -8444,7 +8526,16 @@ "docId": "kibTriggersActionsUiPluginApi", "section": "def-public.RuleDefinitionProps", "text": "RuleDefinitionProps" - } + }, + "<", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleTypeParams", + "text": "RuleTypeParams" + }, + ">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 54ed2e7424e04..2fdc9240f070e 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-02-09 +date: 2024-02-10 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 7046d38f255df..9649cc36041e8 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-02-09 +date: 2024-02-10 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 90387f0a9e623..2881521f6bd06 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-02-09 +date: 2024-02-10 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 8cdbab8d29bc2..cc82d27a1aaa8 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-02-09 +date: 2024-02-10 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 ab6b3b425db60..94f99b974c036 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-02-09 +date: 2024-02-10 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 e576c5172b1a3..e59a248ea056e 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-02-09 +date: 2024-02-10 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 ca2b7fc38dff3..a1daae2521bfc 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-02-09 +date: 2024-02-10 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 ab0476a55f036..bed22a65e33f2 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-02-09 +date: 2024-02-10 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 503035cc178a0..c2572a4825298 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-02-09 +date: 2024-02-10 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 fd1e2fd3252f1..6007be5852e9f 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-02-09 +date: 2024-02-10 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 8ded43633aa1b..48974e7d35e7a 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-02-09 +date: 2024-02-10 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 1598fad99c4dc..ed4ae1d4de3a1 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-02-09 +date: 2024-02-10 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 788dbe3e1405b..2153b886e7695 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-02-09 +date: 2024-02-10 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 89b29bbd5d193..8dfc8327841cf 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-02-09 +date: 2024-02-10 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 d293b4f77202d..aecf8c4e9d8c4 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-02-09 +date: 2024-02-10 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 4971257adbca1..ec47b3b18ceaa 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-02-09 +date: 2024-02-10 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 eb9d104460c95..c6b5c813939b0 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-02-09 +date: 2024-02-10 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 cb4c784432c4f..002791afc1129 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-02-09 +date: 2024-02-10 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 b3ad6181b27a0..334f172fe0a94 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-02-09 +date: 2024-02-10 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 14928ff239e0e..b122ca0b04143 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-02-09 +date: 2024-02-10 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 435c72bbc9e98..e9a232aada676 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 9fb2997892af0..38f0691c9aa17 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-02-09 +date: 2024-02-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 361398cd9d8af89210dfb8c70dd0631e22ec5beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= <contact@patrykkopycinski.com> Date: Sat, 10 Feb 2024 13:28:32 +0100 Subject: [PATCH 101/104] [SentinelOne] Fix Agent status on Timeline Alert details (#176210) ## Summary Fixes https://github.com/elastic/kibana/issues/174235 <img width="1906" alt="Zrzut ekranu 2024-02-5 o 11 54 15" src="https://github.com/elastic/kibana/assets/5188868/5f40dc64-c0fc-4fbf-b4b9-d8ee6e75c890"> <img width="1910" alt="Zrzut ekranu 2024-02-5 o 11 53 53" src="https://github.com/elastic/kibana/assets/5188868/425efd0b-242e-4bb7-b034-13b34c1dde44"> Co-authored-by: Ash <1849116+ashokaditya@users.noreply.github.com> --- .../event_details/table/field_value_cell.tsx | 1 + .../timeline/body/renderers/formatted_field.tsx | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/field_value_cell.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/table/field_value_cell.tsx index bd4a59414e114..37f4f4559b50b 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/field_value_cell.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/table/field_value_cell.tsx @@ -71,6 +71,7 @@ export const FieldValueCell = React.memo( eventId={eventId} fieldFormat={data.format} fieldName={data.field} + fieldFromBrowserField={fieldFromBrowserField} fieldType={data.type} isAggregatable={fieldFromBrowserField.aggregatable} isDraggable={isDraggable} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx index 040e6335eb8a1..944ee20034d0e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx @@ -13,6 +13,7 @@ import { isNumber, isEmpty } from 'lodash/fp'; import React from 'react'; import { css } from '@emotion/css'; +import type { BrowserField } from '../../../../../common/containers/source'; import { ALERT_HOST_CRITICALITY, ALERT_USER_CRITICALITY, @@ -70,6 +71,7 @@ const FormattedFieldValueComponent: React.FC<{ isAggregatable?: boolean; isObjectArray?: boolean; fieldFormat?: string; + fieldFromBrowserField?: BrowserField; fieldName: string; fieldType?: string; isButton?: boolean; @@ -89,6 +91,7 @@ const FormattedFieldValueComponent: React.FC<{ isAggregatable = false, fieldName, fieldType = '', + fieldFromBrowserField, isButton, isObjectArray = false, isDraggable = true, @@ -261,6 +264,11 @@ const FormattedFieldValueComponent: React.FC<{ iconSide={isButton ? 'right' : undefined} /> ); + } else if ( + fieldName === SENTINEL_ONE_AGENT_ID_FIELD || + fieldFromBrowserField?.name === SENTINEL_ONE_AGENT_ID_FIELD + ) { + return <SentinelOneAgentStatus agentId={String(value ?? '')} />; } else if (fieldName === ALERT_HOST_CRITICALITY || fieldName === ALERT_USER_CRITICALITY) { return ( <AssetCriticalityLevel @@ -280,8 +288,6 @@ const FormattedFieldValueComponent: React.FC<{ data-test-subj="endpointHostAgentStatus" /> ); - } else if (fieldName === SENTINEL_ONE_AGENT_ID_FIELD) { - return <SentinelOneAgentStatus agentId={String(value ?? '')} />; } else if ( [ RULE_REFERENCE_FIELD_NAME, From 15ea6818887b0890a6a2f5d2c24e152c6be14ccf Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:24:46 -0500 Subject: [PATCH 102/104] [api-docs] 2024-02-11 Daily api_docs build (#176652) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/610 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/ai_assistant_management_observability.mdx | 2 +- api_docs/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/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 4 ++-- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_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/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_api_integration_helpers.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_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx | 2 +- api_docs/kbn_analytics_shippers_elastic_v3_common.mdx | 2 +- api_docs/kbn_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- api_docs/kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_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 +- api_docs/kbn_content_management_content_editor.mdx | 2 +- .../kbn_content_management_tabbed_table_list_view.mdx | 2 +- api_docs/kbn_content_management_table_list_view.mdx | 2 +- .../kbn_content_management_table_list_view_common.mdx | 2 +- api_docs/kbn_content_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- api_docs/kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- api_docs/kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- api_docs/kbn_core_application_browser_internal.mdx | 2 +- api_docs/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 +- api_docs/kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- api_docs/kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- api_docs/kbn_core_custom_branding_browser_internal.mdx | 2 +- api_docs/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 +- api_docs/kbn_core_custom_branding_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- api_docs/kbn_core_deprecations_browser_internal.mdx | 2 +- api_docs/kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- api_docs/kbn_core_deprecations_server_internal.mdx | 2 +- api_docs/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 +- .../kbn_core_elasticsearch_client_server_internal.mdx | 2 +- api_docs/kbn_core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- api_docs/kbn_core_elasticsearch_server_internal.mdx | 2 +- api_docs/kbn_core_elasticsearch_server_mocks.mdx | 2 +- api_docs/kbn_core_environment_server_internal.mdx | 2 +- api_docs/kbn_core_environment_server_mocks.mdx | 2 +- api_docs/kbn_core_execution_context_browser.mdx | 2 +- api_docs/kbn_core_execution_context_browser_internal.mdx | 2 +- api_docs/kbn_core_execution_context_browser_mocks.mdx | 2 +- api_docs/kbn_core_execution_context_common.mdx | 2 +- api_docs/kbn_core_execution_context_server.mdx | 2 +- api_docs/kbn_core_execution_context_server_internal.mdx | 2 +- api_docs/kbn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- api_docs/kbn_core_http_context_server_mocks.mdx | 2 +- api_docs/kbn_core_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- api_docs/kbn_core_http_resources_server_internal.mdx | 2 +- api_docs/kbn_core_http_resources_server_mocks.mdx | 2 +- api_docs/kbn_core_http_router_server_internal.mdx | 2 +- api_docs/kbn_core_http_router_server_mocks.mdx | 2 +- 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 +- api_docs/kbn_core_injected_metadata_browser_mocks.mdx | 2 +- api_docs/kbn_core_integrations_browser_internal.mdx | 2 +- api_docs/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 +- api_docs/kbn_core_metrics_collectors_server_internal.mdx | 2 +- api_docs/kbn_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 +- api_docs/kbn_core_notifications_browser_internal.mdx | 2 +- api_docs/kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- api_docs/kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_contracts_browser.mdx | 2 +- api_docs/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 +- api_docs/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 +- api_docs/kbn_core_saved_objects_api_browser.mdx | 2 +- api_docs/kbn_core_saved_objects_api_server.mdx | 2 +- api_docs/kbn_core_saved_objects_api_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_base_server_internal.mdx | 2 +- api_docs/kbn_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- api_docs/kbn_core_saved_objects_browser_internal.mdx | 2 +- api_docs/kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ...n_core_saved_objects_import_export_server_internal.mdx | 2 +- .../kbn_core_saved_objects_import_export_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_migration_server_internal.mdx | 2 +- .../kbn_core_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- api_docs/kbn_core_saved_objects_server_internal.mdx | 2 +- api_docs/kbn_core_saved_objects_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- api_docs/kbn_core_test_helpers_deprecations_getters.mdx | 2 +- api_docs/kbn_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- api_docs/kbn_core_test_helpers_model_versions.mdx | 2 +- api_docs/kbn_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 +- api_docs/kbn_core_ui_settings_browser_internal.mdx | 2 +- api_docs/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 +- api_docs/kbn_core_ui_settings_server_internal.mdx | 2 +- api_docs/kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- api_docs/kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- api_docs/kbn_core_user_settings_server_internal.mdx | 2 +- api_docs/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_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_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.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_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_utils.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_ftr_common_functional_services.mdx | 2 +- api_docs/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_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- api_docs/kbn_language_documentation_popover.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 +- api_docs/kbn_management_settings_application.mdx | 2 +- .../kbn_management_settings_components_field_category.mdx | 2 +- .../kbn_management_settings_components_field_input.mdx | 2 +- api_docs/kbn_management_settings_components_field_row.mdx | 2 +- api_docs/kbn_management_settings_components_form.mdx | 2 +- api_docs/kbn_management_settings_field_definition.mdx | 2 +- api_docs/kbn_management_settings_ids.mdx | 2 +- api_docs/kbn_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- api_docs/kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_cancellable_search.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.mdx | 2 +- api_docs/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_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_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.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_observability_alert_details.mdx | 2 +- api_docs/kbn_observability_alerting_test_data.mdx | 2 +- ...kbn_observability_get_padded_alert_time_range_util.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 +- api_docs/kbn_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_library.mdx | 2 +- api_docs/kbn_presentation_publishing.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_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_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_export_types_csv.mdx | 2 +- api_docs/kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- api_docs/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 +- api_docs/kbn_rison.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_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_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 +- 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 +- api_docs/kbn_security_solution_storybook_config.mdx | 2 +- api_docs/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 +- .../kbn_securitysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_alerting_types.mdx | 2 +- api_docs/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 +- api_docs/kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- api_docs/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 +- api_docs/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 +- api_docs/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 +- api_docs/kbn_shared_ux_page_analytics_no_data.mdx | 2 +- api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_kibana_no_data.mdx | 2 +- api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_kibana_template.mdx | 2 +- api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_config.mdx | 2 +- api_docs/kbn_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 +- api_docs/kbn_shared_ux_prompt_no_data_views.mdx | 2 +- api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_predicates.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_eui_helpers.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.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_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_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_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.mdx | 2 +- api_docs/observability_a_i_assistant.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 | 2 +- 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/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.devdocs.json | 8 ++++++++ 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.mdx | 2 +- 652 files changed, 660 insertions(+), 652 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 385bace06af5c..1041386cb6e10 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-02-10 +date: 2024-02-11 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 5734ae5e9beb4..bc2f968d242fd 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index 81bbb9eec6157..d8c9273c69fa7 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index e3c7fb1b34421..db73648e063ce 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-02-10 +date: 2024-02-11 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 52baff9a29b68..c317344cd7f56 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-02-10 +date: 2024-02-11 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 3f58abbc34425..4c07ae5f5c1a9 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-02-10 +date: 2024-02-11 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 073c749dbaf0f..b18e528e6cd36 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-02-10 +date: 2024-02-11 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 5fe323732a208..96e99d36d50fe 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 26b95529e8e26..86b9d7561b9ca 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index a457f71e8152a..6d56f0d4cd985 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-02-10 +date: 2024-02-11 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 9903660e5fe92..5757e05c7c00f 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-02-10 +date: 2024-02-11 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 ef8952788418d..ff8ae3383927d 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-02-10 +date: 2024-02-11 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 51c8b686da324..f85e9f6b480de 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-02-10 +date: 2024-02-11 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 8662e11cc0b62..11957153e800c 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-02-10 +date: 2024-02-11 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 8aecbad4d755b..fa5a439a22043 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-02-10 +date: 2024-02-11 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 55eadee9af118..01e309ea8c2b7 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-02-10 +date: 2024-02-11 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 5239c88744810..2031602713676 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 2859e6ad0d3de..d3604c3fa4fb4 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 3e8c34896e442..72d16a085ff68 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-02-10 +date: 2024-02-11 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 ef57dbe135be7..bb66912bcb867 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-02-10 +date: 2024-02-11 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 ede55af292d72..0e80a36b2a6e1 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-02-10 +date: 2024-02-11 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 20f2a4ff40aff..9a050ec299b13 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-02-10 +date: 2024-02-11 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 73f9b520cb963..2ce940f46dd41 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-02-10 +date: 2024-02-11 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 43d323614e724..45df395c57beb 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-02-10 +date: 2024-02-11 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 3c102e384fdb5..e6ef382e215ed 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-02-10 +date: 2024-02-11 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 d392a2eaa6de3..028c60ed612f9 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 30f1279e2463d..93971928c7a2c 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-02-10 +date: 2024-02-11 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 cdef05f30954b..2e712511f4adf 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 730b676ca2340..44cc140245361 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-02-10 +date: 2024-02-11 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 73cf10c137023..4ba268a88db0c 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-02-10 +date: 2024-02-11 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 7898b51c52ca3..af38065be262c 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-02-10 +date: 2024-02-11 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 385631c40e4cc..eb3c2bf226b84 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-02-10 +date: 2024-02-11 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 c0621eb6049da..0150e9e40e149 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-02-10 +date: 2024-02-11 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 82b645c4f7a3a..d6bc68c2741c1 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-02-10 +date: 2024-02-11 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 a73f304c5640f..e31c68f84f380 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 20ccee017d4c6..155bc9da9e270 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1344,7 +1344,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | <DocLink id="kibTimelinesPluginApi" section="def-common.DeprecatedCellValueElementProps" text="DeprecatedCellValueElementProps"/> | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedCellValueElementProps), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedCellValueElementProps) | - | | <DocLink id="kibTimelinesPluginApi" section="def-common.DeprecatedRowRenderer" text="DeprecatedRowRenderer"/> | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedRowRenderer), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx#:~:text=DeprecatedRowRenderer) | - | | <DocLink id="kibTimelinesPluginApi" section="def-common.BeatFields" text="BeatFields"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields) | - | -| <DocLink id="kibTimelinesPluginApi" section="def-common.BrowserField" text="BrowserField"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [table_tab.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/table_tab.tsx#:~:text=BrowserField)+ 31 more | - | +| <DocLink id="kibTimelinesPluginApi" section="def-common.BrowserField" text="BrowserField"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [table_tab.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/flyout/document_details/right/tabs/table_tab.tsx#:~:text=BrowserField)+ 33 more | - | | <DocLink id="kibTimelinesPluginApi" section="def-common.BrowserFields" text="BrowserFields"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields)+ 108 more | - | | <DocLink id="kibTimelinesPluginApi" section="def-common.IndexFieldsStrategyRequest" text="IndexFieldsStrategyRequest"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyRequest), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyRequest) | - | | <DocLink id="kibTimelinesPluginApi" section="def-common.IndexFieldsStrategyResponse" text="IndexFieldsStrategyResponse"/> | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyResponse), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyResponse) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 8268c82e8b3d7..1c755e1ba8642 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 8aac3a6f3b46f..65fd870b52391 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-02-10 +date: 2024-02-11 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 9dd4510a41dac..b47712cb842ad 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-02-10 +date: 2024-02-11 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 27d0e5d0fd8c3..f50ea600dc2c2 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 42d6e47ce507e..4c0ad20483eda 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 6d7a2905a27eb..13dfeb0b641c9 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 003522e0f9da7..e2b24384583be 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-02-10 +date: 2024-02-11 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 d687aea7596fe..de166a20184c0 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-02-10 +date: 2024-02-11 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 94b2eae124249..5e77b2f36d665 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-02-10 +date: 2024-02-11 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 7d8023458a887..959aa41bee249 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 194930dcde554..5244efee18bf2 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index eca9aadb77c3d..3a1cbe07c2426 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-02-10 +date: 2024-02-11 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 c68eb28a03abc..58bcbab03f923 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-02-10 +date: 2024-02-11 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 46f771ff07dc1..6c6eb503d46d8 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-02-10 +date: 2024-02-11 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 e9f05619a8dd3..c845068d49099 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-02-10 +date: 2024-02-11 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 7aecfd92d86d6..2c26256a58515 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-02-10 +date: 2024-02-11 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 deb9c5c6d549a..e0796e969a312 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-02-10 +date: 2024-02-11 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 707689b79f325..d2ea8a0e64c6b 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-02-10 +date: 2024-02-11 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 b278d5a2cb1a9..58a5a495a84ae 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-02-10 +date: 2024-02-11 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 3ff1b3b40985d..bd2ee88518a4f 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-02-10 +date: 2024-02-11 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 2a5faba1310bb..dd579c1cef1a2 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-02-10 +date: 2024-02-11 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 c10ad2a572013..5ff8e85f61f95 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-02-10 +date: 2024-02-11 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 570e60ec1385b..5153d966efe57 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-02-10 +date: 2024-02-11 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 c5fe43d2d2e02..596cc2f7e6b8c 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-02-10 +date: 2024-02-11 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 ab32d9a193695..f3d6ce4379b45 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-02-10 +date: 2024-02-11 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 6ea64173bfd47..435c1e00cdbb9 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-02-10 +date: 2024-02-11 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 5978901522114..b5356fceb49af 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-02-10 +date: 2024-02-11 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 32e35b30b4405..0ab68091b1ade 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-02-10 +date: 2024-02-11 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 7f3c3ab3d9aa7..31aac69f17f1f 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-02-10 +date: 2024-02-11 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 66a8d7ac10e0c..4355e1ae31535 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-02-10 +date: 2024-02-11 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 44cc417be8e3a..f2f150f5a4ec2 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index c3f78beaa3dc8..4c29d4ccf87ab 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-02-10 +date: 2024-02-11 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 7cd528bfd6806..ad4072afdae89 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-02-10 +date: 2024-02-11 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 a113b757d4230..77114d365fd8f 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-02-10 +date: 2024-02-11 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 71a1488267568..d64ad71a0c38b 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-02-10 +date: 2024-02-11 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 da2511ef2e085..169aa8c614bcd 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-02-10 +date: 2024-02-11 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 9ba4c3632a097..086213d6a81d3 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-02-10 +date: 2024-02-11 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 c811bf4bbd5fd..e4e7d60a20fae 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-02-10 +date: 2024-02-11 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 90f6feadffa18..f6fcdf2c591bb 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 266deabab25bf..a40b0acf29873 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-02-10 +date: 2024-02-11 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 d4fbbc6f8bf3c..ef262558f1113 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 1f7a532261ba4..9e9fb18d712a1 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-02-10 +date: 2024-02-11 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 c7bfd305adcec..55c2fe1db07c7 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-02-10 +date: 2024-02-11 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 f9c4a9d60d719..e91a6e420a1db 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 295c7178e61bd..619a88c16d339 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index f1eeacedbb20c..80fc01383bc6b 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 36183318e0f30..28296500042c7 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 393b9c4e201a8..47eb03dd8e885 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 064f89eaed226..4094b48259a8a 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 5b7c96246091e..af33915564639 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-02-10 +date: 2024-02-11 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_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 2f9646e08c988..a398d622da1c1 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-02-10 +date: 2024-02-11 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 7c53292350518..81c9403ac0c35 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-02-10 +date: 2024-02-11 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 e6bd9400e916b..748e0c9d0ff58 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 8715e94ca938c..59fade1071a09 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-02-10 +date: 2024-02-11 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 5a81d02650139..50efd953efd64 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index d2407c6a00f8e..43792105a00d8 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index dc98e3f1031da..05d494990f347 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 903d5f709db6c..4f6b89f965ee4 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 2ed519c7c509d..5a0cc6c7c59b7 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 571cd44598eca..556ff060fdd07 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 9993c04d8306c..fd8a277edad3f 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 9db415a0f553d..27160f3e49f68 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 991c7c658d887..bde6dc15d68c5 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-02-10 +date: 2024-02-11 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 be5f8a74f544e..8399c7485e42c 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index c117496622630..fbfd6bdd0aad8 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 7388f586fd99e..6a612449687be 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-02-10 +date: 2024-02-11 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 924255022d659..f955c3ff8bfa3 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-02-10 +date: 2024-02-11 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 d5dad96ca9487..38b63c0c931cb 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-02-10 +date: 2024-02-11 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 ed41a608c2cfe..906cac0b05fda 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-02-10 +date: 2024-02-11 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 37c4588f5af95..07ea440bf6979 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 09aed137aebe3..76ab0103ac06f 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-02-10 +date: 2024-02-11 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 4df8356b2ea5e..ed49298af5f61 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-02-10 +date: 2024-02-11 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 bdee9298139c5..fe7dbe24dd064 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-02-10 +date: 2024-02-11 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 341b80db560be..55f01999c743b 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-02-10 +date: 2024-02-11 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 ca0e8165aa69b..d145d3d1d4fca 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-02-10 +date: 2024-02-11 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 71f560eba2896..4a8ac49cea9c1 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-02-10 +date: 2024-02-11 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 86feb7c0db9ae..35725be6673fb 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index d86b8602c204a..25484cf59b24b 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-02-10 +date: 2024-02-11 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 8aae4cc7da1cc..d02ec2122933f 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-02-10 +date: 2024-02-11 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 2b978b8bca133..3457cf8385e93 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-02-10 +date: 2024-02-11 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 16a510b5f493f..c0f08ec8ec330 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-02-10 +date: 2024-02-11 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 d9115d0c2cf16..b409ac5cb81a9 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-02-10 +date: 2024-02-11 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 0ef3138330707..d0a67372e1e3f 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-02-10 +date: 2024-02-11 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 939a7867fa46f..77761dafbacc3 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-02-10 +date: 2024-02-11 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 acc66e6975c3e..64cfbfaf3d388 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index f9709d3c5b4a1..a44c32d310b61 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-02-10 +date: 2024-02-11 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 0a95998371bd4..c1c4fa33ae5da 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-02-10 +date: 2024-02-11 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 787f450b21f24..b8241df42b20e 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-02-10 +date: 2024-02-11 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 b99fd3702fdde..35302060bb561 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 5878bb149fa68..8b308d064e6e4 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 1902da366b1e3..afb48904fa94c 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-02-10 +date: 2024-02-11 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 de0cb33baabe7..ecbf9052304ed 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-02-10 +date: 2024-02-11 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 eec32019b79b5..778f1f4f71bea 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 937613c5a8557..63d59ccb10f87 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-02-10 +date: 2024-02-11 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 2966b582c7378..94922dc9157c2 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-02-10 +date: 2024-02-11 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 ab7819913bf7e..2f6a910c4688c 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-02-10 +date: 2024-02-11 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 0b9418d473ed6..0cf719e5588c5 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-02-10 +date: 2024-02-11 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 dc7b32770eb0f..b6aa80659d319 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-02-10 +date: 2024-02-11 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 4a05c83be1775..7cf8a8b00a93d 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-02-10 +date: 2024-02-11 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 f81c1ec314a42..7aad0aa4c5569 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-02-10 +date: 2024-02-11 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 bb10a729ebae7..2e243e13530e4 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-02-10 +date: 2024-02-11 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 ba349fbfdb853..acdd32a7bfe42 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-02-10 +date: 2024-02-11 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 ccf53d45f6a40..e10e733169a21 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-02-10 +date: 2024-02-11 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 523b1c8107eeb..984dced41f5a2 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-02-10 +date: 2024-02-11 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 8feb1db2cf147..9d918db9e235a 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-02-10 +date: 2024-02-11 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 07ecf91a4c42e..bc8385268b917 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-02-10 +date: 2024-02-11 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 759df6adf3ea5..285e4af68bc9f 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-02-10 +date: 2024-02-11 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 ce66a7d77cd00..878a8a1147833 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-02-10 +date: 2024-02-11 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 35109e0feced4..f8b6a2b6c32d4 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-02-10 +date: 2024-02-11 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 7a702564cb4f2..d743ec1c4df86 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-02-10 +date: 2024-02-11 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 c7d059754d0c4..5155e9c1c9f9a 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 8134214a2ea4e..53713cab702a6 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-02-10 +date: 2024-02-11 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 c5eed9334e92a..d95e1c0e3b6c4 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-02-10 +date: 2024-02-11 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 9b59973ac6bf5..87cad7a4a7aa6 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-02-10 +date: 2024-02-11 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 b0efc51397f58..1606de8053efa 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-02-10 +date: 2024-02-11 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 5a03985977ded..b8a9bdf6327c4 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-02-10 +date: 2024-02-11 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 5cdbf567386d0..881b13f962fc2 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-02-10 +date: 2024-02-11 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 a267385219fcf..00ff36e5a9b12 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-02-10 +date: 2024-02-11 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 cffc7f422d36d..ebe7dcce10cb3 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-02-10 +date: 2024-02-11 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 fe182cc8a7c8f..003d60dc54ce7 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-02-10 +date: 2024-02-11 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 772e457b019c7..3830daddbd95c 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-02-10 +date: 2024-02-11 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 35bb11a528db6..b2f5c372de502 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-02-10 +date: 2024-02-11 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 8b31794f54a11..ff470228c7f7b 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-02-10 +date: 2024-02-11 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 8f051aae78749..c1836d2822c32 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-02-10 +date: 2024-02-11 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 61649bb1b8142..2128e6eb6213f 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-02-10 +date: 2024-02-11 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 11f9add6c507d..4d2b587d1b6b4 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-02-10 +date: 2024-02-11 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 fc3710f36b04e..33f6ac490860a 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-02-10 +date: 2024-02-11 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 e8989b93c296d..a3923e66a070d 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-02-10 +date: 2024-02-11 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 27a309c42f5c4..6682062f66a04 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-02-10 +date: 2024-02-11 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 19821de0267bf..7e412e4d84656 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-02-10 +date: 2024-02-11 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 a9a168afb1ef7..c1c0498587d6d 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-02-10 +date: 2024-02-11 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 7381f962b4feb..e79ddfb62ae5f 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-02-10 +date: 2024-02-11 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 ca2cf8b282ff5..2225a4cc87d5f 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-02-10 +date: 2024-02-11 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 397e8fda55e92..05b4dfd3bcec0 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-02-10 +date: 2024-02-11 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 6b5435b15b17f..eab8ac0954ccd 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-02-10 +date: 2024-02-11 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 4b80b31e2f9be..58d4827d4d876 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-02-10 +date: 2024-02-11 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 3cdb305df92eb..edef4939e24fd 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-02-10 +date: 2024-02-11 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 7f11b0532937d..90101269c587d 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-02-10 +date: 2024-02-11 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 20351accd4c36..9197b11c59c00 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-02-10 +date: 2024-02-11 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 3183542db20c4..73e12d30cd33f 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-02-10 +date: 2024-02-11 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 89ed95c29ef1b..cf67d90eb24a3 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-02-10 +date: 2024-02-11 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 238de24f9ccab..ebca881c0be5b 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-02-10 +date: 2024-02-11 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 3b266e5293b15..3b4a650d211d3 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-02-10 +date: 2024-02-11 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 631db8084cd76..ca1b8247c53c4 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-02-10 +date: 2024-02-11 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 b54a45840bd36..0ad6538d70d66 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-02-10 +date: 2024-02-11 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 6bf7cca624cfa..b5cf62d6ae0d7 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-02-10 +date: 2024-02-11 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 9735265dd33ba..0676526d3dbf0 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-02-10 +date: 2024-02-11 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 81e5b6b9b3c55..2e5ce4430dfde 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 942b52f3098cd..1bd082b34cdd5 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-02-10 +date: 2024-02-11 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 7d90946cab1bd..cda9e42bafd7c 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-02-10 +date: 2024-02-11 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 72c6ebe96708b..21bbb2be7b2d1 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-02-10 +date: 2024-02-11 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 62f1e5d762a64..c8fab3a573a8e 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-02-10 +date: 2024-02-11 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 21219eefda9a5..08cdc48bd3ea4 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-02-10 +date: 2024-02-11 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 c9e3f32ce8438..6af22f0888884 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-02-10 +date: 2024-02-11 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 93781ec36eca3..0aecd1a7d302f 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-02-10 +date: 2024-02-11 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 c0ea6831350b4..dab5d7e38b5c9 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-02-10 +date: 2024-02-11 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 266c2ebd7dd2b..ff081c38aa591 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-02-10 +date: 2024-02-11 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 164507696e107..35d2a8ed5998e 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-02-10 +date: 2024-02-11 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 c752470fce9ec..d1a4660f7f4d5 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 7e26a285432ba..76e5eb520904f 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-02-10 +date: 2024-02-11 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 815a8b2c4b777..e937c3fc1ddb0 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-02-10 +date: 2024-02-11 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 97b5079457d95..7753581fb96b1 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-02-10 +date: 2024-02-11 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 afa686edf71a4..193c353704d9e 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-02-10 +date: 2024-02-11 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 f7f3971751506..6c814d7ce06e6 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-02-10 +date: 2024-02-11 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 045f2498b6446..49e165ebbecd8 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-02-10 +date: 2024-02-11 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 c126972883b7b..2e0f3ce02543e 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-02-10 +date: 2024-02-11 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 6a47c1c26cc09..545044bf52ffa 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-02-10 +date: 2024-02-11 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 4fa95fc2cf606..0fd0fa460dddb 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-02-10 +date: 2024-02-11 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 ab93441e8da46..cc96782959ee9 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-02-10 +date: 2024-02-11 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 60a5bbe0a846f..f6fe47ac21d11 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-02-10 +date: 2024-02-11 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 ae35d2ed85e19..75d0fe03b17cc 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-02-10 +date: 2024-02-11 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 0df896bda210d..f3b8c71159e6c 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-02-10 +date: 2024-02-11 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 3e3a3dc391f41..e16f639b13af3 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-02-10 +date: 2024-02-11 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 aba33bff6d31f..6ffed34ebd619 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-02-10 +date: 2024-02-11 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 e6495b961442a..6e120d259e69d 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-02-10 +date: 2024-02-11 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 776cb38e8283a..c99f19f834dc5 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-02-10 +date: 2024-02-11 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 fde5f7a2f01bc..00c26cf52fb06 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-02-10 +date: 2024-02-11 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 e71ceb01ac7ab..a2224af004975 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-02-10 +date: 2024-02-11 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 965ab641cc59f..f3f51eaed7399 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-02-10 +date: 2024-02-11 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 90cfc709b801b..91a777e524285 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-02-10 +date: 2024-02-11 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 00410c3af99bf..f04a4a69dc7cd 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-02-10 +date: 2024-02-11 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 3ef5c8a0f7380..40db72a5cca5b 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-02-10 +date: 2024-02-11 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 3b717e577e6b5..987bbe7199823 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-02-10 +date: 2024-02-11 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 a9fa3cc078672..f0bd3ae2f9c16 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-02-10 +date: 2024-02-11 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 85d7b44679526..629a8a8b0c33b 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-02-10 +date: 2024-02-11 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 d719bf928f140..60b68fdbfc68b 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-02-10 +date: 2024-02-11 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 e454a0a9b9454..462fd470809ba 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-02-10 +date: 2024-02-11 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 de391fbda8537..921b9dc9e1bbc 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-02-10 +date: 2024-02-11 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 32547fcfb42ae..40cc1e2bc1c89 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-02-10 +date: 2024-02-11 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 6688150902809..c996d8e1352e8 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-02-10 +date: 2024-02-11 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 eef75e992f7fb..b403be9b87ccc 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-02-10 +date: 2024-02-11 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 989599138061b..f36f423ececc9 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-02-10 +date: 2024-02-11 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 e855ae4e38644..ac138745d54bf 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-02-10 +date: 2024-02-11 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 7e2ea15f45a96..7bebb45195bb6 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-02-10 +date: 2024-02-11 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 7701b3dd886bb..10cfba81a031b 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-02-10 +date: 2024-02-11 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 71219cb242432..053581b9baeae 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-02-10 +date: 2024-02-11 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 f29dcfb55ae81..84b177f971a31 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-02-10 +date: 2024-02-11 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 0ef955671242e..22370e6949e96 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-02-10 +date: 2024-02-11 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 4efbdad0e2747..cd05db32d8be9 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-02-10 +date: 2024-02-11 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 dbde40fcc73b5..617d71964d1bd 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-02-10 +date: 2024-02-11 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 b3ee3839939c5..c4bc9e752e45d 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-02-10 +date: 2024-02-11 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 bb7f38d3b6e13..dba8c170343ef 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-02-10 +date: 2024-02-11 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 557854da25915..02a5ede291405 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-02-10 +date: 2024-02-11 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 d39ecc895ad4c..685d1f49367f2 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-02-10 +date: 2024-02-11 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 9f700f97c289b..2e682e6ad1713 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-02-10 +date: 2024-02-11 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 4a62c1724c8ad..03f401cafde13 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-02-10 +date: 2024-02-11 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 9ceb806ba76a2..d46a3cbb206c5 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-02-10 +date: 2024-02-11 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 275e1ba19060d..3af095dc0555b 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-02-10 +date: 2024-02-11 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 712bbcd67e7e0..bea06555ff846 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-02-10 +date: 2024-02-11 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 c5ba1f3b3513b..675ae0e61abff 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-02-10 +date: 2024-02-11 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 dc91d6647528a..2f2989e030210 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-02-10 +date: 2024-02-11 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 d5736d527411b..53d9de40560d3 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-02-10 +date: 2024-02-11 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 af41c951d61c9..acbb45108ca0b 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-02-10 +date: 2024-02-11 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 2532cf0b42d1b..8409b60b78631 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-02-10 +date: 2024-02-11 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 d98b89ce8926a..11560a453300b 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-02-10 +date: 2024-02-11 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 cbc8d55e7d8b7..c83f9349b6264 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-02-10 +date: 2024-02-11 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 fed1e77f2466e..17e4b0cb86896 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-02-10 +date: 2024-02-11 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 346cc4f47eebf..dca851069c374 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-02-10 +date: 2024-02-11 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 e0d1ab00dbed6..39eb8def4328f 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-02-10 +date: 2024-02-11 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 da8dd4e70576c..dd3aaa56a5d98 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-02-10 +date: 2024-02-11 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 9a16ba0f67f34..082c7b99ffcd9 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-02-10 +date: 2024-02-11 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 04d7e364e1c97..4e90cfc1e6e15 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-02-10 +date: 2024-02-11 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 e179632b24033..02bf834756c06 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index b0a7a2a0ad1ad..f5b390b4d6438 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-02-10 +date: 2024-02-11 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 867337b0818d0..f97d0bf41d4cf 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-02-10 +date: 2024-02-11 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 cffb76324bdd8..cec55ecaf5a10 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-02-10 +date: 2024-02-11 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 68e833c0eefb7..6be3bc50dccf0 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-02-10 +date: 2024-02-11 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 7747b56e0065c..4deb8b0633b17 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-02-10 +date: 2024-02-11 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 52e07c7423a9d..7b3335ffa7aa1 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-02-10 +date: 2024-02-11 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 27e7c486236fe..f705307de1c28 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-02-10 +date: 2024-02-11 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 56c0bbc5c9d28..78385197b30dd 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-02-10 +date: 2024-02-11 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 308ec720b09d9..fb6feaa12d5d6 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-02-10 +date: 2024-02-11 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 5b8219fd130ae..567f43a631ec1 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-02-10 +date: 2024-02-11 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 56d810c8b9d4d..8cdf04449d6f4 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-02-10 +date: 2024-02-11 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 01ba055003c58..38376bd6baa48 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-02-10 +date: 2024-02-11 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 03b406dd53618..7169a88a58466 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-02-10 +date: 2024-02-11 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 c3a318fdd8506..c40abe664606b 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-02-10 +date: 2024-02-11 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 21e53212f1a9b..2f563c6c9428d 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-02-10 +date: 2024-02-11 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 129e221381f71..64eb47baa59cd 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-02-10 +date: 2024-02-11 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 0151abd60c96d..750b73ad06c37 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-02-10 +date: 2024-02-11 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 05375848de0a8..db4a9c18429f0 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-02-10 +date: 2024-02-11 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 e6e92e1ddb15b..2c470fb72fbe7 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-02-10 +date: 2024-02-11 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 f4ff48ee2390f..8a86bd09b026d 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-02-10 +date: 2024-02-11 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 5d44cd1340411..1ea34ec532c0c 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-02-10 +date: 2024-02-11 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 7ca4dfc2af7f6..2bf75c924dd9b 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-02-10 +date: 2024-02-11 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 55fc147bb51b1..2c86d1d129ca6 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 7baffd9a337dd..dbf9ede0ec2bc 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index beeb43494f56d..f8e539a5983c0 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 955bab1c0907f..b3b97bbc99e33 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-02-10 +date: 2024-02-11 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 8382b8b7211c5..d546f7eb0b8b6 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-02-10 +date: 2024-02-11 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 2b5db318bbf8f..0de4ea41bb1e3 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-02-10 +date: 2024-02-11 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 ef4bc5ca86c54..b63875a2b2e1a 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-02-10 +date: 2024-02-11 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 7401acb07f77f..23c57769366e0 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-02-10 +date: 2024-02-11 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 242813d24b42a..531a2845dcb49 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-02-10 +date: 2024-02-11 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 abf0fc99e6675..f37e53b48e8c9 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-02-10 +date: 2024-02-11 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 1d140c39438c2..5e4534cde7c0d 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-02-10 +date: 2024-02-11 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 4666c49629ff7..77fc9dd7ae6a7 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-02-10 +date: 2024-02-11 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 c226bd958f071..c43c651e325dc 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-02-10 +date: 2024-02-11 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 7c1b33236f042..d68867caf0ad0 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-02-10 +date: 2024-02-11 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 7df5aff22f019..98469aeca9f05 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-02-10 +date: 2024-02-11 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 8d4f6e607057b..c97e5e1f31fa1 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 23726b5256c23..0d9c5819384ef 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-02-10 +date: 2024-02-11 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 bc89b167d2fb1..abcfa6f992290 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-02-10 +date: 2024-02-11 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 0aa020795fc6e..2ac272eb2619f 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index 934fb73f600ab..bbcbbc5f68df4 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index d8b00b3414c98..aee098b3b7f88 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-02-10 +date: 2024-02-11 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 1f118459d856b..743e5c98149f6 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-02-10 +date: 2024-02-11 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 6320bf7d18323..afd1abbc862b5 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-02-10 +date: 2024-02-11 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 a00814e7c3c34..f3312bac2d196 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-02-10 +date: 2024-02-11 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 512a88036b08a..aed134c87c494 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-02-10 +date: 2024-02-11 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 9feb9ca85abee..522fc2f980961 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-02-10 +date: 2024-02-11 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 84d2b407e1c43..d210d46ea4da0 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-02-10 +date: 2024-02-11 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 c2879ebfe52c8..99a003339cc51 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 0f258bf4ca1f0..15e808284f6c6 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-02-10 +date: 2024-02-11 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 a9126f067853c..bf247f42d6d72 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-02-10 +date: 2024-02-11 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 15e83084ea426..4d241e9e7a101 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-02-10 +date: 2024-02-11 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 fc644d967dfcf..6bd2d52f42dc4 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-02-10 +date: 2024-02-11 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 c0794e88e5525..1a5fbca3918c3 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index a6bed31af50f5..2c93053c427c3 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 8e642b6ec5664..af48c01b178a9 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-02-10 +date: 2024-02-11 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 052ef3400ee5b..3d52a7f768bab 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-02-10 +date: 2024-02-11 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 b5ca26607e577..c5ee6c045acbb 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-02-10 +date: 2024-02-11 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 818ec2c3f6c3d..67c668afc039b 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 83abbd1cc51c5..f759301cc1861 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-02-10 +date: 2024-02-11 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 4efc5364c8bc7..a8fab1b683990 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-02-10 +date: 2024-02-11 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 36149a69b2837..862b7d1ecd8d6 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-02-10 +date: 2024-02-11 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 a3ab6e0049fb2..ec3cd4b84883a 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 1d9ca732a6b97..29f4c160cd89e 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-02-10 +date: 2024-02-11 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 1c05716c6e91e..9f9f75b63e70b 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-02-10 +date: 2024-02-11 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_utils.mdx b/api_docs/kbn_esql_utils.mdx index 011047050c9b4..2b8f56aaf2c67 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index f1bb33842488a..95422718b5e88 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-02-10 +date: 2024-02-11 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 c4ac6cc29456e..863e7444ac006 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-02-10 +date: 2024-02-11 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 25f3648f36f01..1b786996390a7 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-02-10 +date: 2024-02-11 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 3ce0842a1c2d5..8e8d128f99b76 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-02-10 +date: 2024-02-11 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 d12a4434a634c..0efc5d1e62031 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-02-10 +date: 2024-02-11 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 b78352b547a7a..fa168c06193cc 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 058d20814bc55..5bbea782e5316 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-02-10 +date: 2024-02-11 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 2bdcee8425ca3..290d48a645f7f 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-02-10 +date: 2024-02-11 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 790280c86d5d5..f0be8a8f6c940 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-02-10 +date: 2024-02-11 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 8968068f83f77..c2a0a284136fc 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-02-10 +date: 2024-02-11 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 19753a377151c..ab8fa5e933e75 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index c0f9a940d0ae5..9a17ba93c5f79 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-02-10 +date: 2024-02-11 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 bf63f73ac1b56..9a5c5d008f19d 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-02-10 +date: 2024-02-11 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 ff261138ec12a..c6242a47237d2 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-02-10 +date: 2024-02-11 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 b8ba063f387a1..64ba9ebb6f1f1 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-02-10 +date: 2024-02-11 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 962dd3f0f2400..dac1c7c33c6e8 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-02-10 +date: 2024-02-11 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 f525c42a8bdd6..10e81aea5e1ff 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-02-10 +date: 2024-02-11 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 08aff73759d83..d7e2f67c98aec 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-02-10 +date: 2024-02-11 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 0c6644fcfa7d3..eb78dfb0507ea 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-02-10 +date: 2024-02-11 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 e811b00965b2e..2d9dc15a7fb0d 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 8d8b03f15d933..8b6fe79e5d81b 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-02-10 +date: 2024-02-11 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 8f354f520e2b6..5fcc0eb62af0e 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 05adcf6fe8298..812cd5ba62b56 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 9b54d20bf6cf9..a70cb5fb9d140 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-02-10 +date: 2024-02-11 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 98a56b90e57d9..883f838637ef7 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-02-10 +date: 2024-02-11 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 b94b252c606d4..60d52b5b3cd92 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 51f7f2e32d903..600e3dce46524 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 695c4dedae298..1bc5cf588ff44 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index b977cf3c01d7d..06ecb346029f0 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-02-10 +date: 2024-02-11 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 205a95e9d80eb..ccf5a3235b3f6 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-02-10 +date: 2024-02-11 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 ba179a1fe1c06..b765ed7b42bf1 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-02-10 +date: 2024-02-11 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 6e9184f0ce678..47460c054bac1 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-02-10 +date: 2024-02-11 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 d2cda667bac15..acae16ca482e4 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-02-10 +date: 2024-02-11 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 35e236ba517e1..2b1b2ef9e44ec 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-02-10 +date: 2024-02-11 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 0c3d4785ce496..2d886fcfd597c 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-02-10 +date: 2024-02-11 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 86b54a21a7f93..cab65c930c2be 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-02-10 +date: 2024-02-11 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 687e93dbbcd78..f88167fc18530 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-02-10 +date: 2024-02-11 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 0c2e809bd7e0f..122176aa636fd 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-02-10 +date: 2024-02-11 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 706876b0d3857..8b60182f00778 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-02-10 +date: 2024-02-11 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 b9ca77e10d5b2..083749a7340d8 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-02-10 +date: 2024-02-11 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 1790f4a97c4c8..f4ce7bdc6be1f 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-02-10 +date: 2024-02-11 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.mdx b/api_docs/kbn_management_settings_ids.mdx index 9f2c54cc5dc22..4cebc730312e5 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 3cd3348ddfa1f..47a54f4e2edea 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-02-10 +date: 2024-02-11 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 8f1c9745f4d20..d8d92acf7d23c 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-02-10 +date: 2024-02-11 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 b38258156ed37..738d31d553aaf 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-02-10 +date: 2024-02-11 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 668c94ab6f258..362f45842870e 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 97554495430d0..c7f4bb170ea58 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-02-10 +date: 2024-02-11 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 6198eac496a8e..50a22e56d429c 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-02-10 +date: 2024-02-11 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 7c6b7ebb9d338..b5c72a5e5b447 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-02-10 +date: 2024-02-11 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 c9b94b0b97af3..dea1fd7ea4674 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-02-10 +date: 2024-02-11 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 f268440bd46b9..7579b0721d13f 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-02-10 +date: 2024-02-11 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 c1084c844450b..1cddade4a1773 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-02-10 +date: 2024-02-11 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 159f2dbd176f8..ee713e714ab90 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-02-10 +date: 2024-02-11 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 5d3b339dffd75..b025dd21b2ce5 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-02-10 +date: 2024-02-11 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 e7f9428b214e8..542c5d25604a7 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-02-10 +date: 2024-02-11 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 e000cb82bc771..5658c23c67bc0 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-02-10 +date: 2024-02-11 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 9688805069f98..c1efb90693797 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-02-10 +date: 2024-02-11 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 d02f42eced206..596bb9801689d 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-02-10 +date: 2024-02-11 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_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 46a140c0520e9..ed864133bf9e7 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-02-10 +date: 2024-02-11 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 55ad680335d21..356a6f54ce0b0 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-02-10 +date: 2024-02-11 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 a8ffbc4bebbb5..a108e8f214116 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-02-10 +date: 2024-02-11 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 3b6ee11285fa3..85a7c41d8bc5b 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-02-10 +date: 2024-02-11 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 77fa8ae08cfba..23d8ebabf1a92 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-02-10 +date: 2024-02-11 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 59fd41f0dbcdb..64e7ed25eaaaa 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-02-10 +date: 2024-02-11 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 158bd60ffa7eb..9fbaeed2b4440 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index d2a6724c33f2a..f568f4c154d37 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-02-10 +date: 2024-02-11 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 2595c9db2e066..5b8e0aa395b5a 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-02-10 +date: 2024-02-11 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 1f631dfe493d7..541c59270faf0 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-02-10 +date: 2024-02-11 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 111bf54098d87..ea8b528abc18d 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-02-10 +date: 2024-02-11 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 189ec038c08da..73bcce60e8743 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index e0707814522cb..f2c3f09ba9e53 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-02-10 +date: 2024-02-11 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 968bf0d72211b..3da36a0186e79 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-02-10 +date: 2024-02-11 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 59ec3a3ef1969..94576f66e8f61 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 4215bb823eb35..8fb3c3c8015cb 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-02-10 +date: 2024-02-11 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 ddaa4905a318d..2bb9a466be433 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-02-10 +date: 2024-02-11 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 2e4f88186d4bd..13df55f6e809e 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 0abbf6a51f8de..9e97a3c54f074 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-02-10 +date: 2024-02-11 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_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index fe148199e70aa..a7d475f2b88a0 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-02-10 +date: 2024-02-11 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 87728b189ea5d..8e86483e02111 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-02-10 +date: 2024-02-11 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_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index d046ad1c93a8e..3c883b6c32834 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-02-10 +date: 2024-02-11 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 33bc02522f8d4..8181cba20d589 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-02-10 +date: 2024-02-11 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 09a96e2dfe0e4..1e9169f7951d9 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-02-10 +date: 2024-02-11 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 9bdbe18c0ae2e..d180cb75aaf73 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-02-10 +date: 2024-02-11 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 1f70b3342fc1e..f6cdc4023c1ac 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-02-10 +date: 2024-02-11 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 280819206e26f..7b843f4bc7ede 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-02-10 +date: 2024-02-11 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 90230c7906759..159b048637d13 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-02-10 +date: 2024-02-11 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 99c290f7234f4..f4f15f63189b8 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-02-10 +date: 2024-02-11 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 30f48800a0423..deb008aa21e44 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-02-10 +date: 2024-02-11 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 b6b18dee5978b..445692ba4dc04 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-02-10 +date: 2024-02-11 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 ebde4221eb0e4..f3e2878644969 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_library.mdx b/api_docs/kbn_presentation_library.mdx index 4a8c7460ae054..958c02b35996e 100644 --- a/api_docs/kbn_presentation_library.mdx +++ b/api_docs/kbn_presentation_library.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-library title: "@kbn/presentation-library" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-library plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-library'] --- import kbnPresentationLibraryObj from './kbn_presentation_library.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 5160067389323..71a1ea60e3f8f 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 797749b0e41e0..c1a03a92d7b75 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-02-10 +date: 2024-02-11 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 d7912433887f4..2840a4110c2da 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-02-10 +date: 2024-02-11 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 14381ae2eb47e..eec114bf0b6a3 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index f9c20e824c385..5eba525966cf8 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-02-10 +date: 2024-02-11 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 61e79a1fa9168..fea80285dd3a4 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-02-10 +date: 2024-02-11 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 91fefdd53e498..7a3635d4cf544 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-02-10 +date: 2024-02-11 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 777e948bd7c6e..0ffeb3e677282 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-02-10 +date: 2024-02-11 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 a9002ab027896..90bd0fea0152a 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-02-10 +date: 2024-02-11 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 b3c050c9138e5..c6feb7cbbab4c 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index e503bda96dd3b..aa6a2238db25e 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-02-10 +date: 2024-02-11 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 5b0eedc55e72f..0fab175c2d4fa 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-02-10 +date: 2024-02-11 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 36c36b2245870..e9cd4f7049895 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-02-10 +date: 2024-02-11 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 cf49d9ec19918..b77b0494755aa 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-02-10 +date: 2024-02-11 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 9e4262bf99042..630aff5e2cadf 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 08d740683e785..9b6fc11be12ab 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-02-10 +date: 2024-02-11 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 fefa6d5828c06..bce9115330ea7 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-02-10 +date: 2024-02-11 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 6601e65822069..b2e84b89ba455 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-02-10 +date: 2024-02-11 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 56345c7d7d4bd..8ef3498cfb734 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-02-10 +date: 2024-02-11 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 158f03dc2762d..aa0457602972d 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-02-10 +date: 2024-02-11 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 05475e832743e..2fe1010dd11c3 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-02-10 +date: 2024-02-11 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 5cab7969c027f..313ae7f17e449 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-02-10 +date: 2024-02-11 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 ee4523660b339..36b0439c77084 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-02-10 +date: 2024-02-11 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 ce4caba182d10..6774ad197b464 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-02-10 +date: 2024-02-11 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 baab6589fab12..5f99ba7ae1cdf 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 4085bc9e8e4bd..c2bdf4be9965e 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index bd3ae3ace1e7b..1ca59372b7570 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-02-10 +date: 2024-02-11 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 041c9a18773d4..4a89a559a333d 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-02-10 +date: 2024-02-11 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 62e9f6f6f4d7b..466e678fb1048 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-02-10 +date: 2024-02-11 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 43d77d6e0ba65..51970f6b0b36d 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 92ff4fae172f7..812b2c9ddff40 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-02-10 +date: 2024-02-11 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 7d79b235a9c15..13b78b12cb609 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-02-10 +date: 2024-02-11 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 3f0595f32ea9e..7ceca40db2598 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-02-10 +date: 2024-02-11 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 ea9763da09aba..561c8c72e933d 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-02-10 +date: 2024-02-11 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 3ae094a63f7d9..d3009463483c7 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index d88829625de28..506797a5eb4a9 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-02-10 +date: 2024-02-11 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 3733e78b32a0e..0eef6f558a0f1 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-02-10 +date: 2024-02-11 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 f79cef4b22730..bfab62e70c73b 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-02-10 +date: 2024-02-11 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 ee1355b181534..dde02a75ddaf1 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-02-10 +date: 2024-02-11 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_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 9209444c8a9e0..fe05c6a0be8f5 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-02-10 +date: 2024-02-11 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 7013b3c3fcd38..261c3fc9e4622 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-02-10 +date: 2024-02-11 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 74078a35b9d17..a613c8eb4b097 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-02-10 +date: 2024-02-11 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 19a947d642051..5a315439000d8 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 8c3c9ee7232aa..7f9929e578c73 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-02-10 +date: 2024-02-11 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 872dbee27ac58..b5460a5464635 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-02-10 +date: 2024-02-11 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 5465d86157cfa..3255522beb368 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-02-10 +date: 2024-02-11 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 0b3ed6e9a67fe..4cb64a68c12cc 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-02-10 +date: 2024-02-11 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 a518caf295db7..1ad8c772f997f 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 9d1794cad210c..7b4f711d98b3e 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index c25aa57cb5618..72d783a60ebb3 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-02-10 +date: 2024-02-11 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 5294c9188bc24..336fb7871b796 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-02-10 +date: 2024-02-11 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 af817aa9da5b8..a17263839c650 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-02-10 +date: 2024-02-11 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 fb1e7f50a2dda..c0f02740e526a 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-02-10 +date: 2024-02-11 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 6bbf503b4d610..027e459095fb3 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-02-10 +date: 2024-02-11 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 b963816eee64e..4f2edf63c5cf9 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-02-10 +date: 2024-02-11 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 b02395114d732..9127038eff14e 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-02-10 +date: 2024-02-11 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 f32368d1d08eb..2c3bd4c699ef8 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-02-10 +date: 2024-02-11 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 eebf6ef3ce518..1535b1b1aa3b5 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-02-10 +date: 2024-02-11 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 c32bdac640db3..8da99202288cd 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-02-10 +date: 2024-02-11 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 86188a30d22ec..88cd2aeeaa90c 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-02-10 +date: 2024-02-11 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 97957363f75d9..e665ea0714aab 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-02-10 +date: 2024-02-11 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 a6a1558db978e..f959688c30b7c 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-02-10 +date: 2024-02-11 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 285f274931ff2..0f539fa6d4ab0 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 0f2bcb534eb5e..e36d5bf39f909 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-02-10 +date: 2024-02-11 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 db28108c40f51..ff3264d63b9f9 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-02-10 +date: 2024-02-11 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 998be680fb299..88cb9fd90511e 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-02-10 +date: 2024-02-11 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 9da769f36cb4e..ed13dddb93a5a 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-02-10 +date: 2024-02-11 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 2e704e72a3674..2f3ece8f56243 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-02-10 +date: 2024-02-11 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 8c03522fa48e4..81df99584c63a 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-02-10 +date: 2024-02-11 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 08cb723d908e8..cb3665c849340 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-02-10 +date: 2024-02-11 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 942aa9a9d8cf8..abff430a0a630 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-02-10 +date: 2024-02-11 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 481e54346dd17..81a312e8cf7b9 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-02-10 +date: 2024-02-11 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 a43fe3947dce0..1a5b141aafb8d 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-02-10 +date: 2024-02-11 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 7108b7963db99..4e04df271d3ae 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-02-10 +date: 2024-02-11 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 783942c433702..fb37d8c016766 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-02-10 +date: 2024-02-11 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 72eaebb5b2a03..d3b5c89d90fac 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-02-10 +date: 2024-02-11 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 af8b68046204d..01c8269b37881 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-02-10 +date: 2024-02-11 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 780fe057c3cc2..4ae2078a45260 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-02-10 +date: 2024-02-11 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 a56aac2b72456..d7acdd1a0a802 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-02-10 +date: 2024-02-11 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 b2337293a5549..d482177449b87 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-02-10 +date: 2024-02-11 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 eefc69a2eab39..643f72eb9b24f 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-02-10 +date: 2024-02-11 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 024c046908c33..22cfdd1cf1be2 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-02-10 +date: 2024-02-11 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 9db12104e66cf..8f1dcf9e21600 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-02-10 +date: 2024-02-11 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 34cf453918145..b4c86dab78d98 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-02-10 +date: 2024-02-11 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 2b539369d561a..d015bb6a23a2a 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-02-10 +date: 2024-02-11 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 8e92d3fce205a..250e44b778b2e 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-02-10 +date: 2024-02-11 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 07b8df381c03c..f6ea9746f42ea 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-02-10 +date: 2024-02-11 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 7fcc99f13fef2..f2a07ae085402 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-02-10 +date: 2024-02-11 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 f3ac3591ff4a9..54e55ff7aaf33 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-02-10 +date: 2024-02-11 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 7391f0cf0d5d9..0283292e24095 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-02-10 +date: 2024-02-11 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 1713e0e61b08e..4d57a1ae152d3 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-02-10 +date: 2024-02-11 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 70a818437cc7d..9d8acab31cfd3 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-02-10 +date: 2024-02-11 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 ba0de8e44c895..db915ab0825d8 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-02-10 +date: 2024-02-11 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 9efaa97399fc5..69be404378479 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-02-10 +date: 2024-02-11 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 078091817add3..51f701d0a1036 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-02-10 +date: 2024-02-11 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 a7ec5a3edcbd2..f648075e9573f 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-02-10 +date: 2024-02-11 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 c211ae32e1183..9387f34bc8854 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-02-10 +date: 2024-02-11 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 b2b36c0424070..1ecdcea1d7d66 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-02-10 +date: 2024-02-11 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 381c7abe62f1a..217a3073eee20 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-02-10 +date: 2024-02-11 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 990af928cc8d4..eedb8df0dc46b 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-02-10 +date: 2024-02-11 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 7adb2fc25c589..c6605eb569e0d 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-02-10 +date: 2024-02-11 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 b942c8385b5f3..fb3d35caf17a8 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-02-10 +date: 2024-02-11 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 0d6f75c6469e6..7c3aa9753eabd 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-02-10 +date: 2024-02-11 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 f31c58311be68..dbe6c39e9ee15 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-02-10 +date: 2024-02-11 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 0d2a50f59170c..64b7837b5157d 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-02-10 +date: 2024-02-11 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 b906e60922db4..3ec3fe835b67e 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-02-10 +date: 2024-02-11 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 9dce5849c23e4..ebf3476e25460 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 3a6b988861051..fe135c4048e84 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-02-10 +date: 2024-02-11 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 ffc90e9830a0b..aa5491b851796 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-02-10 +date: 2024-02-11 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 906f0fd5b6a47..e789cc1b7fecc 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-02-10 +date: 2024-02-11 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 941a784e1512b..859e39b25f340 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index bdb53b2c1b290..2754684422913 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-02-10 +date: 2024-02-11 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 3c2ae61b11562..a7476ae8d9b90 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-02-10 +date: 2024-02-11 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 9b56d45a9f44c..19c4fdbd2d397 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 00c9119b0b4c5..1947e7918e4cc 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-02-10 +date: 2024-02-11 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 f0ef93fc76ebc..be7c0f3766bf4 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-02-10 +date: 2024-02-11 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 5af7b356ab439..bec6382834370 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-02-10 +date: 2024-02-11 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.mdx b/api_docs/kbn_test_jest_helpers.mdx index 9c2903d91f91c..13c65175c981d 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index d38c501ad593b..6090e47adad80 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 923893333dde2..9fe9558d87652 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 1b53de5031815..22417992b5116 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 14e0b3890f382..af17ece116d06 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index c5574a2ad15ad..0eb899f355fb1 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index db661be012636..23cd5501c5c27 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index a33dc1ce1c211..b09bcf180ed35 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 7103f3295b384..aaba877db9363 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index e08779f896105..7d2fa17c2c4b4 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 90e17a97cf6dc..166a3be4ea76f 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 186b6fe35aa5d..2f1d5c58f4a1f 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index f316be3a7e67a..e5427cb6f23cd 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index fd4d51478839d..7e846fa63f314 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 5098c4717034c..cdc2f63da4e58 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index a9da12a7d7ade..f94363c48eec7 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 61378fd987822..436a5392f8891 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index c88bab58de0aa..e516425a3766f 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index f531e9e46bc5c..eda0fef175a32 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index 2cec32430fd7c..d8b986a24231f 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index fb80422cdef1d..0ce36b3676703 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 2d7506371babc..dd0bb4725b965 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 39c91bea84533..d5628793560cb 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index cca8d7a7b53f2..600013a6725f2 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 60d04ffbdeffb..f80e198556f9d 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index ef399818d32b7..67c24dd346b48 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 823e51b002e3b..7c7453ed27ea5 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index e5f03b11acb4a..36708f7385b73 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 61da592cbf51f..c6fc743f9d2f9 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 5dce57f42059f..5deabea535da9 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 2f6b82142d973..910089ce81c35 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 8e387241f6294..18c6df14e999b 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index cd406d297c6d5..c1a05bc008f47 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 21eecce4ef28b..e64b3bf4774b1 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 99b565816fe0f..c7a50b424f715 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 25dee113085f5..567944d4d2010 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 8bc1438749f6f..aecaa7118d310 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index bfb31cac136d4..7bff19aea644c 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index de46206f3b573..3380e244d744f 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index dd046de2dcf8b..b78d550fcfdd8 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 6a539d7385f45..7f937dd4f5f15 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 6ee5b90743732..c93fb96aeb8cf 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 409307938f4d9..1234f9d291dca 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index dd4967ee01306..d4e44cb28d177 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 878e6606a410f..09afc9743e473 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index a8ad3b992dfa9..edb4f78ecc4b4 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 2fed2f2b9e810..b74fb4c80ba5c 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 542bc9020df70..aad70a736ba6d 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 8ab3d759c1ce2..39ea99294d42e 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-02-10 +date: 2024-02-11 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 75d3ed6478b61..d6cf4a495645c 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index a96733901b891..9f3d1076e58e6 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-02-10 +date: 2024-02-11 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 9fa9cbf2be36b..94409e8c94b9b 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-02-10 +date: 2024-02-11 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 f7c0d5fa37814..364fce65ffe2c 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-02-10 +date: 2024-02-11 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 d5aaea1b4e4f0..129f1950d07dc 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-02-10 +date: 2024-02-11 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 659cceb3a8920..b5bb1b7e213a8 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-02-10 +date: 2024-02-11 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 88deeddca3154..ce4a78efd494f 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index 3de25ffb3c752..9461fcb4e533d 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-02-10 +date: 2024-02-11 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 34e8f063a8b57..c076663692f30 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-02-10 +date: 2024-02-11 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 44b7623c4c95d..25fb5f1237e86 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-02-10 +date: 2024-02-11 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 42612160893a9..76361cf65c98e 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-02-10 +date: 2024-02-11 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 840c85d4f0e2a..1dd0fc4f5c001 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-02-10 +date: 2024-02-11 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 1a1eaa8131d57..54d9c13804a44 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-02-10 +date: 2024-02-11 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 2d9df35882149..4b27ac25c2dc4 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-02-10 +date: 2024-02-11 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 c23adbb20d60a..4b08037a65458 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-02-10 +date: 2024-02-11 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 b8b300d9eb4a3..a862d6d10ecd1 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-02-10 +date: 2024-02-11 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 6cc2eb929ca40..b0c1e9e8c32c6 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-02-10 +date: 2024-02-11 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 ecd23ecf1afc9..faf11db8230b6 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-02-10 +date: 2024-02-11 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 040152eaf31b4..42a1670c52345 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-02-10 +date: 2024-02-11 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 8bdda4b341bc9..0a65ea95e3363 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-02-10 +date: 2024-02-11 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 d5990f78ae086..becca0b609184 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-02-10 +date: 2024-02-11 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 8b0b2f4d09cc6..501abcdc7a1f4 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-02-10 +date: 2024-02-11 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 206586826633c..ecc2efc9eb95d 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-02-10 +date: 2024-02-11 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 4a943c90dea82..fb215f080197a 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 3b1bedb288c2b..8da4328b7693f 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-02-10 +date: 2024-02-11 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 3b666bcab3973..975edabe486d1 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-02-10 +date: 2024-02-11 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 27ed013a44264..495e4ac05416c 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-02-10 +date: 2024-02-11 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 0724e1fdbb2fd..268926586119b 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-02-10 +date: 2024-02-11 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 08473606f3a19..b86708a4cda3e 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-02-10 +date: 2024-02-11 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 e7ec542f369d4..79d61aa1c9eb9 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-02-10 +date: 2024-02-11 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 fb516421c5d51..0647271e3016b 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-02-10 +date: 2024-02-11 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 5a2607b183d78..0de3dd4712cc4 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-02-10 +date: 2024-02-11 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 f0198a49ddad1..079fbc27deb80 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 139fc75a8f530..96b65dd0772df 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-02-10 +date: 2024-02-11 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 bf7a1a6a20cdd..29e0aff597e29 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-02-10 +date: 2024-02-11 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 10e8d93c82c94..14dae824d8046 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-02-10 +date: 2024-02-11 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 54101814b7e73..c549c2b70bc05 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-02-10 +date: 2024-02-11 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 4385d61c626ac..d1016105fcacd 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-02-10 +date: 2024-02-11 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 328d643f6549e..d6a5aff049962 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-02-10 +date: 2024-02-11 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 30ad29655d566..e1511ffd12729 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 317cfc5bde49d..db2a40395132b 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 1e3f3728bc032..416ea7a6fb78b 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 5c60c4833efa2..8bd18a9ec990e 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2024-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 20c6c6b43dc66..330842f160ad5 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index 287fe4d5c5417..a79de6ce82d32 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -1527,6 +1527,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/utils.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field.tsx" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/threatmatch_input/index.tsx" diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 1b82b8daee696..ed3773d4c25a2 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-02-10 +date: 2024-02-11 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 8b72157191059..47127ab6ae9e8 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-02-10 +date: 2024-02-11 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 2fdc9240f070e..19b98a17d504f 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-02-10 +date: 2024-02-11 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 9649cc36041e8..7fa75e12030d4 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-02-10 +date: 2024-02-11 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 2881521f6bd06..ad83fbe9b1d0b 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-02-10 +date: 2024-02-11 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 cc82d27a1aaa8..6187e10618edf 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-02-10 +date: 2024-02-11 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 94f99b974c036..8a83db3c438a2 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-02-10 +date: 2024-02-11 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 e59a248ea056e..f3c78d7c262de 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-02-10 +date: 2024-02-11 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 a1daae2521bfc..257612b54d8cd 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-02-10 +date: 2024-02-11 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 bed22a65e33f2..2f60359a244be 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-02-10 +date: 2024-02-11 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 c2572a4825298..15e83c5a9b4b6 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-02-10 +date: 2024-02-11 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 6007be5852e9f..538ad01cb477c 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-02-10 +date: 2024-02-11 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 48974e7d35e7a..9574635e34dfc 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-02-10 +date: 2024-02-11 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 ed4ae1d4de3a1..2dfc19664235e 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-02-10 +date: 2024-02-11 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 2153b886e7695..53fba333ba810 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-02-10 +date: 2024-02-11 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 8dfc8327841cf..4ff167a4997d8 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-02-10 +date: 2024-02-11 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 aecf8c4e9d8c4..71b25a0e26a2b 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-02-10 +date: 2024-02-11 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 ec47b3b18ceaa..5e594c2320088 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-02-10 +date: 2024-02-11 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 c6b5c813939b0..f1a0d56ff2c32 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-02-10 +date: 2024-02-11 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 002791afc1129..f9993b7e007c8 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-02-10 +date: 2024-02-11 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 334f172fe0a94..c79330542aff8 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-02-10 +date: 2024-02-11 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 b122ca0b04143..07a81891983b4 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-02-10 +date: 2024-02-11 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 e9a232aada676..a0e4b49c51133 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 38f0691c9aa17..a16dab9206ed5 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-02-10 +date: 2024-02-11 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 955dd69df3f96800a1c082aada6ef76581069738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= <soren.louv@elastic.co> Date: Mon, 12 Feb 2024 00:38:59 +0100 Subject: [PATCH 103/104] [Obs AI Assistant] Simplify routing (#176569) Minor simplification to how we link into the conversation app --- .../public/components/chat/chat_header.tsx | 4 +- .../use_observability_ai_assistant_router.ts | 40 ++----------------- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx index de8a80928207b..0dc37c7829482 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_header.tsx @@ -73,14 +73,14 @@ export function ChatHeader({ const handleNavigateToConversations = () => { if (conversationId) { - router.navigateToConversationsApp('/conversations/{conversationId}', { + router.push('/conversations/{conversationId}', { path: { conversationId, }, query: {}, }); } else { - router.navigateToConversationsApp('/conversations/new', { path: {}, query: {} }); + router.push('/conversations/new', { path: {}, query: {} }); } }; diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts index afdae21c91a8d..16e27d1f8505a 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant_router.ts @@ -7,7 +7,6 @@ import { PathsOf, TypeAsArgs, TypeOf } from '@kbn/typed-react-router-config'; import { useMemo } from 'react'; -import { useHistory } from 'react-router-dom'; import { ObservabilityAIAssistantRouter, ObservabilityAIAssistantRoutes } from '../routes/config'; import { observabilityAIAssistantRouter } from '../routes/config'; import { useKibana } from './use_kibana'; @@ -21,15 +20,9 @@ interface StatefulObservabilityAIAssistantRouter extends ObservabilityAIAssistan path: T, ...params: TypeAsArgs<TypeOf<ObservabilityAIAssistantRoutes, T>> ): void; - navigateToConversationsApp<T extends PathsOf<ObservabilityAIAssistantRoutes>>( - path: T, - ...params: TypeAsArgs<TypeOf<ObservabilityAIAssistantRoutes, T>> - ): void; } export function useObservabilityAIAssistantRouter(): StatefulObservabilityAIAssistantRouter { - const history = useHistory(); - const { services: { http, @@ -47,43 +40,16 @@ export function useObservabilityAIAssistantRouter(): StatefulObservabilityAIAssi ...observabilityAIAssistantRouter, push: (...args) => { const next = link(...args); - - history.push(next); - }, - navigateToConversationsApp: (path, ...args) => { - const [_, route, routeParam] = path.split('/'); - - const sanitized = routeParam.replace('{', '').replace('}', ''); - - const pathKey = args[0]?.path; - - if (typeof pathKey !== 'object') { - return; - } - - if (Object.keys(pathKey).length === 0) { - navigateToApp('observabilityAIAssistant', { - path: route, - }); - return; - } - - if (Object.keys(pathKey).length === 1) { - navigateToApp('observabilityAIAssistant', { - // @ts-expect-error - path: `${route}/${pathKey[sanitized]}`, - }); - return; - } + navigateToApp('observabilityAIAssistant', { path: next, replace: false }); }, replace: (path, ...args) => { const next = link(path, ...args); - history.replace(next); + navigateToApp('observabilityAIAssistant', { path: next, replace: true }); }, link: (path, ...args) => { return http.basePath.prepend('/app/observabilityAIAssistant' + link(path, ...args)); }, }), - [history, navigateToApp, http.basePath] + [navigateToApp, http.basePath] ); } From 7a5fcc9cb35491c407475c82508cea4138cb9c85 Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Sun, 11 Feb 2024 20:19:54 -0800 Subject: [PATCH 104/104] [RAM] Add modal when disabling rule to prompt user to untrack alerts (#175363) ## Summary Adds a modal to all of the stack management disable flows to ask the user if they want to untrack orphaned alerts - Rules list -> bulk disable - Rules list -> State dropdown - Rules list -> Action items dropdown - Rule details ### To Test 1. Navigate to rules list or rule details 2. Try to create a rule that generate alerts 3. Disable the rule, use the modal to determine if the alerts should be untracked 4. Check the alerts to see if they were untracked or still tracked (depending on step 3) ![image](https://github.com/elastic/kibana/assets/74562234/1d980f51-d243-4742-b856-12a58369c0f9) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co> --- .../rule/apis/bulk_disable/schemas/v1.ts | 1 + .../bulk_disable/bulk_disable_rules.test.ts | 129 +++++---- .../bulk_disable/bulk_disable_rules.ts | 16 +- .../methods/bulk_disable/schemas/index.ts | 1 + .../server/routes/disable_rule.test.ts | 1 + .../alerting/server/routes/disable_rule.ts | 12 +- .../bulk_disable/bulk_disable_rules_route.ts | 4 +- .../server/rules_client/methods/disable.ts | 28 +- .../server/rules_client/rules_client.ts | 2 +- .../server/rules_client/tests/disable.test.ts | 53 +++- .../application/lib/rule_api/bulk_disable.ts | 6 +- .../components/rule_quick_edit_buttons.tsx | 262 ++++++++++-------- .../components/untrack_alerts_modal.test.tsx | 53 ++++ .../components/untrack_alerts_modal.tsx | 72 +++++ .../with_bulk_rule_api_operations.test.tsx | 13 +- .../with_bulk_rule_api_operations.tsx | 5 +- .../components/rule_details.test.tsx | 10 +- .../rule_details/components/rule_details.tsx | 42 ++- .../components/rule_status_panel.test.tsx | 107 +++---- .../components/rule_status_panel.tsx | 9 +- .../collapsed_item_actions.test.tsx | 11 +- .../components/collapsed_item_actions.tsx | 90 ++++-- .../components/rule_status_dropdown.tsx | 145 ++++++---- .../rules_list/components/rules_list.tsx | 10 +- .../rules_list_bulk_disable.test.tsx | 50 +++- .../components/rules_list_table.tsx | 13 +- .../triggers_actions_ui/public/types.ts | 8 + .../common/lib/alert_utils.ts | 7 +- .../tests/alerting/group1/disable.ts | 63 ++++- .../tests/alerting/group4/bulk_disable.ts | 130 +++++++++ .../tests/alerting/group4/index.ts | 1 + .../apps/triggers_actions_ui/details.ts | 3 + .../rules_list/rules_list.ts | 121 +++++++- .../apps/observability/pages/rules_page.ts | 4 + .../observability/rules/rules_list.ts | 8 + 35 files changed, 1100 insertions(+), 390 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.tsx create mode 100644 x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/bulk_disable.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_disable/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_disable/schemas/v1.ts index 3e74ed88ff0f8..41a727b8b19b6 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_disable/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_disable/schemas/v1.ts @@ -10,4 +10,5 @@ import { schema } from '@kbn/config-schema'; export const bulkDisableRulesRequestBodySchema = schema.object({ filter: schema.maybe(schema.string()), ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), + untrack: schema.maybe(schema.boolean({ defaultValue: false })), }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.test.ts index 81a8466e23a22..3f43d6077eb35 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.test.ts @@ -41,14 +41,6 @@ import { import { migrateLegacyActions } from '../../../../rules_client/lib'; import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; -jest.mock('../../../../task_runner/alert_task_instance', () => ({ - taskInstanceToAlertTaskInstance: jest.fn(), -})); - -const { taskInstanceToAlertTaskInstance } = jest.requireMock( - '../../../../task_runner/alert_task_instance' -); - jest.mock('../../../../rules_client/lib/siem_legacy_actions/migrate_legacy_actions', () => { return { migrateLegacyActions: jest.fn().mockResolvedValue({ @@ -63,6 +55,12 @@ jest.mock('../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invali bulkMarkApiKeysForInvalidation: jest.fn(), })); +jest.mock('../../../../rules_client/lib/untrack_rule_alerts', () => ({ + untrackRuleAlerts: jest.fn(), +})); + +const { untrackRuleAlerts } = jest.requireMock('../../../../rules_client/lib/untrack_rule_alerts'); + const taskManager = taskManagerMock.createStart(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); @@ -192,6 +190,76 @@ describe('bulkDisableRules', () => { }); }); + test('should call untrack alert if untrack is true', async () => { + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ + saved_objects: [disabledRuleForBulkDisable1, disabledRuleForBulkDisable2], + }); + + const result = await rulesClient.bulkDisableRules({ filter: 'fake_filter', untrack: true }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ + id: 'id1', + attributes: expect.objectContaining({ + enabled: false, + }), + }), + expect.objectContaining({ + id: 'id2', + attributes: expect.objectContaining({ + enabled: false, + }), + }), + ]), + { overwrite: true } + ); + + expect(result).toStrictEqual({ + errors: [], + rules: [returnedRuleForBulkDisable1, returnedRuleForBulkDisable2], + total: 2, + }); + + expect(untrackRuleAlerts).toHaveBeenCalled(); + }); + + test('should not call untrack alert if untrack is false', async () => { + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ + saved_objects: [disabledRuleForBulkDisable1, disabledRuleForBulkDisable2], + }); + + const result = await rulesClient.bulkDisableRules({ filter: 'fake_filter', untrack: true }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ + id: 'id1', + attributes: expect.objectContaining({ + enabled: false, + }), + }), + expect.objectContaining({ + id: 'id2', + attributes: expect.objectContaining({ + enabled: false, + }), + }), + ]), + { overwrite: true } + ); + + expect(result).toStrictEqual({ + errors: [], + rules: [returnedRuleForBulkDisable1, returnedRuleForBulkDisable2], + total: 2, + }); + + expect(untrackRuleAlerts).toHaveBeenCalled(); + }); + test('should try to disable rules, one successful and one with 500 error', async () => { unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ saved_objects: [disabledRuleForBulkDisable1, savedObjectWith500Error], @@ -585,51 +653,6 @@ describe('bulkDisableRules', () => { }); }); - describe('recoverRuleAlerts', () => { - beforeEach(() => { - taskInstanceToAlertTaskInstance.mockImplementation(() => ({ - state: { - alertInstances: { - '1': { - meta: { - lastScheduledActions: { - group: 'default', - date: new Date().toISOString(), - }, - }, - state: { bar: false }, - }, - }, - }, - })); - }); - test('should call logEvent', async () => { - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ - saved_objects: [disabledRuleForBulkDisable1, disabledRuleForBulkDisable2], - }); - - await rulesClient.bulkDisableRules({ filter: 'fake_filter' }); - - expect(eventLogger.logEvent).toHaveBeenCalledTimes(2); - }); - - test('should call logger.warn', async () => { - eventLogger.logEvent.mockImplementation(() => { - throw new Error('UPS'); - }); - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ - saved_objects: [disabledRuleForBulkDisable1, disabledRuleForBulkDisable2], - }); - - await rulesClient.bulkDisableRules({ filter: 'fake_filter' }); - - expect(logger.warn).toHaveBeenCalledTimes(2); - expect(logger.warn).toHaveBeenLastCalledWith( - "rulesClient.disable('id2') - Could not write untrack events - UPS" - ); - }); - }); - describe('legacy actions migration for SIEM', () => { test('should call migrateLegacyActions', async () => { encryptedSavedObjects.createPointInTimeFinderDecryptedAsInternalUser = jest diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.ts index 0ac84ce2ef6d7..84229c4dc665e 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/bulk_disable_rules.ts @@ -50,7 +50,7 @@ export const bulkDisableRules = async <Params extends RuleParams>( throw Boom.badRequest(`Error validating bulk disable data - ${error.message}`); } - const { ids, filter } = options; + const { ids, filter, untrack = false } = options; const kueryNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : buildKueryNodeFilter(filter); const authorizationFilter = await getAuthorizationFilter(context, { action: 'DISABLE' }); @@ -72,7 +72,7 @@ export const bulkDisableRules = async <Params extends RuleParams>( action: 'DISABLE', logger: context.logger, bulkOperation: (filterKueryNode: KueryNode | null) => - bulkDisableRulesWithOCC(context, { filter: filterKueryNode }), + bulkDisableRulesWithOCC(context, { filter: filterKueryNode, untrack }), filter: kueryNodeFilterWithAuth, }) ); @@ -120,7 +120,13 @@ export const bulkDisableRules = async <Params extends RuleParams>( const bulkDisableRulesWithOCC = async ( context: RulesClientContext, - { filter }: { filter: KueryNode | null } + { + filter, + untrack = false, + }: { + filter: KueryNode | null; + untrack: boolean; + } ) => { const additionalFilter = nodeBuilder.is('alert.attributes.enabled', 'true'); @@ -151,7 +157,9 @@ const bulkDisableRulesWithOCC = async ( for await (const response of rulesFinder.find()) { await pMap(response.saved_objects, async (rule) => { try { - await untrackRuleAlerts(context, rule.id, rule.attributes); + if (untrack) { + await untrackRuleAlerts(context, rule.id, rule.attributes); + } if (rule.attributes.name) { ruleNameToRuleIdMapping[rule.id] = rule.attributes.name; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/schemas/index.ts index 3e74ed88ff0f8..41a727b8b19b6 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/schemas/index.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_disable/schemas/index.ts @@ -10,4 +10,5 @@ import { schema } from '@kbn/config-schema'; export const bulkDisableRulesRequestBodySchema = schema.object({ filter: schema.maybe(schema.string()), ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), + untrack: schema.maybe(schema.boolean({ defaultValue: false })), }); diff --git a/x-pack/plugins/alerting/server/routes/disable_rule.test.ts b/x-pack/plugins/alerting/server/routes/disable_rule.test.ts index 6f4806b8e17f5..6186fbd8a5db7 100644 --- a/x-pack/plugins/alerting/server/routes/disable_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/disable_rule.test.ts @@ -52,6 +52,7 @@ describe('disableRuleRoute', () => { Array [ Object { "id": "1", + "untrack": false, }, ] `); diff --git a/x-pack/plugins/alerting/server/routes/disable_rule.ts b/x-pack/plugins/alerting/server/routes/disable_rule.ts index 99795e7ee2bf2..726b080bedbf1 100644 --- a/x-pack/plugins/alerting/server/routes/disable_rule.ts +++ b/x-pack/plugins/alerting/server/routes/disable_rule.ts @@ -15,6 +15,14 @@ const paramSchema = schema.object({ id: schema.string(), }); +const bodySchema = schema.nullable( + schema.maybe( + schema.object({ + untrack: schema.maybe(schema.boolean({ defaultValue: false })), + }) + ) +); + export const disableRuleRoute = ( router: IRouter<AlertingRequestHandlerContext>, licenseState: ILicenseState @@ -24,14 +32,16 @@ export const disableRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_disable`, validate: { params: paramSchema, + body: bodySchema, }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; + const { untrack = false } = req.body || {}; try { - await rulesClient.disable({ id }); + await rulesClient.disable({ id, untrack }); return res.noContent(); } catch (e) { if (e instanceof RuleTypeDisabledError) { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts index 03afb4a95d25a..39b81ee74fe91 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts @@ -39,10 +39,10 @@ export const bulkDisableRulesRoute = ({ const rulesClient = (await context.alerting).getRulesClient(); const body: BulkDisableRulesRequestBodyV1 = req.body; - const { filter, ids } = body; + const { filter, ids, untrack } = body; try { - const bulkDisableResults = await rulesClient.bulkDisableRules({ filter, ids }); + const bulkDisableResults = await rulesClient.bulkDisableRules({ filter, ids, untrack }); const resultBody: BulkDisableRulesResponseV1<RuleParamsV1> = { body: { diff --git a/x-pack/plugins/alerting/server/rules_client/methods/disable.ts b/x-pack/plugins/alerting/server/rules_client/methods/disable.ts index 38b0dcc7e17d6..88396559031c8 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/disable.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/disable.ts @@ -15,15 +15,33 @@ import { untrackRuleAlerts, updateMeta, migrateLegacyActions } from '../lib'; import { RuleAttributes } from '../../data/rule/types'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; -export async function disable(context: RulesClientContext, { id }: { id: string }): Promise<void> { +export async function disable( + context: RulesClientContext, + { + id, + untrack = false, + }: { + id: string; + untrack?: boolean; + } +): Promise<void> { return await retryIfConflicts( context.logger, `rulesClient.disable('${id}')`, - async () => await disableWithOCC(context, { id }) + async () => await disableWithOCC(context, { id, untrack }) ); } -async function disableWithOCC(context: RulesClientContext, { id }: { id: string }) { +async function disableWithOCC( + context: RulesClientContext, + { + id, + untrack = false, + }: { + id: string; + untrack?: boolean; + } +) { let attributes: RawRule; let version: string | undefined; let references: SavedObjectReference[]; @@ -70,7 +88,9 @@ async function disableWithOCC(context: RulesClientContext, { id }: { id: string throw error; } - await untrackRuleAlerts(context, id, attributes as RuleAttributes); + if (untrack) { + await untrackRuleAlerts(context, id, attributes as RuleAttributes); + } context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 0a2da42d7e424..39b4353525f7e 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -160,7 +160,7 @@ export class RulesClient { public updateApiKey = (options: { id: string }) => updateApiKey(this.context, options); public enable = (options: { id: string }) => enable(this.context, options); - public disable = (options: { id: string }) => disable(this.context, options); + public disable = (options: { id: string; untrack?: boolean }) => disable(this.context, options); public snooze = (options: SnoozeRuleOptions) => snoozeRule(this.context, options); public unsnooze = (options: UnsnoozeParams) => unsnoozeRule(this.context, options); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/disable.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/disable.test.ts index 4f539f5a9f7b1..9e7073da8a18d 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/disable.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/disable.test.ts @@ -299,7 +299,7 @@ describe('disable()', () => { }, ownerId: null, }); - await rulesClient.disable({ id: '1' }); + await rulesClient.disable({ id: '1', untrack: true }); expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith( RULE_SAVED_OBJECT_TYPE, @@ -388,7 +388,7 @@ describe('disable()', () => { test('disables the rule even if unable to retrieve task manager doc to generate untrack event log events', async () => { taskManager.get.mockRejectedValueOnce(new Error('Fail')); - await rulesClient.disable({ id: '1' }); + await rulesClient.disable({ id: '1', untrack: true }); expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith( RULE_SAVED_OBJECT_TYPE, @@ -440,6 +440,55 @@ describe('disable()', () => { ); }); + test('should not untrack rule alert if untrack is false', async () => { + await rulesClient.disable({ id: '1', untrack: false }); + expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); + expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith( + RULE_SAVED_OBJECT_TYPE, + '1', + { + namespace: 'default', + } + ); + expect(unsecuredSavedObjectsClient.update).toHaveBeenCalledWith( + RULE_SAVED_OBJECT_TYPE, + '1', + { + consumer: 'myApp', + schedule: { interval: '10s' }, + alertTypeId: 'myType', + enabled: false, + meta: { + versionApiKeyLastmodified: 'v7.10.0', + }, + revision: 0, + scheduledTaskId: '1', + apiKey: 'MTIzOmFiYw==', + apiKeyOwner: 'elastic', + updatedAt: '2019-02-12T21:01:22.479Z', + updatedBy: 'elastic', + actions: [ + { + group: 'default', + id: '1', + actionTypeId: '1', + actionRef: '1', + params: { + foo: true, + }, + }, + ], + nextRun: null, + }, + { + version: '123', + } + ); + expect(taskManager.bulkDisable).toHaveBeenCalledWith(['1'], false); + expect(taskManager.get).not.toHaveBeenCalled(); + expect(taskManager.removeIfExists).not.toHaveBeenCalled(); + }); + test('falls back when getDecryptedAsInternalUser throws an error', async () => { encryptedSavedObjects.getDecryptedAsInternalUser.mockRejectedValueOnce(new Error('Fail')); await rulesClient.disable({ id: '1' }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/bulk_disable.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/bulk_disable.ts index 4e322d494d7df..437d2ae016293 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/bulk_disable.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/bulk_disable.ts @@ -5,16 +5,18 @@ * 2.0. */ import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; -import { BulkOperationResponse, BulkOperationAttributes } from '../../../types'; +import { BulkOperationResponse, BulkDisableParams } from '../../../types'; export const bulkDisableRules = async ({ filter, ids, http, -}: BulkOperationAttributes): Promise<BulkOperationResponse> => { + untrack, +}: BulkDisableParams): Promise<BulkOperationResponse> => { try { const body = JSON.stringify({ ids: ids?.length ? ids : undefined, + untrack, ...(filter ? { filter: JSON.stringify(filter) } : {}), }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx index fa7fe6bae44d5..9327733f3b5ef 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { KueryNode } from '@kbn/es-query'; -import React, { useMemo } from 'react'; +import React, { useMemo, useCallback, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiButtonEmpty, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; @@ -18,6 +18,7 @@ import { } from './with_bulk_rule_api_operations'; import './rule_quick_edit_buttons.scss'; import { useKibana } from '../../../../common/lib/kibana'; +import { UntrackAlertsModal } from './untrack_alerts_modal'; export type ComponentOpts = { selectedItems: RuleTableItem[]; @@ -29,7 +30,7 @@ export type ComponentOpts = { isEnablingRules?: boolean; isDisablingRules?: boolean; isBulkEditing?: boolean; - onDisable: () => Promise<void>; + onDisable: (untrack: boolean) => Promise<void>; onEnable: () => Promise<void>; updateRulesToBulkEdit: (props: UpdateRulesToBulkEditProps) => void; } & BulkOperationsComponentOpts; @@ -52,6 +53,8 @@ export const RuleQuickEditButtons: React.FunctionComponent<ComponentOpts> = ({ notifications: { toasts }, } = useKibana().services; + const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false); + const isPerformingAction = isEnablingRules || isDisablingRules || isBulkEditing; const hasDisabledByLicenseRuleTypes = useMemo(() => { @@ -229,125 +232,146 @@ export const RuleQuickEditButtons: React.FunctionComponent<ComponentOpts> = ({ } } + const onDisableClick = useCallback(() => { + setIsUntrackAlertsModalOpen(true); + }, []); + + const onModalClose = useCallback(() => { + setIsUntrackAlertsModalOpen(false); + }, []); + + const onModalConfirm = useCallback( + (untrack: boolean) => { + onModalClose(); + onDisable(untrack); + }, + [onModalClose, onDisable] + ); + return ( - <EuiFlexGroup - alignItems="baseline" - direction="column" - gutterSize="none" - data-test-subj="ruleQuickEditButton" - > - {!isAllSelected && ( - <> - <EuiFlexItem> - <EuiButtonEmpty - onClick={onSnoozeAllClick} - isLoading={isBulkEditing && bulkEditAction === 'snooze'} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkSnooze" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.snoozeAllTitle" - defaultMessage="Snooze now" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={onUnsnoozeAllClick} - isLoading={isBulkEditing && bulkEditAction === 'unsnooze'} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkUnsnooze" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.unsnoozeAllTitle" - defaultMessage="Unsnooze now" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={onScheduleAllClick} - isLoading={isBulkEditing && bulkEditAction === 'schedule'} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkSnoozeSchedule" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.snoozeScheduleAllTitle" - defaultMessage="Schedule snooze" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={onUnscheduleAllClick} - isLoading={isBulkEditing && bulkEditAction === 'unschedule'} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkRemoveSnoozeSchedule" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.removeSnoozeScheduleAllTitle" - defaultMessage="Unschedule snooze" - /> - </EuiButtonEmpty> - </EuiFlexItem> - </> + <> + <EuiFlexGroup + alignItems="baseline" + direction="column" + gutterSize="none" + data-test-subj="ruleQuickEditButton" + > + {!isAllSelected && ( + <> + <EuiFlexItem> + <EuiButtonEmpty + onClick={onSnoozeAllClick} + isLoading={isBulkEditing && bulkEditAction === 'snooze'} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkSnooze" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.snoozeAllTitle" + defaultMessage="Snooze now" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={onUnsnoozeAllClick} + isLoading={isBulkEditing && bulkEditAction === 'unsnooze'} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkUnsnooze" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.unsnoozeAllTitle" + defaultMessage="Unsnooze now" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={onScheduleAllClick} + isLoading={isBulkEditing && bulkEditAction === 'schedule'} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkSnoozeSchedule" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.snoozeScheduleAllTitle" + defaultMessage="Schedule snooze" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={onUnscheduleAllClick} + isLoading={isBulkEditing && bulkEditAction === 'unschedule'} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkRemoveSnoozeSchedule" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.removeSnoozeScheduleAllTitle" + defaultMessage="Unschedule snooze" + /> + </EuiButtonEmpty> + </EuiFlexItem> + </> + )} + <EuiFlexItem> + <EuiButtonEmpty + onClick={onEnable} + isLoading={isEnablingRules} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkEnable" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.enableAllTitle" + defaultMessage="Enable" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={onDisableClick} + isLoading={isDisablingRules} + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkDisable" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.disableAllTitle" + defaultMessage="Disable" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={updateAPIKeysClick} + isLoading={isBulkEditing && bulkEditAction === 'updateApiKey'} + isDisabled={isPerformingAction} + data-test-subj="updateAPIKeys" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.updateRuleAPIKeysTitle" + defaultMessage="Update API keys" + /> + </EuiButtonEmpty> + </EuiFlexItem> + <EuiFlexItem> + <EuiButtonEmpty + onClick={deleteSelectedItems} + isLoading={isBulkEditing && bulkEditAction === 'delete'} + iconType="trash" + color="danger" + isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} + data-test-subj="bulkDelete" + className="actBulkActionPopover__deleteAll" + > + <FormattedMessage + id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.deleteAllTitle" + defaultMessage="Delete" + /> + </EuiButtonEmpty> + </EuiFlexItem> + </EuiFlexGroup> + {isUntrackAlertsModalOpen && ( + <UntrackAlertsModal onConfirm={onModalConfirm} onCancel={onModalClose} /> )} - <EuiFlexItem> - <EuiButtonEmpty - onClick={onEnable} - isLoading={isEnablingRules} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkEnable" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.enableAllTitle" - defaultMessage="Enable" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={onDisable} - isLoading={isDisablingRules} - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkDisable" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.disableAllTitle" - defaultMessage="Disable" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={updateAPIKeysClick} - isLoading={isBulkEditing && bulkEditAction === 'updateApiKey'} - isDisabled={isPerformingAction} - data-test-subj="updateAPIKeys" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.updateRuleAPIKeysTitle" - defaultMessage="Update API keys" - /> - </EuiButtonEmpty> - </EuiFlexItem> - <EuiFlexItem> - <EuiButtonEmpty - onClick={deleteSelectedItems} - isLoading={isBulkEditing && bulkEditAction === 'delete'} - iconType="trash" - color="danger" - isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes} - data-test-subj="bulkDelete" - className="actBulkActionPopover__deleteAll" - > - <FormattedMessage - id="xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.deleteAllTitle" - defaultMessage="Delete" - /> - </EuiButtonEmpty> - </EuiFlexItem> - </EuiFlexGroup> + </> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.test.tsx new file mode 100644 index 0000000000000..78d06175c580c --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.test.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; + +import { UntrackAlertsModal } from './untrack_alerts_modal'; + +const onConfirmMock = jest.fn(); + +const onCancelMock = jest.fn(); + +describe('Untrack alerts modal', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render correctly', () => { + render(<UntrackAlertsModal onCancel={onCancelMock} onConfirm={onConfirmMock} />); + + expect(screen.getByTestId('untrackAlertsModal')).toBeInTheDocument(); + }); + + it('should track alerts', () => { + render(<UntrackAlertsModal onCancel={onCancelMock} onConfirm={onConfirmMock} />); + + fireEvent.click(screen.getByTestId('untrackAlertsModalSwitch')); + + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + expect(onConfirmMock).toHaveBeenCalledWith(true); + }); + + it('should untrack alerts', () => { + render(<UntrackAlertsModal onCancel={onCancelMock} onConfirm={onConfirmMock} />); + + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + expect(onConfirmMock).toHaveBeenCalledWith(false); + }); + + it('should close if cancel is clicked', () => { + render(<UntrackAlertsModal onCancel={onCancelMock} onConfirm={onConfirmMock} />); + + fireEvent.click(screen.getByTestId('confirmModalCancelButton')); + + expect(onCancelMock).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.tsx new file mode 100644 index 0000000000000..f3ad676e5fc21 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/untrack_alerts_modal.tsx @@ -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. + */ + +import React, { useState, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiConfirmModal, EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; + +const UNTRACK_ORPHANED_ALERTS_TITLE = i18n.translate( + 'xpack.triggersActionsUI.sections.untrackAlertsModal.title', + { + defaultMessage: 'Disable rule', + } +); + +const UNTRACK_ORPHANED_ALERTS_CONFIRM_BUTTON_TEXT = i18n.translate( + 'xpack.triggersActionsUI.sections.untrackAlertsModal.confirmButtonText', + { + defaultMessage: 'Disable rule', + } +); + +const UNTRACK_ORPHANED_ALERTS_CANCEL_BUTTON_TEXT = i18n.translate( + 'xpack.triggersActionsUI.sections.untrackAlertsModal.cancelButtonText', + { + defaultMessage: 'cancel', + } +); + +const UNTRACK_ORPHANED_ALERTS_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.untrackAlertsModal.toggleLabel', + { + defaultMessage: + 'When disabling, all alerts related to this rule will be updated to "Untracked"', + } +); + +export interface UntrackAlertsModalProps { + onCancel: () => void; + onConfirm: (untrack: boolean) => void; +} + +export const UntrackAlertsModal = (props: UntrackAlertsModalProps) => { + const { onCancel, onConfirm } = props; + + const [isUntrack, setIsUntrack] = useState<boolean>(false); + + const onChange = useCallback((e: EuiSwitchEvent) => { + setIsUntrack(e.target.checked); + }, []); + + return ( + <EuiConfirmModal + data-test-subj="untrackAlertsModal" + title={UNTRACK_ORPHANED_ALERTS_TITLE} + onCancel={onCancel} + onConfirm={() => onConfirm(isUntrack)} + confirmButtonText={UNTRACK_ORPHANED_ALERTS_CONFIRM_BUTTON_TEXT} + cancelButtonText={UNTRACK_ORPHANED_ALERTS_CANCEL_BUTTON_TEXT} + > + <EuiSwitch + data-test-subj="untrackAlertsModalSwitch" + label={UNTRACK_ORPHANED_ALERTS_LABEL} + checked={isUntrack} + onChange={onChange} + /> + </EuiConfirmModal> + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.test.tsx index 4fba7e7027d8c..5a283ff60ec72 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.test.tsx @@ -139,7 +139,11 @@ describe('with_bulk_rule_api_operations', () => { it('disableRule calls the disableRule api', () => { const { http } = useKibanaMock().services; const ComponentToExtend = ({ bulkDisableRules, rule }: ComponentOpts & { rule: Rule }) => { - return <button onClick={() => bulkDisableRules({ ids: [rule.id] })}>{'call api'}</button>; + return ( + <button onClick={() => bulkDisableRules({ ids: [rule.id], untrack: true })}> + {'call api'} + </button> + ); }; const ExtendedComponent = withBulkRuleOperations(ComponentToExtend); @@ -148,7 +152,7 @@ describe('with_bulk_rule_api_operations', () => { component.find('button').simulate('click'); expect(bulkDisableRules).toHaveBeenCalledTimes(1); - expect(bulkDisableRules).toHaveBeenCalledWith({ ids: [rule.id], http }); + expect(bulkDisableRules).toHaveBeenCalledWith({ ids: [rule.id], http, untrack: true }); }); // bulk rules @@ -212,7 +216,9 @@ describe('with_bulk_rule_api_operations', () => { const { http } = useKibanaMock().services; const ComponentToExtend = ({ bulkDisableRules, rules }: ComponentOpts & { rules: Rule[] }) => { return ( - <button onClick={() => bulkDisableRules({ ids: rules.map((rule) => rule.id) })}> + <button + onClick={() => bulkDisableRules({ ids: rules.map((rule) => rule.id), untrack: true })} + > {'call api'} </button> ); @@ -227,6 +233,7 @@ describe('with_bulk_rule_api_operations', () => { expect(bulkDisableRules).toHaveBeenCalledWith({ ids: [rules[0].id, rules[1].id], http, + untrack: true, }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.tsx index ecb431ad3ba93..81a4f27ef5e1c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/with_bulk_rule_api_operations.tsx @@ -23,6 +23,7 @@ import { BulkEditResponse, BulkOperationResponse, BulkOperationAttributesWithoutHttp, + BulkDisableParamsWithoutHttp, } from '../../../../types'; import type { LoadExecutionLogAggregationsProps, @@ -92,7 +93,7 @@ export interface ComponentOpts { cloneRule: (ruleId: string) => Promise<Rule>; bulkDeleteRules: (props: BulkOperationAttributesWithoutHttp) => Promise<BulkOperationResponse>; bulkEnableRules: (props: BulkOperationAttributesWithoutHttp) => Promise<BulkOperationResponse>; - bulkDisableRules: (props: BulkOperationAttributesWithoutHttp) => Promise<BulkOperationResponse>; + bulkDisableRules: (props: BulkDisableParamsWithoutHttp) => Promise<BulkOperationResponse>; } export type PropsWithOptionalApiHandlers<T> = Omit<T, keyof ComponentOpts> & Partial<ComponentOpts>; @@ -199,7 +200,7 @@ export function withBulkRuleOperations<T>( bulkEnableRules={async (bulkEnableProps: BulkOperationAttributesWithoutHttp) => { return await bulkEnableRules({ http, ...bulkEnableProps }); }} - bulkDisableRules={async (bulkDisableProps: BulkOperationAttributesWithoutHttp) => { + bulkDisableRules={async (bulkDisableProps: BulkDisableParamsWithoutHttp) => { return await bulkDisableRules({ http, ...bulkDisableProps }); }} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx index 3bd45741714a0..7d292c5dee3cb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx @@ -772,8 +772,16 @@ describe('rule_details', () => { disableButton.simulate('click'); + const modal = wrapper.find('[data-test-subj="untrackAlertsModal"]'); + expect(modal.exists()).toBeTruthy(); + + modal.find('[data-test-subj="confirmModalConfirmButton"]').last().simulate('click'); + expect(mockRuleApis.bulkDisableRules).toHaveBeenCalledTimes(1); - expect(mockRuleApis.bulkDisableRules).toHaveBeenCalledWith({ ids: [rule.id] }); + expect(mockRuleApis.bulkDisableRules).toHaveBeenCalledWith({ + ids: [rule.id], + untrack: false, + }); }); it('should enable the rule when clicked', async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.tsx index 6bae4f720c032..a7f46a8e554c5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.tsx @@ -70,6 +70,7 @@ import { } from '../../rules_list/translations'; import { useBulkOperationToast } from '../../../hooks/use_bulk_operation_toast'; import { RefreshToken } from './types'; +import { UntrackAlertsModal } from '../../common/components/untrack_alerts_modal'; export type RuleDetailsProps = { rule: Rule; @@ -115,6 +116,7 @@ export const RuleDetails: React.FunctionComponent<RuleDetailsProps> = ({ const [rulesToDelete, setRulesToDelete] = useState<string[]>([]); const [rulesToUpdateAPIKey, setRulesToUpdateAPIKey] = useState<string[]>([]); + const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false); const [hasActionsWithBrokenConnector, setHasActionsWithBrokenConnector] = useState<boolean>(false); @@ -288,11 +290,39 @@ export const RuleDetails: React.FunctionComponent<RuleDetailsProps> = ({ setRulesToDelete([]); goToRulesList(); }; + const onDeleteCancel = () => { setIsDeleteModalVisibility(false); setRulesToDelete([]); }; + const onDisableModalOpen = () => { + setIsUntrackAlertsModalOpen(true); + }; + + const onDisableModalClose = () => { + setIsUntrackAlertsModalOpen(false); + }; + + const onEnable = async () => { + await bulkEnableRules({ ids: [rule.id] }); + requestRefresh(); + }; + + const onDisable = async (untrack: boolean) => { + onDisableModalClose(); + await bulkDisableRules({ ids: [rule.id], untrack }); + requestRefresh(); + }; + + const onEnableDisable = (enable: boolean) => { + if (enable) { + onEnable(); + } else { + onDisableModalOpen(); + } + }; + return ( <> {isDeleteModalFlyoutVisible && ( @@ -311,6 +341,9 @@ export const RuleDetails: React.FunctionComponent<RuleDetailsProps> = ({ )} /> )} + {isUntrackAlertsModalOpen && ( + <UntrackAlertsModal onCancel={onDisableModalClose} onConfirm={onDisable} /> + )} <UpdateApiKeyModalConfirmation onCancel={() => { setRulesToUpdateAPIKey([]); @@ -400,14 +433,7 @@ export const RuleDetails: React.FunctionComponent<RuleDetailsProps> = ({ onApiKeyUpdate={(ruleId) => { setRulesToUpdateAPIKey([ruleId]); }} - onEnableDisable={async (enable) => { - if (enable) { - await bulkEnableRules({ ids: [rule.id] }); - } else { - await bulkDisableRules({ ids: [rule.id] }); - } - requestRefresh(); - }} + onEnableDisable={onEnableDisable} onRunRule={onRunRule} />, editButton, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.test.tsx index 69dab6587d6f0..ebe28a2636378 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.test.tsx @@ -6,6 +6,14 @@ */ import React from 'react'; +import { + render, + screen, + waitFor, + waitForElementToBeRemoved, + fireEvent, +} from '@testing-library/react'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { act } from 'react-dom/test-utils'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; @@ -103,35 +111,33 @@ describe('rule status panel', () => { it('should disable the rule when picking disable in the dropdown', async () => { const rule = mockRule({ enabled: true }); const bulkDisableRules = jest.fn(); - const wrapper = mountWithIntl( - <RuleStatusPanelWithProvider - {...mockAPIs} - rule={rule} - isEditable - healthColor="primary" - statusMessage="Ok" - requestRefresh={requestRefresh} - bulkDisableRules={bulkDisableRules} - /> + render( + <IntlProvider locale="en"> + <RuleStatusPanelWithProvider + {...mockAPIs} + rule={rule} + isEditable + healthColor="primary" + statusMessage="Ok" + requestRefresh={requestRefresh} + bulkDisableRules={bulkDisableRules} + /> + </IntlProvider> ); - const actionsElem = wrapper - .find('[data-test-subj="statusDropdown"] .euiBadge__childButton') - .first(); - actionsElem.simulate('click'); - await act(async () => { - await nextTick(); - wrapper.update(); - }); + if (screen.queryByTestId('centerJustifiedSpinner')) { + await waitForElementToBeRemoved(() => screen.queryByTestId('centerJustifiedSpinner')); + } - await act(async () => { - const actionsMenuElem = wrapper.find('[data-test-subj="ruleStatusMenu"]'); - const actionsMenuItemElem = actionsMenuElem.first().find('button.euiContextMenuItem'); - actionsMenuItemElem.at(1).simulate('click'); - await nextTick(); - }); + fireEvent.click(screen.getByTestId('ruleStatusDropdownBadge')); + + fireEvent.click(screen.getByTestId('statusDropdownDisabledItem')); + + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); - expect(bulkDisableRules).toHaveBeenCalledTimes(1); + expect(screen.queryByRole('progressbar')).toBeInTheDocument(); + + await waitFor(() => expect(bulkDisableRules).toHaveBeenCalledTimes(1)); }); it('if rule is already disabled should do nothing when picking disable in the dropdown', async () => { @@ -233,55 +239,4 @@ describe('rule status panel', () => { expect(bulkEnableRules).toHaveBeenCalledTimes(0); }); - - it('should show the loading spinner when the rule enabled switch was clicked and the server responded with some delay', async () => { - const rule = mockRule({ - enabled: true, - }); - - const bulkDisableRules = jest.fn(async () => { - await new Promise((resolve) => setTimeout(resolve, 6000)); - }) as any; - - const wrapper = mountWithIntl( - <RuleStatusPanelWithProvider - {...mockAPIs} - rule={rule} - isEditable - healthColor="primary" - statusMessage="Ok" - requestRefresh={requestRefresh} - bulkDisableRules={bulkDisableRules} - /> - ); - - const actionsElem = wrapper - .find('[data-test-subj="statusDropdown"] .euiBadge__childButton') - .first(); - actionsElem.simulate('click'); - - await act(async () => { - await nextTick(); - wrapper.update(); - }); - - await act(async () => { - const actionsMenuElem = wrapper.find('[data-test-subj="ruleStatusMenu"]'); - const actionsMenuItemElem = actionsMenuElem.first().find('button.euiContextMenuItem'); - actionsMenuItemElem.at(1).simulate('click'); - }); - - await act(async () => { - await nextTick(); - wrapper.update(); - }); - - await act(async () => { - expect(bulkDisableRules).toHaveBeenCalled(); - expect( - wrapper.find('[data-test-subj="statusDropdown"] .euiBadge__childButton .euiLoadingSpinner') - .length - ).toBeGreaterThan(0); - }); - }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx index a7b87cc722530..2419993f12670 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_status_panel.tsx @@ -102,6 +102,13 @@ export const RuleStatusPanel: React.FC<RuleStatusPanelWithApiProps> = ({ requestRefresh(); }, [requestRefresh, loadEventLogs]); + const onDisableRule = useCallback( + (untrack: boolean) => { + return bulkDisableRules({ ids: [rule.id], untrack }); + }, + [bulkDisableRules, rule.id] + ); + useEffect(() => { if (isInitialized.current) { loadEventLogs(); @@ -126,7 +133,7 @@ export const RuleStatusPanel: React.FC<RuleStatusPanelWithApiProps> = ({ </EuiFlexItem> <EuiFlexItem> <RuleStatusDropdown - disableRule={() => bulkDisableRules({ ids: [rule.id] })} + disableRule={onDisableRule} enableRule={() => bulkEnableRules({ ids: [rule.id] })} snoozeRule={async () => {}} unsnoozeRule={async () => {}} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.test.tsx index 8d5b7952b5f00..9bcab7c092421 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.test.tsx @@ -224,11 +224,20 @@ describe('CollapsedItemActions', () => { wrapper.update(); }); wrapper.find('button[data-test-subj="disableButton"]').simulate('click'); + + const modal = wrapper.find('[data-test-subj="untrackAlertsModal"]'); + expect(modal.exists()).toBeTruthy(); + + modal.find('[data-test-subj="confirmModalConfirmButton"]').last().simulate('click'); + await act(async () => { await tick(10); wrapper.update(); }); - expect(bulkDisableRules).toHaveBeenCalled(); + expect(bulkDisableRules).toHaveBeenCalledWith({ + ids: ['1'], + untrack: false, + }); }); test('handles case when rule is unmuted and disabled and enable is clicked', async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.tsx index 7df59161dffeb..5a6217f31f83f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/collapsed_item_actions.tsx @@ -34,6 +34,7 @@ import { SNOOZE_SUCCESS_MESSAGE, UNSNOOZE_SUCCESS_MESSAGE, } from './notify_badge'; +import { UntrackAlertsModal } from '../../common/components/untrack_alerts_modal'; export type ComponentOpts = { item: RuleTableItem; @@ -70,6 +71,8 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({ const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false); const [isDisabled, setIsDisabled] = useState<boolean>(!item.enabled); + const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false); + useEffect(() => { setIsDisabled(!item.enabled); }, [item.enabled]); @@ -179,6 +182,42 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({ ]; }, [isDisabled, item, snoozedButtonText]); + const onDisableModalOpen = useCallback(() => { + setIsUntrackAlertsModalOpen(true); + }, []); + + const onDisableModalClose = useCallback(() => { + setIsUntrackAlertsModalOpen(false); + }, []); + + const onEnable = useCallback(async () => { + asyncScheduler.schedule(async () => { + await bulkEnableRules({ ids: [item.id] }); + onRuleChanged(); + }, 10); + setIsDisabled(false); + setIsPopoverOpen(false); + }, [bulkEnableRules, onRuleChanged, item.id]); + + const onDisable = useCallback( + async (untrack: boolean) => { + onDisableModalClose(); + await bulkDisableRules({ ids: [item.id], untrack }); + onRuleChanged(); + setIsDisabled(true); + setIsPopoverOpen(false); + }, + [onDisableModalClose, bulkDisableRules, onRuleChanged, item.id] + ); + + const onDisableClick = useCallback(() => { + if (isDisabled) { + onEnable(); + } else { + onDisableModalOpen(); + } + }, [isDisabled, onEnable, onDisableModalOpen]); + const panels = [ { id: 0, @@ -191,19 +230,7 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({ { disabled: !item.isEditable || !item.enabledInLicense, 'data-test-subj': 'disableButton', - onClick: async () => { - const enabled = !isDisabled; - asyncScheduler.schedule(async () => { - if (enabled) { - await bulkDisableRules({ ids: [item.id] }); - } else { - await bulkEnableRules({ ids: [item.id] }); - } - onRuleChanged(); - }, 10); - setIsDisabled(!isDisabled); - setIsPopoverOpen(!isPopoverOpen); - }, + onClick: onDisableClick, name: isDisabled ? i18n.translate( 'xpack.triggersActionsUI.sections.rulesList.collapsedItemActons.enableTitle', @@ -310,22 +337,27 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({ ]; return ( - <EuiPopover - button={button} - isOpen={isPopoverOpen} - closePopover={() => setIsPopoverOpen(false)} - ownFocus - panelPaddingSize="none" - data-test-subj="collapsedItemActions" - > - <EuiContextMenu - initialPanelId={0} - panels={panels} - className="actCollapsedItemActions" - data-test-subj="collapsedActionPanel" - data-testid="collapsedActionPanel" - /> - </EuiPopover> + <> + <EuiPopover + button={button} + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + ownFocus + panelPaddingSize="none" + data-test-subj="collapsedItemActions" + > + <EuiContextMenu + initialPanelId={0} + panels={panels} + className="actCollapsedItemActions" + data-test-subj="collapsedActionPanel" + data-testid="collapsedActionPanel" + /> + </EuiPopover> + {isUntrackAlertsModalOpen && ( + <UntrackAlertsModal onCancel={onDisableModalClose} onConfirm={onDisable} /> + )} + </> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx index 145fda4e4addd..1470fe2606107 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_dropdown.tsx @@ -27,6 +27,7 @@ import { SnoozePanel } from './rule_snooze'; import { isRuleSnoozed } from '../../../lib'; import { Rule, SnoozeSchedule, BulkOperationResponse } from '../../../../types'; import { ToastWithCircuitBreakerContent } from '../../../components/toast_with_circuit_breaker_content'; +import { UntrackAlertsModal } from '../../common/components/untrack_alerts_modal'; export type SnoozeUnit = 'm' | 'h' | 'd' | 'w' | 'M'; const SNOOZE_END_TIME_FORMAT = 'LL @ LT'; @@ -40,7 +41,7 @@ export interface ComponentOpts { rule: DropdownRuleRecord; onRuleChanged: () => void; enableRule: () => Promise<BulkOperationResponse>; - disableRule: () => Promise<BulkOperationResponse>; + disableRule: (untrack: boolean) => Promise<BulkOperationResponse>; snoozeRule: (snoozeSchedule: SnoozeSchedule) => Promise<void>; unsnoozeRule: (scheduleIds?: string[]) => Promise<void>; isEditable: boolean; @@ -74,6 +75,7 @@ export const RuleStatusDropdown: React.FunctionComponent<ComponentOpts> = ({ }, [rule, hideSnoozeOption]); const [isUpdating, setIsUpdating] = useState<boolean>(false); const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false); + const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false); const onClickBadge = useCallback(() => setIsPopoverOpen((isOpen) => !isOpen), [setIsPopoverOpen]); const onClosePopover = useCallback(() => setIsPopoverOpen(false), [setIsPopoverOpen]); @@ -97,25 +99,59 @@ export const RuleStatusDropdown: React.FunctionComponent<ComponentOpts> = ({ throw new Error(); }, [enableRule, toasts]); - const onChangeEnabledStatus = useCallback( - async (enable: boolean) => { - if (rule.enabled === enable) { - return; - } + const onEnable = useCallback(async () => { + setIsUpdating(true); + try { + await enableRuleInternal(); + setIsEnabled(true); + onRuleChanged(); + } finally { + setIsUpdating(false); + } + }, [onRuleChanged, enableRuleInternal]); + + const onDisable = useCallback( + async (untrack: boolean) => { setIsUpdating(true); try { - if (enable) { - await enableRuleInternal(); - } else { - await disableRule(); - } - setIsEnabled(!isEnabled); + await disableRule(untrack); + setIsEnabled(false); onRuleChanged(); } finally { setIsUpdating(false); } }, - [rule.enabled, isEnabled, onRuleChanged, enableRuleInternal, disableRule] + [onRuleChanged, disableRule] + ); + + const onDisableModalOpen = useCallback(() => { + setIsUntrackAlertsModalOpen(true); + }, []); + + const onDisableModalClose = useCallback(() => { + setIsUntrackAlertsModalOpen(false); + }, []); + + const onModalConfirm = useCallback( + (untrack: boolean) => { + onDisableModalClose(); + onDisable(untrack); + }, + [onDisableModalClose, onDisable] + ); + + const onChangeEnabledStatus = useCallback( + async (enable: boolean) => { + if (rule.enabled === enable) { + return; + } + if (enable) { + await onEnable(); + } else { + onDisableModalOpen(); + } + }, + [rule.enabled, onEnable, onDisableModalOpen] ); const onSnoozeRule = useCallback( @@ -168,6 +204,7 @@ export const RuleStatusDropdown: React.FunctionComponent<ComponentOpts> = ({ const editableBadge = ( <EuiBadge + data-test-subj="ruleStatusDropdownBadge" color={badgeColor} iconSide="right" iconType={!isUpdating && isEditable ? 'arrowDown' : undefined} @@ -185,44 +222,49 @@ export const RuleStatusDropdown: React.FunctionComponent<ComponentOpts> = ({ ); return ( - <EuiFlexGroup - direction={direction} - alignItems={direction === 'row' ? 'center' : 'flexStart'} - justifyContent="flexStart" - gutterSize={direction === 'row' ? 's' : 'xs'} - responsive={false} - > - <EuiFlexItem grow={false}> - {isEditable ? ( - <EuiPopover - button={editableBadge} - isOpen={isPopoverOpen && isEditable} - closePopover={onClosePopover} - panelPaddingSize="s" - data-test-subj="statusDropdown" - title={badgeMessage} - > - <RuleStatusMenu - onClosePopover={onClosePopover} - onChangeEnabledStatus={onChangeEnabledStatus} - isEnabled={isEnabled} - isSnoozed={isSnoozed} - snoozeEndTime={rule.isSnoozedUntil} - hideSnoozeOption={hideSnoozeOption} - snoozeRule={onSnoozeRule} - unsnoozeRule={onUnsnoozeRule} - scheduledSnoozes={rule.snoozeSchedule} - activeSnoozes={rule.activeSnoozes} - /> - </EuiPopover> - ) : ( - nonEditableBadge - )} - </EuiFlexItem> - <EuiFlexItem data-test-subj="remainingSnoozeTime" grow={false}> - {remainingSnoozeTime} - </EuiFlexItem> - </EuiFlexGroup> + <> + <EuiFlexGroup + direction={direction} + alignItems={direction === 'row' ? 'center' : 'flexStart'} + justifyContent="flexStart" + gutterSize={direction === 'row' ? 's' : 'xs'} + responsive={false} + > + <EuiFlexItem grow={false}> + {isEditable ? ( + <EuiPopover + button={editableBadge} + isOpen={isPopoverOpen && isEditable} + closePopover={onClosePopover} + panelPaddingSize="s" + data-test-subj="statusDropdown" + title={badgeMessage} + > + <RuleStatusMenu + onClosePopover={onClosePopover} + onChangeEnabledStatus={onChangeEnabledStatus} + isEnabled={isEnabled} + isSnoozed={isSnoozed} + snoozeEndTime={rule.isSnoozedUntil} + hideSnoozeOption={hideSnoozeOption} + snoozeRule={onSnoozeRule} + unsnoozeRule={onUnsnoozeRule} + scheduledSnoozes={rule.snoozeSchedule} + activeSnoozes={rule.activeSnoozes} + /> + </EuiPopover> + ) : ( + nonEditableBadge + )} + </EuiFlexItem> + <EuiFlexItem data-test-subj="remainingSnoozeTime" grow={false}> + {remainingSnoozeTime} + </EuiFlexItem> + </EuiFlexGroup> + {isUntrackAlertsModalOpen && ( + <UntrackAlertsModal onConfirm={onModalConfirm} onCancel={onDisableModalClose} /> + )} + </> ); }; @@ -260,6 +302,7 @@ const RuleStatusMenu: React.FunctionComponent<RuleStatusMenuProps> = ({ } onClosePopover(); }, [onChangeEnabledStatus, onClosePopover, unsnoozeRule, isSnoozed]); + const disableRule = useCallback(() => { onChangeEnabledStatus(false); onClosePopover(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index 67d475ae2689e..9b66a65949674 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -555,8 +555,8 @@ export const RulesList = ({ }; const onDisableRule = useCallback( - (rule: RuleTableItem) => { - return bulkDisableRules({ http, ids: [rule.id] }); + (rule: RuleTableItem, untrack: boolean) => { + return bulkDisableRules({ http, ids: [rule.id], untrack }); }, [bulkDisableRules] ); @@ -701,12 +701,12 @@ export const RulesList = ({ onClearSelection(); }; - const onDisable = async () => { + const onDisable = async (untrack: boolean) => { setIsDisablingRules(true); const { errors, total } = isAllSelected - ? await bulkDisableRules({ http, filter: getFilter() }) - : await bulkDisableRules({ http, ids: selectedIds }); + ? await bulkDisableRules({ http, filter: getFilter(), untrack }) + : await bulkDisableRules({ http, ids: selectedIds, untrack }); setIsDisablingRules(false); showToast({ action: 'DISABLE', errors, total }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_bulk_disable.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_bulk_disable.test.tsx index 4110ea34d3c95..40aad0464e4f2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_bulk_disable.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_bulk_disable.test.tsx @@ -7,10 +7,10 @@ import * as React from 'react'; import { IToasts } from '@kbn/core/public'; import { - act, render, screen, cleanup, + waitFor, waitForElementToBeRemoved, fireEvent, } from '@testing-library/react'; @@ -180,10 +180,16 @@ describe('Rules list Bulk Disable', () => { }); it('can bulk disable', async () => { - await act(async () => { - fireEvent.click(screen.getByTestId('bulkDisable')); + fireEvent.click(screen.getByTestId('bulkDisable')); + + await waitFor(() => { + expect(screen.getByTestId('untrackAlertsModal')).toBeInTheDocument(); }); + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + await waitForElementToBeRemoved(() => screen.queryByTestId('bulkDisable')); + const filter = bulkDisableRules.mock.calls[0][0].filter; expect(filter.function).toEqual('and'); @@ -192,23 +198,25 @@ describe('Rules list Bulk Disable', () => { expect(filter.arguments[1].arguments[0].arguments[0].value).toEqual('alert.id'); expect(filter.arguments[1].arguments[0].arguments[1].value).toEqual('alert:2'); - expect(bulkDisableRules).toHaveBeenCalledWith( - expect.not.objectContaining({ - ids: [], - }) - ); + expect(bulkDisableRules).toHaveBeenCalled(); + expect(screen.getByTestId('checkboxSelectRow-1').closest('tr')).not.toHaveClass( 'euiTableRow-isSelected' ); - expect(screen.queryByTestId('bulkDisable')).not.toBeInTheDocument(); }); describe('Toast', () => { it('should have success toast message', async () => { - await act(async () => { - fireEvent.click(screen.getByTestId('bulkDisable')); + fireEvent.click(screen.getByTestId('bulkDisable')); + + await waitFor(() => { + expect(screen.getByTestId('untrackAlertsModal')).toBeInTheDocument(); }); + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + await waitForElementToBeRemoved(() => screen.queryByTestId('bulkDisable')); + expect(useKibanaMock().services.notifications.toasts.addSuccess).toHaveBeenCalledTimes(1); expect(useKibanaMock().services.notifications.toasts.addSuccess).toHaveBeenCalledWith( 'Disabled 10 rules' @@ -229,10 +237,16 @@ describe('Rules list Bulk Disable', () => { total: 10, }); - await act(async () => { - fireEvent.click(screen.getByTestId('bulkDisable')); + fireEvent.click(screen.getByTestId('bulkDisable')); + + await waitFor(() => { + expect(screen.getByTestId('untrackAlertsModal')).toBeInTheDocument(); }); + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + await waitForElementToBeRemoved(() => screen.queryByTestId('bulkDisable')); + expect(useKibanaMock().services.notifications.toasts.addWarning).toHaveBeenCalledTimes(1); expect(useKibanaMock().services.notifications.toasts.addWarning).toHaveBeenCalledWith( expect.objectContaining({ @@ -255,10 +269,16 @@ describe('Rules list Bulk Disable', () => { total: 1, }); - await act(async () => { - fireEvent.click(screen.getByTestId('bulkDisable')); + fireEvent.click(screen.getByTestId('bulkDisable')); + + await waitFor(() => { + expect(screen.getByTestId('untrackAlertsModal')).toBeInTheDocument(); }); + fireEvent.click(screen.getByTestId('confirmModalConfirmButton')); + + await waitForElementToBeRemoved(() => screen.queryByTestId('bulkDisable')); + expect(useKibanaMock().services.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); expect(useKibanaMock().services.notifications.toasts.addDanger).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx index 9933a52e3ac1f..0f1f42b475a35 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx @@ -127,7 +127,7 @@ export interface RulesListTableProps { onPercentileOptionsChange?: (options: EuiSelectableOption[]) => void; onRuleChanged: () => Promise<void>; onEnableRule: (rule: RuleTableItem) => Promise<BulkOperationResponse>; - onDisableRule: (rule: RuleTableItem) => Promise<BulkOperationResponse>; + onDisableRule: (rule: RuleTableItem, untrack: boolean) => Promise<BulkOperationResponse>; onSnoozeRule: (rule: RuleTableItem, snoozeSchedule: SnoozeSchedule) => Promise<void>; onUnsnoozeRule: (rule: RuleTableItem, scheduleIds?: string[]) => Promise<void>; onSelectAll: () => void; @@ -281,12 +281,19 @@ export const RulesListTable = (props: RulesListTableProps) => { [ruleTypeRegistry] ); + const onDisableRuleInternal = useCallback( + (rule: RuleTableItem) => (untrack: boolean) => { + return onDisableRule(rule, untrack); + }, + [onDisableRule] + ); + const renderRuleStatusDropdown = useCallback( (rule: RuleTableItem) => { return ( <RuleStatusDropdown hideSnoozeOption - disableRule={async () => await onDisableRule(rule)} + disableRule={onDisableRuleInternal(rule)} enableRule={async () => await onEnableRule(rule)} snoozeRule={async () => {}} unsnoozeRule={async () => {}} @@ -296,7 +303,7 @@ export const RulesListTable = (props: RulesListTableProps) => { /> ); }, - [isRuleTypeEditableInContext, onDisableRule, onEnableRule, onRuleChanged] + [isRuleTypeEditableInContext, onDisableRuleInternal, onEnableRule, onRuleChanged] ); const selectionColumn = useMemo(() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 36cc294bbda5f..ba5afb74ecfd8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -221,6 +221,14 @@ export type BulkOperationAttributes = BulkOperationAttributesWithoutHttp & { http: HttpSetup; }; +export type BulkDisableParamsWithoutHttp = BulkOperationAttributesWithoutHttp & { + untrack: boolean; +}; + +export type BulkDisableParams = BulkDisableParamsWithoutHttp & { + http: HttpSetup; +}; + export interface ActionParamsProps<TParams> { actionParams: Partial<TParams>; index: number; diff --git a/x-pack/test/alerting_api_integration/common/lib/alert_utils.ts b/x-pack/test/alerting_api_integration/common/lib/alert_utils.ts index 3307211694cc0..6cf75ee6ad635 100644 --- a/x-pack/test/alerting_api_integration/common/lib/alert_utils.ts +++ b/x-pack/test/alerting_api_integration/common/lib/alert_utils.ts @@ -101,10 +101,13 @@ export class AlertUtils { return request; } - public getDisableRequest(alertId: string) { + public getDisableRequest(alertId: string, untrack?: boolean) { const request = this.supertestWithoutAuth .post(`${getUrlPrefix(this.space.id)}/api/alerting/rule/${alertId}/_disable`) - .set('kbn-xsrf', 'foo'); + .set('kbn-xsrf', 'foo') + .send({ + untrack: untrack === undefined ? true : untrack, + }); if (this.user) { return request.auth(this.user.username, this.user.password); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/disable.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/disable.ts index 0dccb0ea5a545..32d8a4dc3c650 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/disable.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/disable.ts @@ -7,6 +7,8 @@ import expect from '@kbn/expect'; import { RULE_SAVED_OBJECT_TYPE } from '@kbn/alerting-plugin/server'; +import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; +import { ALERT_STATUS } from '@kbn/rule-data-utils'; import { Spaces } from '../../../scenarios'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -20,6 +22,8 @@ import { } from '../../../../common/lib'; import { validateEvent } from './event_log'; +const alertAsDataIndex = '.internal.alerts-observability.test.alerts.alerts-default-000001'; + // eslint-disable-next-line import/no-default-export export default function createDisableRuleTests({ getService }: FtrProviderContext) { const es = getService('es'); @@ -31,7 +35,16 @@ export default function createDisableRuleTests({ getService }: FtrProviderContex const objectRemover = new ObjectRemover(supertestWithoutAuth); const ruleUtils = new RuleUtils({ space: Spaces.space1, supertestWithoutAuth }); - after(() => objectRemover.removeAll()); + afterEach(async () => { + await es.deleteByQuery({ + index: alertAsDataIndex, + query: { + match_all: {}, + }, + conflicts: 'proceed', + }); + await objectRemover.removeAll(); + }); async function getScheduledTask(id: string): Promise<TaskManagerDoc> { const scheduledTask = await es.get<TaskManagerDoc>({ @@ -172,6 +185,54 @@ export default function createDisableRuleTests({ getService }: FtrProviderContex }); }); + it('should not untrack alerts if untrack is false', async () => { + const { body: createdRule } = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.always-firing-alert-as-data', + schedule: { interval: '24h' }, + throttle: undefined, + notify_when: undefined, + params: { + index: ES_TEST_INDEX_NAME, + reference: 'test', + }, + }) + ) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); + + await retry.try(async () => { + const { + hits: { hits: activeAlerts }, + } = await es.search({ + index: alertAsDataIndex, + body: { query: { match_all: {} } }, + }); + + expect(activeAlerts.length).eql(2); + activeAlerts.forEach((activeAlert: any) => { + expect(activeAlert._source[ALERT_STATUS]).eql('active'); + }); + }); + + await ruleUtils.getDisableRequest(createdRule.id, false); + + const { + hits: { hits: untrackedAlerts }, + } = await es.search({ + index: alertAsDataIndex, + body: { query: { match_all: {} } }, + }); + expect(untrackedAlerts.length).eql(2); + untrackedAlerts.forEach((untrackedAlert: any) => { + expect(untrackedAlert._source[ALERT_STATUS]).eql('active'); + }); + }); + it('should disable rule even if associated task manager document is missing', async () => { const { body: createdRule } = await supertestWithoutAuth .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/bulk_disable.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/bulk_disable.ts new file mode 100644 index 0000000000000..e5692e73a15ab --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/bulk_disable.ts @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; +import { ALERT_STATUS } from '@kbn/rule-data-utils'; +import { Spaces } from '../../../scenarios'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common/lib'; + +const alertAsDataIndex = '.internal.alerts-observability.test.alerts.alerts-default-000001'; + +// eslint-disable-next-line import/no-default-export +export default function createDisableRuleTests({ getService }: FtrProviderContext) { + const es = getService('es'); + const retry = getService('retry'); + const supertest = getService('supertest'); + + describe('bulkDisable', () => { + const objectRemover = new ObjectRemover(supertest); + + const createRule = async () => { + const { body: createdRule } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.always-firing-alert-as-data', + schedule: { interval: '24h' }, + throttle: undefined, + notify_when: undefined, + params: { + index: ES_TEST_INDEX_NAME, + reference: 'test', + }, + }) + ) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); + return createdRule.id; + }; + + const getAlerts = async () => { + const { + hits: { hits: alerts }, + } = await es.search({ + index: alertAsDataIndex, + body: { query: { match_all: {} } }, + }); + + return alerts; + }; + + afterEach(async () => { + await es.deleteByQuery({ + index: alertAsDataIndex, + query: { + match_all: {}, + }, + conflicts: 'proceed', + }); + await objectRemover.removeAll(); + }); + + it('should bulk disable and untrack', async () => { + const createdRule1 = await createRule(); + const createdRule2 = await createRule(); + + await retry.try(async () => { + const alerts = await getAlerts(); + + expect(alerts.length).eql(4); + alerts.forEach((activeAlert: any) => { + expect(activeAlert._source[ALERT_STATUS]).eql('active'); + }); + }); + + await supertest + .patch(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_bulk_disable`) + .set('kbn-xsrf', 'foo') + .send({ + ids: [createdRule1, createdRule2], + untrack: true, + }) + .expect(200); + + const alerts = await getAlerts(); + + expect(alerts.length).eql(4); + alerts.forEach((untrackedAlert: any) => { + expect(untrackedAlert._source[ALERT_STATUS]).eql('untracked'); + }); + }); + + it('should bulk disable and not untrack if untrack is false', async () => { + const createdRule1 = await createRule(); + const createdRule2 = await createRule(); + + await retry.try(async () => { + const alerts = await getAlerts(); + + expect(alerts.length).eql(4); + alerts.forEach((activeAlert: any) => { + expect(activeAlert._source[ALERT_STATUS]).eql('active'); + }); + }); + + await supertest + .patch(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_bulk_disable`) + .set('kbn-xsrf', 'foo') + .send({ + ids: [createdRule1, createdRule2], + untrack: false, + }) + .expect(200); + + const alerts = await getAlerts(); + + expect(alerts.length).eql(4); + alerts.forEach((activeAlert: any) => { + expect(activeAlert._source[ALERT_STATUS]).eql('active'); + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts index 15084a47f4d86..86c239250d109 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts @@ -23,6 +23,7 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./snooze')); loadTestFile(require.resolve('./unsnooze')); loadTestFile(require.resolve('./bulk_edit')); + loadTestFile(require.resolve('./bulk_disable')); loadTestFile(require.resolve('./capped_action_type')); loadTestFile(require.resolve('./scheduled_task_id')); loadTestFile(require.resolve('./run_soon')); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index c7dc220e96723..0d7539c566e7e 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -200,6 +200,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await actionsMenuItemElem.at(1)?.click(); + await testSubjects.click('confirmModalConfirmButton'); + await pageObjects.header.waitUntilLoadingHasFinished(); + await retry.try(async () => { expect(await actionsDropdown.getVisibleText()).to.eql('Disabled'); }); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts index 1a169c3bd69bf..7838ec24c50a3 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts @@ -17,13 +17,15 @@ import { } from '../../../lib/alert_api_actions'; import { ObjectRemover } from '../../../lib/object_remover'; import { generateUniqueKey } from '../../../lib/get_test_data'; +import { getTestAlertData } from '../../../lib/get_test_data'; -export default ({ getPageObjects, getService }: FtrProviderContext) => { +export default ({ getPageObjects, getPageObject, getService }: FtrProviderContext) => { const testSubjects = getService('testSubjects'); const find = getService('find'); const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']); const supertest = getService('supertest'); const retry = getService('retry'); + const header = getPageObject('header'); const objectRemover = new ObjectRemover(supertest); async function refreshAlertsList() { @@ -39,6 +41,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('rulesTab'); } + const getAlertSummary = async (ruleId: string) => { + const { body: summary } = await supertest + .get(`/internal/alerting/rule/${encodeURIComponent(ruleId)}/_alert_summary`) + .expect(200); + return summary; + }; + describe('rules list', function () { const assertRulesLength = async (length: number) => { return await retry.try(async () => { @@ -185,6 +194,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('disableButton'); + await testSubjects.click('confirmModalConfirmButton'); + await refreshAlertsList(); await find.waitForDeletedByCssSelector('.euiBasicTable-loading'); @@ -195,12 +206,93 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { ); }); + it('should untrack disable rule if untrack switch is true', async () => { + const { body: createdRule } = await supertest + .post(`/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestAlertData({ + rule_type_id: 'test.always-firing', + schedule: { interval: '24h' }, + params: { + instances: [{ id: 'alert-id' }], + }, + }) + ) + .expect(200); + + objectRemover.add(createdRule.id, 'alert', 'alerts'); + + await retry.try(async () => { + const { alerts: alertInstances } = await getAlertSummary(createdRule.id); + expect(Object.keys(alertInstances).length).to.eql(1); + expect(alertInstances['alert-id'].tracked).to.eql(true); + }); + + await refreshAlertsList(); + await pageObjects.triggersActionsUI.searchAlerts(createdRule.name); + + await testSubjects.click('collapsedItemActions'); + + await testSubjects.click('disableButton'); + + await testSubjects.click('untrackAlertsModalSwitch'); + + await testSubjects.click('confirmModalConfirmButton'); + + await header.waitUntilLoadingHasFinished(); + + await retry.try(async () => { + const { alerts: alertInstances } = await getAlertSummary(createdRule.id); + expect(alertInstances['alert-id'].tracked).to.eql(false); + }); + }); + + it('should not untrack disable rule if untrack switch if false', async () => { + const { body: createdRule } = await supertest + .post(`/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestAlertData({ + rule_type_id: 'test.always-firing', + schedule: { interval: '24h' }, + params: { + instances: [{ id: 'alert-id' }], + }, + }) + ) + .expect(200); + + objectRemover.add(createdRule.id, 'alert', 'alerts'); + + await retry.try(async () => { + const { alerts: alertInstances } = await getAlertSummary(createdRule.id); + expect(Object.keys(alertInstances).length).to.eql(1); + expect(alertInstances['alert-id'].tracked).to.eql(true); + }); + + await refreshAlertsList(); + await pageObjects.triggersActionsUI.searchAlerts(createdRule.name); + + await testSubjects.click('collapsedItemActions'); + + await testSubjects.click('disableButton'); + + await testSubjects.click('confirmModalConfirmButton'); + + await header.waitUntilLoadingHasFinished(); + + await retry.try(async () => { + const { alerts: alertInstances } = await getAlertSummary(createdRule.id); + expect(alertInstances['alert-id'].tracked).to.eql(true); + }); + }); + it('should re-enable single alert', async () => { const createdAlert = await createAlert({ supertest, objectRemover, }); - await disableAlert({ supertest, alertId: createdAlert.id }); await refreshAlertsList(); await pageObjects.triggersActionsUI.searchAlerts(createdAlert.name); @@ -212,8 +304,25 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('disableButton'); - await refreshAlertsList(); - await find.waitForDeletedByCssSelector('.euiBasicTable-loading'); + await testSubjects.click('confirmModalConfirmButton'); + + await header.waitUntilLoadingHasFinished(); + + await pageObjects.triggersActionsUI.ensureRuleActionStatusApplied( + createdAlert.name, + 'statusDropdown', + 'disabled' + ); + + await testSubjects.click('collapsedItemActions'); + + await retry.waitForWithTimeout('disable button to show up', 30000, async () => { + return await testSubjects.isDisplayed('disableButton'); + }); + + await testSubjects.click('disableButton'); + + await header.waitUntilLoadingHasFinished(); await pageObjects.triggersActionsUI.ensureRuleActionStatusApplied( createdAlert.name, @@ -255,6 +364,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('bulkAction'); await testSubjects.click('bulkDisable'); + await testSubjects.click('confirmModalConfirmButton'); + + await header.waitUntilLoadingHasFinished(); + await retry.try(async () => { const toastTitle = await pageObjects.common.closeToast(); expect(toastTitle).to.eql('Disabled 1 rule'); diff --git a/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts b/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts index e9b87e203fad8..ca1a3f5c622df 100644 --- a/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts +++ b/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts @@ -270,6 +270,10 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { await testSubjects.existOrFail('rulesList'); await observability.alerts.rulesPage.clickRuleStatusDropDownMenu(); await observability.alerts.rulesPage.clickDisableFromDropDownMenu(); + + await testSubjects.click('confirmModalConfirmButton'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.waitFor('The rule to be disabled', async () => { const tableRows = await find.allByCssSelector('.euiTableRow'); const rows = await getRulesList(tableRows); diff --git a/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts b/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts index d664d36e99f1e..2ebb4395bf317 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts @@ -22,6 +22,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const svlCommonPage = getPageObject('svlCommonPage'); const svlCommonNavigation = getPageObject('svlCommonNavigation'); const svlTriggersActionsUI = getPageObject('svlTriggersActionsUI'); + const header = getPageObject('header'); const svlObltNavigation = getService('svlObltNavigation'); const testSubjects = getService('testSubjects'); const supertest = getService('supertest'); @@ -300,6 +301,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('collapsedItemActions'); await testSubjects.click('disableButton'); + await testSubjects.click('confirmModalConfirmButton'); + + await header.waitUntilLoadingHasFinished(); + await refreshRulesList(); await find.waitForDeletedByCssSelector('.euiBasicTable-loading'); @@ -387,6 +392,9 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('bulkAction'); await testSubjects.click('bulkDisable'); + await testSubjects.click('confirmModalConfirmButton'); + await header.waitUntilLoadingHasFinished(); + await retry.try(async () => { const resultToast = await toasts.getToastElement(1); const toastText = await resultToast.getVisibleText();