From a25506c842422f56108ec19218777a860df6a04c Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Fri, 30 Jun 2023 16:17:43 -0700 Subject: [PATCH 01/98] [Cloud Security] Remove CloudFormation from manual options (#161037) --- .../get_aws_credentials_form_options.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/aws_credentials_form/get_aws_credentials_form_options.tsx b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/aws_credentials_form/get_aws_credentials_form_options.tsx index 4b245b9a992ac3..b7c1e1d36b5cc9 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/aws_credentials_form/get_aws_credentials_form_options.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/aws_credentials_form/get_aws_credentials_form_options.tsx @@ -103,10 +103,12 @@ export const getAwsCredentialsFormManualOptions = (): Array<{ value: AwsCredentialsType; text: string; }> => { - return Object.entries(getAwsCredentialsFormOptions()).map(([key, value]) => ({ - value: key as AwsCredentialsType, - text: value.label, - })); + return Object.entries(getAwsCredentialsFormOptions()) + .map(([key, value]) => ({ + value: key as AwsCredentialsType, + text: value.label, + })) + .filter(({ value }) => value !== 'cloud_formation'); }; export const DEFAULT_MANUAL_AWS_CREDENTIALS_TYPE = 'assume_role'; From 938716e58aa7b4ee37233529510ac0956cfe888c Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Fri, 30 Jun 2023 20:45:39 -0700 Subject: [PATCH 02/98] [Dashboard] Redesign clone experience (#159752) ## Summary Closes #154500. Closes https://github.com/elastic/kibana/issues/114206. This updates the UX around cloning dashboards. I removed the clone confirm model, so cloning a dashboard is just a one click action now. This aligns with how other apps like ML handle cloning. I've also made the dashboard title breadcrumb a button in edit mode that opens the dashboard settings flyout for better discoverability. https://github.com/elastic/kibana/assets/1697105/4f5ea117-a5e4-4ec5-9113-8b09fd8c84a1 I also changed the pattern for cloned dashboard title from `Dashboard Title Copy` to `Dashboard Title (#)`. Screenshot 2023-06-30 at 1 03 35 PM --- .../top_nav/dashboard_top_nav.tsx | 19 +- .../api/lib/extract_title_and_count.test.ts | 32 +++ .../api/lib/extract_title_and_count.ts | 19 ++ .../__snapshots__/clone_modal.test.js.snap | 65 ------ .../api/overlays/clone_modal.test.js | 57 ----- .../embeddable/api/overlays/clone_modal.tsx | 203 ------------------ .../api/overlays/show_clone_modal.tsx | 72 ------- .../embeddable/api/run_save_functions.tsx | 44 ++-- .../check_for_duplicate_dashboard_title.ts | 2 +- test/accessibility/apps/dashboard.ts | 7 +- .../apps/dashboard/group4/dashboard_clone.ts | 36 +--- .../functional/page_objects/dashboard_page.ts | 18 -- .../translations/translations/fr-FR.json | 11 +- .../translations/translations/ja-JP.json | 11 +- .../translations/translations/zh-CN.json | 11 +- 15 files changed, 100 insertions(+), 507 deletions(-) create mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.test.ts create mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.ts delete mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/clone_modal.test.js.snap delete mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.test.js delete mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.tsx delete mode 100644 src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/show_clone_modal.tsx diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_top_nav.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_top_nav.tsx index 512c8b5fe7ebc0..5e80bdf3ec97a5 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_top_nav.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_top_nav.tsx @@ -17,7 +17,7 @@ import { import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { EuiHorizontalRule, EuiToolTipProps } from '@elastic/eui'; +import { EuiHorizontalRule, EuiIcon, EuiToolTipProps } from '@elastic/eui'; import { getDashboardTitle, leaveConfirmStrings, @@ -145,10 +145,23 @@ export function DashboardTopNav({ embedSettings, redirectTo }: DashboardTopNavPr }, }, { - text: dashboardTitle, + text: + viewMode === ViewMode.EDIT ? ( + <> + {dashboardTitle} + + ) : ( + dashboardTitle + ), + onClick: + viewMode === ViewMode.EDIT + ? () => { + dashboard.showSettings(); + } + : undefined, }, ]); - }, [setBreadcrumbs, redirectTo, dashboardTitle]); + }, [setBreadcrumbs, redirectTo, dashboardTitle, dashboard, viewMode]); /** * Build app leave handler whenever hasUnsavedChanges changes diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.test.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.test.ts new file mode 100644 index 00000000000000..a781d1d74ee177 --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.test.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 { extractTitleAndCount } from './extract_title_and_count'; + +describe('extractTitleAndCount', () => { + it('extracts base title and copy count from a cloned dashboard title', () => { + expect(extractTitleAndCount('Test dashboard (1)')).toEqual(['Test dashboard', 1]); + expect(extractTitleAndCount('Test dashboard (2)')).toEqual(['Test dashboard', 2]); + expect(extractTitleAndCount('Test dashboard (200)')).toEqual(['Test dashboard', 200]); + expect(extractTitleAndCount('Test dashboard (1) (2) (3) (4) (5)')).toEqual([ + 'Test dashboard (1) (2) (3) (4)', + 5, + ]); + }); + + it('defaults to the count to 1 and returns the original title when the provided title does not contain a valid count', () => { + expect(extractTitleAndCount('Test dashboard')).toEqual(['Test dashboard', 1]); + expect(extractTitleAndCount('Test dashboard 2')).toEqual(['Test dashboard 2', 1]); + expect(extractTitleAndCount('Test dashboard (-1)')).toEqual(['Test dashboard (-1)', 1]); + expect(extractTitleAndCount('Test dashboard (0)')).toEqual(['Test dashboard (0)', 1]); + expect(extractTitleAndCount('Test dashboard (3.0)')).toEqual(['Test dashboard (3.0)', 1]); + expect(extractTitleAndCount('Test dashboard (8.4)')).toEqual(['Test dashboard (8.4)', 1]); + expect(extractTitleAndCount('Test dashboard (foo3.0)')).toEqual(['Test dashboard (foo3.0)', 1]); + expect(extractTitleAndCount('Test dashboard (bar7)')).toEqual(['Test dashboard (bar7)', 1]); + }); +}); diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.ts new file mode 100644 index 00000000000000..7100fab8af96df --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/lib/extract_title_and_count.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const extractTitleAndCount = (title: string): [string, number] => { + if (title.slice(-1) === ')') { + const startIndex = title.lastIndexOf(' ('); + const count = title.substring(startIndex + 2, title.lastIndexOf(')')); + if (!count.includes('.') && Number.isInteger(Number(count)) && Number(count) >= 1) { + const baseTitle = title.substring(0, startIndex); + return [baseTitle, Number(count)]; + } + } + return [title, 1]; +}; diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/clone_modal.test.js.snap b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/clone_modal.test.js.snap deleted file mode 100644 index 6c00faa6546d23..00000000000000 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/clone_modal.test.js.snap +++ /dev/null @@ -1,65 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders DashboardCloneModal 1`] = ` - - - - - - - - -

- -

-
- - -
- - - - - - - - -
-`; diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.test.js b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.test.js deleted file mode 100644 index bc88218a8e3881..00000000000000 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.test.js +++ /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 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 sinon from 'sinon'; -import { shallowWithI18nProvider, mountWithI18nProvider } from '@kbn/test-jest-helpers'; -import { findTestSubject } from '@elastic/eui/lib/test'; - -import { DashboardCloneModal } from './clone_modal'; - -let onClone; -let onClose; - -beforeEach(() => { - onClone = sinon.spy(); - onClose = sinon.spy(); -}); - -test('renders DashboardCloneModal', () => { - const component = shallowWithI18nProvider( - - ); - expect(component).toMatchSnapshot(); -}); - -test('onClone', () => { - const component = mountWithI18nProvider( - - ); - findTestSubject(component, 'cloneConfirmButton').simulate('click'); - sinon.assert.calledWith(onClone, 'dash title'); - sinon.assert.notCalled(onClose); -}); - -test('onClose', () => { - const component = mountWithI18nProvider( - - ); - findTestSubject(component, 'cloneCancelButton').simulate('click'); - sinon.assert.calledOnce(onClose); - sinon.assert.notCalled(onClone); -}); - -test('title', () => { - const component = mountWithI18nProvider( - - ); - const event = { target: { value: 'a' } }; - component.find('input').simulate('change', event); - findTestSubject(component, 'cloneConfirmButton').simulate('click'); - sinon.assert.calledWith(onClone, 'a'); -}); diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.tsx deleted file mode 100644 index 0408b85d27fef6..00000000000000 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/clone_modal.tsx +++ /dev/null @@ -1,203 +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 React, { Fragment } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { - EuiButton, - EuiButtonEmpty, - EuiFieldText, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiSpacer, - EuiText, - EuiCallOut, -} from '@elastic/eui'; - -interface Props { - onClone: ( - newTitle: string, - isTitleDuplicateConfirmed: boolean, - onTitleDuplicate: () => void - ) => Promise; - onClose: () => void; - title: string; -} - -interface State { - newDashboardName: string; - isTitleDuplicateConfirmed: boolean; - hasTitleDuplicate: boolean; - isLoading: boolean; -} - -export class DashboardCloneModal extends React.Component { - private isMounted = false; - - constructor(props: Props) { - super(props); - - this.state = { - newDashboardName: props.title, - isTitleDuplicateConfirmed: false, - hasTitleDuplicate: false, - isLoading: false, - }; - } - componentDidMount() { - this.isMounted = true; - } - - componentWillUnmount() { - this.isMounted = false; - } - - onTitleDuplicate = () => { - this.setState({ - isTitleDuplicateConfirmed: true, - hasTitleDuplicate: true, - }); - }; - - cloneDashboard = async () => { - this.setState({ - isLoading: true, - }); - - await this.props.onClone( - this.state.newDashboardName, - this.state.isTitleDuplicateConfirmed, - this.onTitleDuplicate - ); - - if (this.isMounted) { - this.setState({ - isLoading: false, - }); - } - }; - - onInputChange = (event: any) => { - this.setState({ - newDashboardName: event.target.value, - isTitleDuplicateConfirmed: false, - hasTitleDuplicate: false, - }); - }; - - renderDuplicateTitleCallout = () => { - if (!this.state.hasTitleDuplicate) { - return; - } - - return ( - - - -

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

-
-
- ); - }; - - render() { - return ( - - - - - - - - - -

- -

-
- - - - - - {this.renderDuplicateTitleCallout()} -
- - - - - - - - - - -
- ); - } -} diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/show_clone_modal.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/show_clone_modal.tsx deleted file mode 100644 index 6ebd6f7711717a..00000000000000 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/show_clone_modal.tsx +++ /dev/null @@ -1,72 +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 React from 'react'; -import { i18n } from '@kbn/i18n'; -import ReactDOM from 'react-dom'; - -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; - -import { DashboardCloneModal } from './clone_modal'; -import { pluginServices } from '../../../../services/plugin_services'; - -export interface ShowCloneModalProps { - onClose: () => void; - onClone: ( - newTitle: string, - isTitleDuplicateConfirmed: boolean, - onTitleDuplicate: () => void - ) => Promise<{ id?: string } | { error: Error }>; - title: string; -} - -export function showCloneModal({ onClone, title, onClose }: ShowCloneModalProps) { - const { - settings: { theme }, - } = pluginServices.getServices(); - - const container = document.createElement('div'); - const closeModal = () => { - ReactDOM.unmountComponentAtNode(container); - document.body.removeChild(container); - onClose(); - }; - - const onCloneConfirmed = async ( - newTitle: string, - isTitleDuplicateConfirmed: boolean, - onTitleDuplicate: () => void - ) => { - onClone(newTitle, isTitleDuplicateConfirmed, onTitleDuplicate).then( - (response: { id?: string } | { error: Error }) => { - // The only time you don't want to close the modal is if it's asking you - // to confirm a duplicate title, in which case there will be no error and no id. - if ((response as { error: Error }).error || (response as { id?: string }).id) { - closeModal(); - } - } - ); - }; - document.body.appendChild(container); - const element = ( - - - - - - ); - ReactDOM.render(element, container); -} diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx index 09eba955766c2b..ae13c70a739d63 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx @@ -15,10 +15,10 @@ import { DASHBOARD_CONTENT_ID, SAVED_OBJECT_POST_TIME } from '../../../dashboard import { DashboardSaveOptions, DashboardStateFromSaveModal } from '../../types'; import { DashboardSaveModal } from './overlays/save_modal'; import { DashboardContainer } from '../dashboard_container'; -import { showCloneModal } from './overlays/show_clone_modal'; import { pluginServices } from '../../../services/plugin_services'; import { DashboardContainerInput } from '../../../../common'; import { SaveDashboardReturn } from '../../../services/dashboard_content_management/types'; +import { extractTitleAndCount } from './lib/extract_title_and_count'; export function runSaveAs(this: DashboardContainer) { const { @@ -152,31 +152,41 @@ export async function runClone(this: DashboardContainer) { const { explicitInput: currentState } = this.getState(); - return new Promise((resolve) => { - const onClone = async ( - newTitle: string, - isTitleDuplicateConfirmed: boolean, - onTitleDuplicate: () => void - ) => { - if ( + return new Promise(async (resolve, reject) => { + try { + const [baseTitle, baseCount] = extractTitleAndCount(currentState.title); + let copyCount = baseCount; + let newTitle = `${baseTitle} (${copyCount})`; + while ( !(await checkForDuplicateDashboardTitle({ title: newTitle, - onTitleDuplicate, lastSavedTitle: currentState.title, copyOnSave: true, - isTitleDuplicateConfirmed, + isTitleDuplicateConfirmed: false, })) ) { - // do not clone if title is duplicate and is unconfirmed - return {}; + copyCount++; + newTitle = `${baseTitle} (${copyCount})`; } const saveResult = await saveDashboardState({ - saveOptions: { saveAsCopy: true }, - currentState: { ...currentState, title: newTitle }, + saveOptions: { + saveAsCopy: true, + }, + currentState: { + ...currentState, + title: newTitle, + }, }); resolve(saveResult); - return saveResult.id ? { id: saveResult.id } : { error: saveResult.error }; - }; - showCloneModal({ onClone, title: currentState.title, onClose: () => resolve(undefined) }); + return saveResult.id + ? { + id: saveResult.id, + } + : { + error: saveResult.error, + }; + } catch (error) { + reject(error); + } }); } diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/check_for_duplicate_dashboard_title.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/check_for_duplicate_dashboard_title.ts index 67fad986a1641e..0ffcf8c9788e96 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/check_for_duplicate_dashboard_title.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/check_for_duplicate_dashboard_title.ts @@ -14,7 +14,7 @@ export interface DashboardDuplicateTitleCheckProps { title: string; copyOnSave: boolean; lastSavedTitle: string; - onTitleDuplicate: () => void; + onTitleDuplicate?: () => void; isTitleDuplicateConfirmed: boolean; } diff --git a/test/accessibility/apps/dashboard.ts b/test/accessibility/apps/dashboard.ts index 8c2924a0901c17..32d198c7d5e023 100644 --- a/test/accessibility/apps/dashboard.ts +++ b/test/accessibility/apps/dashboard.ts @@ -18,7 +18,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Dashboard', () => { const dashboardName = 'Dashboard Listing A11y'; - const clonedDashboardName = 'Dashboard Listing A11y Copy'; + const clonedDashboardName = 'Dashboard Listing A11y (1)'; it('dashboard', async () => { await PageObjects.common.navigateToApp('dashboard'); @@ -132,11 +132,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await a11y.testAppSnapshot(); }); - it('Confirm clone with *copy* appended', async () => { - await PageObjects.dashboard.confirmClone(); - await a11y.testAppSnapshot(); - }); - it('Dashboard listing table', async () => { await PageObjects.dashboard.gotoDashboardLandingPage(); await a11y.testAppSnapshot(); diff --git a/test/functional/apps/dashboard/group4/dashboard_clone.ts b/test/functional/apps/dashboard/group4/dashboard_clone.ts index 26738760b28e46..c62c1a41959004 100644 --- a/test/functional/apps/dashboard/group4/dashboard_clone.ts +++ b/test/functional/apps/dashboard/group4/dashboard_clone.ts @@ -17,7 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('dashboard clone', function describeIndexTests() { const dashboardName = 'Dashboard Clone Test'; - const clonedDashboardName = dashboardName + ' Copy'; + const clonedDashboardName = dashboardName + ' (1)'; before(async function () { return PageObjects.dashboard.initTests(); @@ -31,7 +31,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.dashboard.saveDashboard(dashboardName); await PageObjects.dashboard.clickClone(); - await PageObjects.dashboard.confirmClone(); await PageObjects.dashboard.gotoDashboardLandingPage(); await listingTable.searchAndExpectItemsCount('dashboard', clonedDashboardName, 1); }); @@ -43,38 +42,5 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(panelTitles).to.eql(PageObjects.dashboard.getTestVisualizationNames()); }); }); - - it('clone appends Copy to the dashboard title name', async () => { - await PageObjects.dashboard.loadSavedDashboard(dashboardName); - await PageObjects.dashboard.clickClone(); - - const title = await PageObjects.dashboard.getCloneTitle(); - expect(title).to.be(clonedDashboardName); - }); - - it('and warns on duplicate name', async function () { - await PageObjects.dashboard.confirmClone(); - await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true }); - }); - - it("and doesn't save", async () => { - await PageObjects.dashboard.cancelClone(); - await PageObjects.dashboard.gotoDashboardLandingPage(); - - await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1); - }); - - it('Clones on confirm duplicate title warning', async function () { - await PageObjects.dashboard.loadSavedDashboard(dashboardName); - await PageObjects.dashboard.clickClone(); - - await PageObjects.dashboard.confirmClone(); - await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true }); - await PageObjects.dashboard.confirmClone(); - await PageObjects.dashboard.waitForRenderComplete(); - await PageObjects.dashboard.gotoDashboardLandingPage(); - - await listingTable.searchAndExpectItemsCount('dashboard', dashboardName + ' Copy', 2); - }); }); } diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts index 602f0f9d3fd929..897ceb5564d93c 100644 --- a/test/functional/page_objects/dashboard_page.ts +++ b/test/functional/page_objects/dashboard_page.ts @@ -212,24 +212,6 @@ export class DashboardPageObject extends FtrService { await this.testSubjects.click('dashboardClone'); } - public async getCloneTitle() { - return await this.testSubjects.getAttribute('clonedDashboardTitle', 'value'); - } - - public async confirmClone() { - this.log.debug('Confirming clone'); - await this.testSubjects.click('cloneConfirmButton'); - } - - public async cancelClone() { - this.log.debug('Canceling clone'); - await this.testSubjects.click('cloneCancelButton'); - } - - public async setClonedDashboardTitle(title: string) { - await this.testSubjects.setValue('clonedDashboardTitle', title); - } - /** * Asserts that the duplicate title warning is either displayed or not displayed. * @param { displayed: boolean } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 654e2259983cd2..730b9def5cfba3 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -1114,9 +1114,6 @@ "dashboard.panelStorageError.setError": "Une erreur s'est produite lors de la définition des modifications non enregistrées : {message}", "dashboard.share.defaultDashboardTitle": "Tableau de bord [{date}]", "dashboard.strings.dashboardEditTitle": "Modification de {title}", - "dashboard.topNav.cloneModal.dashboardExistsDescription": "Cliquez sur {confirmClone} pour cloner le tableau de bord avec le titre dupliqué.", - "dashboard.topNav.cloneModal.dashboardExistsTitle": "Il existe déjà un tableau de bord avec le titre {newDashboardName}.", - "dashboard.topNav.showCloneModal.dashboardCopyTitle": "Copie de {title}", "dashboard.actions.DownloadCreateDrilldownAction.displayName": "Télécharger au format CSV", "dashboard.actions.downloadOptionsUnsavedFilename": "sans titre", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "Minimiser", @@ -1128,7 +1125,6 @@ "dashboard.appLeaveConfirmModal.unsavedChangesTitle": "Modifications non enregistrées", "dashboard.badge.readOnly.text": "Lecture seule", "dashboard.badge.readOnly.tooltip": "Impossible d'enregistrer les tableaux de bord", - "dashboard.cloneModal.cloneDashboardTitleAriaLabel": "Titre du tableau de bord cloné", "dashboard.createConfirmModal.cancelButtonLabel": "Annuler", "dashboard.createConfirmModal.confirmButtonLabel": "Redémarrer", "dashboard.createConfirmModal.continueButtonLabel": "Poursuivre les modifications", @@ -1221,11 +1217,6 @@ "dashboard.solutionToolbar.addPanelButtonLabel": "Créer une visualisation", "dashboard.solutionToolbar.editorMenuButtonLabel": "Sélectionner un type", "dashboard.solutionToolbar.quickCreateButtonGroupLegend": "Raccourcis vers les types de visualisation populaires", - "dashboard.topNav.cloneModal.cancelButtonLabel": "Annuler", - "dashboard.topNav.cloneModal.cloneDashboardModalHeaderTitle": "Cloner le tableau de bord", - "dashboard.topNav.cloneModal.confirmButtonLabel": "Confirmer le clonage", - "dashboard.topNav.cloneModal.confirmCloneDescription": "Confirmer le clonage", - "dashboard.topNav.cloneModal.enterNewNameForDashboardDescription": "Veuillez saisir un autre nom pour votre tableau de bord.", "dashboard.topNav.labsButtonAriaLabel": "ateliers", "dashboard.topNav.labsConfigDescription": "Ateliers", "dashboard.topNav.saveModal.objectType": "tableau de bord", @@ -39433,4 +39424,4 @@ "xpack.painlessLab.title": "Painless Lab", "xpack.painlessLab.walkthroughButtonLabel": "Présentation" } -} \ 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 70ae6e7263d36f..3b16e422bdef5f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1114,9 +1114,6 @@ "dashboard.panelStorageError.setError": "保存されていない変更の設定中にエラーが発生しました:{message}", "dashboard.share.defaultDashboardTitle": "ダッシュボード[{date}]", "dashboard.strings.dashboardEditTitle": "{title}の編集中", - "dashboard.topNav.cloneModal.dashboardExistsDescription": "{confirmClone}をクリックして重複タイトルでダッシュボードのクローンを作成します。", - "dashboard.topNav.cloneModal.dashboardExistsTitle": "「{newDashboardName}」というタイトルのダッシュボードがすでに存在します。", - "dashboard.topNav.showCloneModal.dashboardCopyTitle": "{title}コピー", "dashboard.actions.DownloadCreateDrilldownAction.displayName": "CSV をダウンロード", "dashboard.actions.downloadOptionsUnsavedFilename": "無題", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "最小化", @@ -1128,7 +1125,6 @@ "dashboard.appLeaveConfirmModal.unsavedChangesTitle": "保存されていない変更", "dashboard.badge.readOnly.text": "読み取り専用", "dashboard.badge.readOnly.tooltip": "ダッシュボードを保存できません", - "dashboard.cloneModal.cloneDashboardTitleAriaLabel": "クローンダッシュボードタイトル", "dashboard.createConfirmModal.cancelButtonLabel": "キャンセル", "dashboard.createConfirmModal.confirmButtonLabel": "やり直す", "dashboard.createConfirmModal.continueButtonLabel": "編集を続行", @@ -1221,11 +1217,6 @@ "dashboard.solutionToolbar.addPanelButtonLabel": "ビジュアライゼーションを作成", "dashboard.solutionToolbar.editorMenuButtonLabel": "タイプを選択してください", "dashboard.solutionToolbar.quickCreateButtonGroupLegend": "よく使用されるビジュアライゼーションタイプへのショートカット", - "dashboard.topNav.cloneModal.cancelButtonLabel": "キャンセル", - "dashboard.topNav.cloneModal.cloneDashboardModalHeaderTitle": "ダッシュボードのクローンを作成", - "dashboard.topNav.cloneModal.confirmButtonLabel": "クローンの確認", - "dashboard.topNav.cloneModal.confirmCloneDescription": "クローンの確認", - "dashboard.topNav.cloneModal.enterNewNameForDashboardDescription": "ダッシュボードの新しい名前を入力してください。", "dashboard.topNav.labsButtonAriaLabel": "ラボ", "dashboard.topNav.labsConfigDescription": "ラボ", "dashboard.topNav.saveModal.objectType": "ダッシュボード", @@ -39407,4 +39398,4 @@ "xpack.painlessLab.title": "Painless Lab", "xpack.painlessLab.walkthroughButtonLabel": "実地検証" } -} \ 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 0bba12b9495e17..0443aa6e236cab 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1114,9 +1114,6 @@ "dashboard.panelStorageError.setError": "设置未保存更改时遇到错误:{message}", "dashboard.share.defaultDashboardTitle": "仪表板 [{date}]", "dashboard.strings.dashboardEditTitle": "正在编辑 {title}", - "dashboard.topNav.cloneModal.dashboardExistsDescription": "单击“{confirmClone}”以克隆具有重复标题的仪表板。", - "dashboard.topNav.cloneModal.dashboardExistsTitle": "具有标题 {newDashboardName} 的仪表板已存在。", - "dashboard.topNav.showCloneModal.dashboardCopyTitle": "{title} 副本", "dashboard.actions.DownloadCreateDrilldownAction.displayName": "下载为 CSV", "dashboard.actions.downloadOptionsUnsavedFilename": "未命名", "dashboard.actions.toggleExpandPanelMenuItem.expandedDisplayName": "最小化", @@ -1128,7 +1125,6 @@ "dashboard.appLeaveConfirmModal.unsavedChangesTitle": "未保存的更改", "dashboard.badge.readOnly.text": "只读", "dashboard.badge.readOnly.tooltip": "无法保存仪表板", - "dashboard.cloneModal.cloneDashboardTitleAriaLabel": "克隆仪表板标题", "dashboard.createConfirmModal.cancelButtonLabel": "取消", "dashboard.createConfirmModal.confirmButtonLabel": "重头开始", "dashboard.createConfirmModal.continueButtonLabel": "继续编辑", @@ -1221,11 +1217,6 @@ "dashboard.solutionToolbar.addPanelButtonLabel": "创建可视化", "dashboard.solutionToolbar.editorMenuButtonLabel": "选择类型", "dashboard.solutionToolbar.quickCreateButtonGroupLegend": "常用可视化类型的快捷键", - "dashboard.topNav.cloneModal.cancelButtonLabel": "取消", - "dashboard.topNav.cloneModal.cloneDashboardModalHeaderTitle": "克隆仪表板", - "dashboard.topNav.cloneModal.confirmButtonLabel": "确认克隆", - "dashboard.topNav.cloneModal.confirmCloneDescription": "确认克隆", - "dashboard.topNav.cloneModal.enterNewNameForDashboardDescription": "请为您的仪表板输入新的名称。", "dashboard.topNav.labsButtonAriaLabel": "实验", "dashboard.topNav.labsConfigDescription": "实验", "dashboard.topNav.saveModal.objectType": "仪表板", @@ -39401,4 +39392,4 @@ "xpack.painlessLab.title": "Painless 实验室", "xpack.painlessLab.walkthroughButtonLabel": "指导" } -} \ No newline at end of file +} From 7886d8ae5e16fee0216e47bda43147447ab458b7 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Sat, 1 Jul 2023 01:00:44 -0400 Subject: [PATCH 03/98] [api-docs] 2023-07-01 Daily api_docs build (#161052) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/385 --- api_docs/actions.devdocs.json | 25 +++ api_docs/actions.mdx | 4 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.devdocs.json | 85 ++------ api_docs/charts.mdx | 4 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/ess_security.mdx | 2 +- api_docs/event_annotation.devdocs.json | 6 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.devdocs.json | 8 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.devdocs.json | 12 +- 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.devdocs.json | 8 +- 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.devdocs.json | 4 +- 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.devdocs.json | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.devdocs.json | 46 +++-- api_docs/kbn_cell_actions.mdx | 4 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- 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 | 8 + api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- 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 +- ...cts_migration_server_internal.devdocs.json | 26 ++- ...aved_objects_migration_server_internal.mdx | 4 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- ...n_management_cards_navigation.devdocs.json | 191 ++++++++++++++++++ api_docs/kbn_management_cards_navigation.mdx | 39 ++++ ...n_management_storybook_config.devdocs.json | 62 ++++++ api_docs/kbn_management_storybook_config.mdx | 30 +++ api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.devdocs.json | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.devdocs.json | 34 ++++ api_docs/management.mdx | 4 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 20 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.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 | 2 + api_docs/triggers_actions_ui.mdx | 4 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 558 files changed, 1034 insertions(+), 666 deletions(-) create mode 100644 api_docs/kbn_management_cards_navigation.devdocs.json create mode 100644 api_docs/kbn_management_cards_navigation.mdx create mode 100644 api_docs/kbn_management_storybook_config.devdocs.json create mode 100644 api_docs/kbn_management_storybook_config.mdx diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index cf8e0ca6a5155a..c79b223c1b7f3f 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -2412,6 +2412,17 @@ "path": "x-pack/plugins/actions/server/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "actions", + "id": "def-server.ActionResult.isSystemAction", + "type": "boolean", + "tags": [], + "label": "isSystemAction", + "description": [], + "path": "x-pack/plugins/actions/server/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -2651,6 +2662,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "actions", + "id": "def-server.ActionType.isSystemAction", + "type": "CompoundType", + "tags": [], + "label": "isSystemAction", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/actions/server/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "actions", "id": "def-server.ActionType.renderParameterTemplates", diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index e4059a185d67fc..06c63a8c971e26 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 268 | 10 | 263 | 27 | +| 270 | 10 | 265 | 27 | ## Client diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index c66454a419263f..c6d7d26c63e1cb 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 79d62cf6f7adf7..6ecac7bcaea236 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-06-30 +date: 2023-07-01 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 b0c136fe1f236c..4af04d872e2394 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-06-30 +date: 2023-07-01 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 9ff7b42cdc6b6a..37ac435398734e 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 6ce00c0fb8669a..aa931db319a6c3 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-06-30 +date: 2023-07-01 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 fb9c9b73b8ae1c..0123b23518fff1 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-06-30 +date: 2023-07-01 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 4844ba6bce50a2..e174bfa09b8e89 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-06-30 +date: 2023-07-01 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 c6f7616af2acef..0ffbd670d9015d 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-06-30 +date: 2023-07-01 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 e3c7e3cea65220..e6a9241261ae22 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.devdocs.json b/api_docs/charts.devdocs.json index c2c62ac98565d3..abf1df83078594 100644 --- a/api_docs/charts.devdocs.json +++ b/api_docs/charts.devdocs.json @@ -1626,28 +1626,6 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.truncatedColorSchemas", - "type": "Array", - "tags": [], - "label": "truncatedColorSchemas", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.ColorSchema", - "text": "ColorSchema" - }, - "[]" - ], - "path": "src/plugins/charts/common/static/color_maps/truncated_color_maps.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false } ], "objects": [ @@ -1834,19 +1812,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-public.truncatedColorMaps", - "type": "Object", - "tags": [], - "label": "truncatedColorMaps", - "description": [], - "path": "src/plugins/charts/common/static/color_maps/truncated_color_maps.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-public.vislibColorMaps", @@ -3378,6 +3343,21 @@ } ], "misc": [ + { + "parentPluginId": "charts", + "id": "def-common.AllowedChartOverrides", + "type": "Type", + "tags": [], + "label": "AllowedChartOverrides", + "description": [], + "signature": [ + "{ chart?: { description?: string | undefined; title?: string | undefined; } | undefined; }" + ], + "path": "src/plugins/charts/common/static/overrides/settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "charts", "id": "def-common.AllowedSettingsOverrides", @@ -3609,28 +3589,6 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-common.truncatedColorSchemas", - "type": "Array", - "tags": [], - "label": "truncatedColorSchemas", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.ColorSchema", - "text": "ColorSchema" - }, - "[]" - ], - "path": "src/plugins/charts/common/static/color_maps/truncated_color_maps.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false } ], "objects": [ @@ -3817,19 +3775,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-common.truncatedColorMaps", - "type": "Object", - "tags": [], - "label": "truncatedColorMaps", - "description": [], - "path": "src/plugins/charts/common/static/color_maps/truncated_color_maps.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-common.vislibColorMaps", diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 3425efc5094546..8a92de2f2759e0 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.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 | |-------------------|-----------|------------------------|-----------------| -| 271 | 16 | 256 | 10 | +| 268 | 16 | 253 | 10 | ## Client diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index eb31c684c9d3a8..1e7ffe0d05f197 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index da6d338953ea66..eeec8c7620b042 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index e89d26d4633d95..97f0420608ec91 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 85c3f9decab957..3816605ce1bef0 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-06-30 +date: 2023-07-01 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 79333feecc9bbe..072abbe09deeb8 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-06-30 +date: 2023-07-01 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 fe046ab8337ad9..077e6a1ec85258 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-06-30 +date: 2023-07-01 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 a62a0e8209dff2..42f4bfbf226dd2 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-06-30 +date: 2023-07-01 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 e04d9ceb461b57..9cce614a030661 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-06-30 +date: 2023-07-01 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 cb6873c7ab74cd..e813c7511e6eb1 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 af0579a61f9421..fadd1e1348bb23 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-06-30 +date: 2023-07-01 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 0af4c903bec62f..2cbf1b7f35cc98 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-06-30 +date: 2023-07-01 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 e360eded64ab81..d03dbee720c0f6 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-06-30 +date: 2023-07-01 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 c5ce53d1f8b664..6e92d23d8d236f 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-06-30 +date: 2023-07-01 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 9ecf8580ab7623..37d2cc897faeed 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-06-30 +date: 2023-07-01 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 ce841f73084a6b..91bafcbb7bec41 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-06-30 +date: 2023-07-01 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 5eddd6d09b2ac1..2d05f5867f6e02 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-06-30 +date: 2023-07-01 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 2159e38e384687..4631d427203bbc 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-06-30 +date: 2023-07-01 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 d69b6df539cd26..0681e67455300d 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-06-30 +date: 2023-07-01 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 154f8b8cf5da3f..eea4362f80dc3d 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 44bd02caec7029..533b3932c76679 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-06-30 +date: 2023-07-01 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 b06578e5105c39..69bf17c8f45824 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index aabc7eaaaa8892..f3cc6dbcdc2af3 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index fc10a044869ca1..bd42999b8bb391 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index ed9272a818d877..261808e397ef05 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 28a1d98a08541e..2b430ebfc1bae0 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-06-30 +date: 2023-07-01 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 eaa7e9dc5f3786..9784bf7b83c719 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-06-30 +date: 2023-07-01 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 df3a1d0c882f67..f99a9214582d7c 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-06-30 +date: 2023-07-01 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 ba0c81fe3d5327..aae1a53406e64a 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index f1d93502a483ec..237172dcfa41f1 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-06-30 +date: 2023-07-01 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 0e59e0fb9a7aae..516bb43480f2a6 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-06-30 +date: 2023-07-01 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 337857d40fed0b..69dd9145dc9a2f 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-06-30 +date: 2023-07-01 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 07ccebc213360e..bd8f0ede8bd7c6 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-06-30 +date: 2023-07-01 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 c04f0a59a21bb3..09fa5cc06c6f65 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 399b025106548d..8577b01233fb3e 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.devdocs.json b/api_docs/event_annotation.devdocs.json index 32aa51ade4db3d..3b205ea85a4728 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -1752,7 +1752,7 @@ "label": "AvailableAnnotationIcon", "description": [], "signature": [ - "\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\"" + "\"alert\" | \"circle\" | \"tag\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"triangle\"" ], "path": "src/plugins/event_annotation/common/types.ts", "deprecated": false, @@ -2545,7 +2545,7 @@ "label": "options", "description": [], "signature": [ - "(\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\")[]" + "(\"alert\" | \"circle\" | \"tag\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"triangle\")[]" ], "path": "src/plugins/event_annotation/common/manual_event_annotation/index.ts", "deprecated": false, @@ -3712,7 +3712,7 @@ "label": "options", "description": [], "signature": [ - "(\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\")[]" + "(\"alert\" | \"circle\" | \"tag\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"triangle\")[]" ], "path": "src/plugins/event_annotation/common/query_point_event_annotation/index.ts", "deprecated": false, diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index f91cb517feb635..bde82301dcc6d0 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 3f92b5605985c2..2a3df496eafcf5 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-06-30 +date: 2023-07-01 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 f4500594093aae..b7b6099efa62b9 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-06-30 +date: 2023-07-01 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 e5740a73695052..8ed4d17443c564 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.devdocs.json b/api_docs/expression_gauge.devdocs.json index b3767918876fb1..eb53b79bbe0444 100644 --- a/api_docs/expression_gauge.devdocs.json +++ b/api_docs/expression_gauge.devdocs.json @@ -1185,9 +1185,9 @@ "section": "def-common.FormatFactory", "text": "FormatFactory" }, - "; chartsThemeService: ", - "Theme", - "; paletteService: ", + "; chartsThemeService: Omit<", + "ThemeService", + ", \"init\">; paletteService: ", { "pluginId": "@kbn/coloring", "scope": "common", @@ -1265,7 +1265,7 @@ "CustomXDomain", " | undefined>; ariaDescription?: string | undefined; ariaDescribedBy?: string | undefined; ariaLabelledBy?: string | undefined; ariaTableCaption?: string | undefined; legendAction?: \"ignore\" | undefined; legendStrategy?: ", "LegendStrategy", - " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>>) | undefined; }" + " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> & Partial>) | undefined; }" ], "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", "deprecated": false, diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 7def1b81a5a4fe..7e6a06f626ecaa 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.devdocs.json b/api_docs/expression_heatmap.devdocs.json index 50e3f743d7330f..91fc345d8f6c30 100644 --- a/api_docs/expression_heatmap.devdocs.json +++ b/api_docs/expression_heatmap.devdocs.json @@ -488,12 +488,12 @@ { "parentPluginId": "expressionHeatmap", "id": "def-common.HeatmapExpressionProps.overrides", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "overrides", "description": [], "signature": [ - "Partial; ariaDescription?: string | undefined; ariaDescribedBy?: string | undefined; ariaLabelledBy?: string | undefined; ariaTableCaption?: string | undefined; legendAction?: \"ignore\" | undefined; legendStrategy?: ", "LegendStrategy", - " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> | undefined" + " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> & Partial>) | undefined" ], "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_functions.ts", "deprecated": false, @@ -869,9 +869,9 @@ "section": "def-common.FormatFactory", "text": "FormatFactory" }, - "; chartsThemeService: ", - "Theme", - "; chartsActiveCursorService: ", + "; chartsThemeService: Omit<", + "ThemeService", + ", \"init\">; chartsActiveCursorService: ", "ActiveCursor", "; datatableUtilities: ", { diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index bbcc3e7b554f2f..34f08c006711b0 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-06-30 +date: 2023-07-01 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 67dddb60149ec3..7f87e4fda94954 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-06-30 +date: 2023-07-01 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 83a31df66a811c..4b526292a9213e 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-06-30 +date: 2023-07-01 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 58dc2b1d884751..82e89d4c0c092a 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.devdocs.json b/api_docs/expression_metric_vis.devdocs.json index 22d54b78b9e6dd..dfd0f3a000d80c 100644 --- a/api_docs/expression_metric_vis.devdocs.json +++ b/api_docs/expression_metric_vis.devdocs.json @@ -863,12 +863,12 @@ { "parentPluginId": "expressionMetricVis", "id": "def-common.MetricVisRenderConfig.overrides", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "overrides", "description": [], "signature": [ - "Partial; ariaDescription?: string | undefined; ariaDescribedBy?: string | undefined; ariaLabelledBy?: string | undefined; ariaTableCaption?: string | undefined; legendAction?: \"ignore\" | undefined; legendStrategy?: ", "LegendStrategy", - " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> | undefined" + " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> & Partial>) | undefined" ], "path": "src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts", "deprecated": false, @@ -1012,7 +1012,7 @@ "label": "AvailableMetricIcon", "description": [], "signature": [ - "\"alert\" | \"temperature\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"compute\" | \"editorComment\" | \"empty\" | \"flag\" | \"globe\" | \"heart\" | \"mapMarker\" | \"pin\" | \"sortDown\" | \"sortUp\" | \"starEmpty\" | \"tag\"" + "\"alert\" | \"tag\" | \"temperature\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"compute\" | \"editorComment\" | \"empty\" | \"flag\" | \"globe\" | \"heart\" | \"mapMarker\" | \"pin\" | \"sortDown\" | \"sortUp\" | \"starEmpty\"" ], "path": "src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts", "deprecated": false, diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 0c4232609f3f0b..ba3603fab4fa52 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-06-30 +date: 2023-07-01 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 813bc296286a24..e5429937e2485d 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-06-30 +date: 2023-07-01 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 f20a7524b60b55..d95270262d9545 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-06-30 +date: 2023-07-01 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 f9b6ba47e74338..a019b70928a03a 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-06-30 +date: 2023-07-01 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 ef603320e6d0f4..2caec4f4ca51d6 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-06-30 +date: 2023-07-01 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 2ba509c870682b..ea2bfa46792d98 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.devdocs.json b/api_docs/expression_x_y.devdocs.json index 48f2615fc4e12e..dea5fb9e26e9dd 100644 --- a/api_docs/expression_x_y.devdocs.json +++ b/api_docs/expression_x_y.devdocs.json @@ -1950,7 +1950,7 @@ "CustomXDomain", " | undefined>; ariaDescription?: string | undefined; ariaDescribedBy?: string | undefined; ariaLabelledBy?: string | undefined; ariaTableCaption?: string | undefined; legendAction?: \"ignore\" | undefined; legendStrategy?: ", "LegendStrategy", - " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>>) | undefined" + " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> & Partial>) | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts", "deprecated": false, @@ -2236,7 +2236,7 @@ "label": "AvailableReferenceLineIcon", "description": [], "signature": [ - "\"alert\" | \"circle\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"empty\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\"" + "\"alert\" | \"circle\" | \"tag\" | \"asterisk\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"empty\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"triangle\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 3b89a347dbf57e..5909216b9cfbf1 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-06-30 +date: 2023-07-01 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 fc95731a8a0b63..8085fe47d034e4 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-06-30 +date: 2023-07-01 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 127c2d2822f6f2..6513d046fadcf2 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-06-30 +date: 2023-07-01 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 687978bccc8add..d7b0f942c6de20 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-06-30 +date: 2023-07-01 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 ad991578c2ab93..9389f24e97ccc7 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index 6b2aba6f8174f5..40f738a455dc1f 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -2058,7 +2058,7 @@ "tags": [], "label": "indexIsAlias", "description": [ - "\nTreat the indices provided as Aliases. If set to true, ES `search()` will be used to\nretrieve the file info and content instead of `get()`. This is needed to ensure the\ncontent can be retrieved in cases where an index may have rolled over (ES `get()`\nneeds a \"real\" index)" + "\nTreat the indices provided as Aliases/Datastreams.\nWhen set to `true`:\n- additional ES calls will be made to get the real backing indexes\n- will not check if indexes exists and attempt to create them if not\n- an additional `@timestamp` property will be written to all documents (at root of document)" ], "signature": [ "boolean | undefined" diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 4e809c08a8c475..9a52c4cbdff2f6 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-06-30 +date: 2023-07-01 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 8a3d40d0b91910..7e4330582ece45 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 4cb5430104b851..ed61b04e05a384 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-06-30 +date: 2023-07-01 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 e5ea2aeecd2a77..834c8f25531a49 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-06-30 +date: 2023-07-01 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 e53b84ea30c451..27ba62f7037dc1 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-06-30 +date: 2023-07-01 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 c006f13e44f545..c88c52fa2468cb 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-06-30 +date: 2023-07-01 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 37874756ae600b..2afbcab16f41a0 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-06-30 +date: 2023-07-01 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 5e7e7abc133785..e8eb7427670671 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 9ba60a392c0cb8..cc1c3805f7f955 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 a95d95b2f1ae8f..35456b77cccdd6 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 46015cb7fdf45e..5fc344716d6ea9 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-06-30 +date: 2023-07-01 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 d95fbef2f92edd..15d235dcae78ee 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-06-30 +date: 2023-07-01 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 97e504fba24a2a..965fb6558c4ee8 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index ec58624389c647..20bce145bd15d1 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-06-30 +date: 2023-07-01 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 284ab00535c41b..cd446b3cc5368a 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 726cb14e740fff..35cdf41d7371b3 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 95ccd9d0321104..722291a196303a 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 a7589efb2149e7..84dad5db99bc53 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-06-30 +date: 2023-07-01 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 e9892d94dfaa1a..65dedf5271500d 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-06-30 +date: 2023-07-01 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 287ebd767d02b1..087b1f64302d6c 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index f2ace21d05cb0e..eb575a7303ea25 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 03c8672a9ef255..55c8403918918d 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-06-30 +date: 2023-07-01 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 bbc79116ad84de..e24218328119d8 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-06-30 +date: 2023-07-01 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 8121eecbf5b144..a1820cf184fd16 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 30fd472fb29e71..c098c30d40e6f4 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index dfd07d3e9a68de..a0406b2cb9a631 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-06-30 +date: 2023-07-01 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 6fcab3e9754fcb..c93053e2337e6d 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-06-30 +date: 2023-07-01 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 4e7c5470ccfc60..dccbd6d70f6ab8 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-06-30 +date: 2023-07-01 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 c8d7ad44036384..061e9d19ea5a48 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 cf766ee6c35127..9b84e7c15b0ea9 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 4b8dc25f45ac9d..74349c25f4c361 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.devdocs.json b/api_docs/kbn_cell_actions.devdocs.json index a25ef677ee34e6..dcc406e62c1d00 100644 --- a/api_docs/kbn_cell_actions.devdocs.json +++ b/api_docs/kbn_cell_actions.devdocs.json @@ -36,13 +36,7 @@ "text": "FilterManager" }, " | undefined; fieldName: string; value: ", - { - "pluginId": "@kbn/cell-actions", - "scope": "common", - "docId": "kibKbnCellActionsPluginApi", - "section": "def-common.CellActionFieldValue", - "text": "CellActionFieldValue" - }, + "DefaultActionsSupportedValue", "; }) => void" ], "path": "packages/kbn-cell-actions/src/actions/filter/filter_in.ts", @@ -100,7 +94,7 @@ "label": "value", "description": [], "signature": [ - "string | number | boolean | string[] | boolean[] | number[] | null | undefined" + "string[] | boolean[] | number[]" ], "path": "packages/kbn-cell-actions/src/actions/filter/filter_in.ts", "deprecated": false, @@ -129,13 +123,7 @@ "text": "FilterManager" }, " | undefined; fieldName: string; value: ", - { - "pluginId": "@kbn/cell-actions", - "scope": "common", - "docId": "kibKbnCellActionsPluginApi", - "section": "def-common.CellActionFieldValue", - "text": "CellActionFieldValue" - }, + "DefaultActionsSupportedValue", "; }) => void" ], "path": "packages/kbn-cell-actions/src/actions/filter/filter_out.ts", @@ -193,7 +181,7 @@ "label": "value", "description": [], "signature": [ - "string | number | boolean | string[] | boolean[] | number[] | null | undefined" + "string[] | boolean[] | number[]" ], "path": "packages/kbn-cell-actions/src/actions/filter/filter_out.ts", "deprecated": false, @@ -460,6 +448,14 @@ "section": "def-public.FilterManager", "text": "FilterManager" }, + "; notifications: ", + { + "pluginId": "@kbn/core-notifications-browser", + "scope": "common", + "docId": "kibKbnCoreNotificationsBrowserPluginApi", + "section": "def-common.NotificationsStart", + "text": "NotificationsStart" + }, "; }) => ", { "pluginId": "@kbn/cell-actions", @@ -524,6 +520,14 @@ "section": "def-public.FilterManager", "text": "FilterManager" }, + "; notifications: ", + { + "pluginId": "@kbn/core-notifications-browser", + "scope": "common", + "docId": "kibKbnCoreNotificationsBrowserPluginApi", + "section": "def-common.NotificationsStart", + "text": "NotificationsStart" + }, "; }) => ", { "pluginId": "@kbn/cell-actions", @@ -1273,7 +1277,15 @@ "label": "CellActionFieldValue", "description": [], "signature": [ - "string | number | boolean | string[] | boolean[] | number[] | null | undefined" + "string[] | undefined[] | boolean[] | number[] | ", + { + "pluginId": "@kbn/utility-types", + "scope": "common", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-common.Serializable", + "text": "Serializable" + }, + " | null[]" ], "path": "packages/kbn-cell-actions/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index b33eb81b6a1a29..a7639c73f45498 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-threat-hunting-explore](https://github.com/orgs/elast | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 62 | 1 | 44 | 2 | +| 62 | 1 | 44 | 3 | ## Common diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index cd02912cf61ccf..8e04f5febc8ed8 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-06-30 +date: 2023-07-01 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 5a84b25e188dde..161b4de98ccd3a 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-06-30 +date: 2023-07-01 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 9baba9fced13ba..9eb6321ce39286 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-06-30 +date: 2023-07-01 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 48b91ddeb3ff00..9772ad1fd78f79 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-06-30 +date: 2023-07-01 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 9c33e19d0ac89a..367a6b85328fa3 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-06-30 +date: 2023-07-01 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 2fc809b21c27dd..bb4ea84bea7c80 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-06-30 +date: 2023-07-01 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 a816cd623cbd07..76d7b5bc026e93 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 67573c599cc48e..5e6056b43a6c49 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 25e3b0e8d28c60..5abd935b63062b 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-06-30 +date: 2023-07-01 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 b0b76d58ad9d50..9123b8f8ce7fc4 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-06-30 +date: 2023-07-01 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 914fd72c83af5d..7efea03d18f2eb 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 e1f235e1d21273..11d07d7ad553e9 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-06-30 +date: 2023-07-01 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 83b44191d3e769..8c8263f8643ebb 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-06-30 +date: 2023-07-01 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 5b4aa6403c757f..dc2fbbd422a9b7 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-06-30 +date: 2023-07-01 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 4a643f4abd01bb..76001ca2d5509b 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 36fc8b77b88192..5d86eb8efd1bb0 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-06-30 +date: 2023-07-01 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 81f91c52398cec..bb210a21276c13 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 d9cbd1dcfeb849..34150bc49e1c1f 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 69751397230946..1c02569c26d927 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 57b0b1005246f1..4c6c943d247b64 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 6e95e325b85134..6584f83892231b 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-06-30 +date: 2023-07-01 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 fea858147789db..cf1df4a50f6972 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 4926468326f17d..ad50dbe580f7d5 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 5eec364c82a913..5517f3b95e92da 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 a42591a619af6e..673b705af68705 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 a7f3dc9896fa8b..a4498502822f79 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c787874beccfa9..48c0f559c575f6 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-06-30 +date: 2023-07-01 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 4c4bd50d635572..d6becbd96821a8 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 c9ce8b9ef4ffb7..dd72ba1615c106 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 04fb2016aac807..e0e5f64b773390 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 2a8cdfb9e35aab..285d6e59a0bb2e 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 3c2e12d30eb997..02db0a935e8cbd 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-06-30 +date: 2023-07-01 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 94bf124c8443d2..0839bcacd4d101 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 b5b2de345636fb..7fbee73954fa21 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c0162cc0508d9e..431b353bd4000e 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 b6c64bd693f11f..88fd69febeb623 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-06-30 +date: 2023-07-01 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 d7719d9c61f058..2415ecf9db7565 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-06-30 +date: 2023-07-01 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 3e36e267542d76..f40fc3e1dc0b8a 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 a98f34d29414af..a54869dad417d4 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 9971dd240ee010..f79f870e9cae62 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 73f6d07157fc6d..176e96ae00c66a 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 4dd4c46bdaf4c6..5c2eedb83c3889 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 a3eb72d395357e..9cc30b7ee6941c 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 f56893f9807c8f..0c1c964a700f30 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 27a4e3f2487864..2fa50712a44937 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-06-30 +date: 2023-07-01 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 9fc4ff8f05bc2e..7f43fe91bc3a04 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-06-30 +date: 2023-07-01 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 0f2bdd55f8b341..dc232f748612cd 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 c13ea492a7c122..aed66c612e6d2f 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 705af1a99f7e6a..aa984e1f77cd1a 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 fcdb41ea8ec35d..1b664b4d9eb7c9 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 48bad509c8b750..ffa08a48efb781 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 2a3d480017da6f..7597d906d36c5f 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-06-30 +date: 2023-07-01 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 3adc0a462aec11..222e5308a34d6b 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-06-30 +date: 2023-07-01 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 19b6c3861807ff..538757036af87a 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 7fec2cfc9e9a75..bdba34782c752a 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 34fa37a32b7916..6cd962bcb0c63d 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 14b71b77064773..9c54bbd8da94c7 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 39efaa80587c8c..93195e54f67650 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-06-30 +date: 2023-07-01 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 85c2fb294ecbfd..70b3f703355bfe 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c989fe7b121fad..ceb6eabdfd911e 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 e9301439b6ed0f..56db9ab357dcf4 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c6702cd7c050f9..3e43aab5895192 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-06-30 +date: 2023-07-01 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 d135ff737655e8..9d174e26a16f79 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 8d7e4fdb80df19..957ae12e27c2cd 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 a0cbc632376981..9def52d5d31306 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 85b2b29711d5ea..640d9382efb011 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 9a4bff32924637..e1568c5f0f0fac 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 44fa0c99cac009..48b7c375bef4fa 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 b6fb4bb8b7abf3..c4842434dc45bf 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c2ca321287b084..b031df83beed9c 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-06-30 +date: 2023-07-01 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 33a8a9c730e4e0..13451b79366c2a 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-06-30 +date: 2023-07-01 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 d86a751f18d6d4..18d85afc81be59 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 6b3d182746dd04..9caca36c4673b1 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 8d6ec4e81ace1f..4f0c4d626c11a5 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 94604c98e9a1de..f88999fa831513 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 57198beac077e7..f40d2286787084 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 a769b60950ea0f..dee354ca07e8b3 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 6830558759b941..6e8d24f2423b8b 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 7f4e3aa97d4fac..d67c75668cdc93 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-06-30 +date: 2023-07-01 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 44e850dd73eaf1..0c3ebe8b2e3584 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 58c73ddf9155f3..125f06f0fd5446 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-06-30 +date: 2023-07-01 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 0e251aca15b30a..06ed029830dc8f 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-06-30 +date: 2023-07-01 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 104637ea97997d..00b4b2462966c7 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 e36512c4a18f19..e796110feb5399 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 89d0c5b958eccc..97a25e0d010bd8 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 8b8c401974e251..ec68fbe43e2939 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 92518c2c6c9860..7a33a89311b4e9 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -5499,6 +5499,10 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/server/routes/uninstall_token/handlers.test.ts" }, + { + "plugin": "fleet", + "path": "x-pack/plugins/fleet/server/routes/uninstall_token/handlers.test.ts" + }, { "plugin": "remoteClusters", "path": "x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts" @@ -5819,6 +5823,10 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/server/routes/uninstall_token/index.ts" }, + { + "plugin": "fleet", + "path": "x-pack/plugins/fleet/server/routes/uninstall_token/index.ts" + }, { "plugin": "fleet", "path": "x-pack/plugins/fleet/server/services/security/fleet_router.test.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index c8ce637609a8d5..8218462ac370a4 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-06-30 +date: 2023-07-01 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 37152419ec61dd..5e0a5229c1b1ba 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 38b996d68e19ed..6042ae34b1ae4e 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 384056aae6faae..819bf5b277a4f9 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 a146a9355e5382..a9a71970248929 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 48738f858e1db0..50bdbd095679d5 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-06-30 +date: 2023-07-01 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 31ce4c84da6bb8..1d5450bdddc08a 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 3e0175adb9a293..9f3e591f4ee302 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 c2e1506137554b..fbc3e018431917 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 08d4413e6f96ae..412a9c93621a94 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 ca3a0ec2fc9fc8..90c707717e68c2 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 fbc58e07cc3c61..1755befbdafd4b 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 b1fa75a0c78409..cad40a226bbe07 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 19837d2466be74..25430eb395c9a3 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-06-30 +date: 2023-07-01 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 27dba6e73fc29f..3d117adba5b8c6 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 92a43ea8687d5c..7482a36344757d 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 263c754aa76844..5ed240b9de7d09 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 f5bb802aa6c404..64d1a5c58e5174 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-06-30 +date: 2023-07-01 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 2dba6b6673c5d9..e6fa7b12326604 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 45ffe9cf4d651c..94572b7231d43e 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 837c4e7df325fd..8938c2216ad38a 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 d2840e4e3968b1..703c7e2c1331bc 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 8df5f813b97684..3f69c05a08085b 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-06-30 +date: 2023-07-01 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 af792e2945fc47..ffc6867a386e1f 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 e41644eb284f5a..74ecd4d1e91ed1 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 084ba973a9e70a..f24a224536f8b8 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 9d2c1bbc4f07c1..0f8469d060ceb2 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-06-30 +date: 2023-07-01 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 5b265d7f20e05a..3ef94f1e951057 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 a3a7f979c4a37b..cfa981f8e33dfe 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 d1a80ab0625fca..405825fe22cb92 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 dc00617d5b3793..7857f3a4bf705a 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 559a39395b091d..9a09e07f9f89fe 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 6ad21beb9fbb2d..1e9517c476f3ca 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 6a923c38874b6d..3fb3ede439430e 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 3d0bb2d7f0e3cf..db2e3278691a22 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 011a4a7ec2fd51..98cdfca257b602 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 4b57b1c67b92a8..11b58536e16a27 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index dcc5f9bce15e84..ca38adb5d0b9e8 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-06-30 +date: 2023-07-01 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 81327250270c94..9c97b413193214 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 b5088454b1d8aa..391e24d7133007 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-06-30 +date: 2023-07-01 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 22ee50388f0b0e..7219dc56c2f8ea 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 4ae90668e74e64..57d8bc1f80ab56 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 9a54cf7cf39206..53b89a11bb10a5 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 b135ed45cbc2d5..c118721af4c54d 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 b79f72ccb4974f..efa074188a66f4 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 90d97d003d6b8c..af549e9f5538e8 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 5f3dae559b6d94..460d8bdda3dfa1 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-06-30 +date: 2023-07-01 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 ce1c8b4561da9e..6490a50ad91e7a 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 3c9f791e6f1bb0..57bd092ce6cdd4 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 10017078ace481..56f877a8f46870 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 2d148f9c34964a..cbfbdf2a6ef386 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 c23757de2cf8fc..ebbd58eb20b854 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 f4256143bb941a..0b5debaa947ee1 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 786f7ea994800b..1491e5d3d60e5d 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-06-30 +date: 2023-07-01 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 5f66640f4d31b2..100e22633553b6 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 6112c22b2b6a43..bf100b41170362 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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.devdocs.json b/api_docs/kbn_core_saved_objects_migration_server_internal.devdocs.json index 699397cdf48dcd..3a6495d4c50785 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.devdocs.json +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.devdocs.json @@ -1335,7 +1335,7 @@ "tags": [], "label": "pickupUpdatedMappings", "description": [ - "\nPickup updated mappings by performing an update by query operation on all\ndocuments in the index. Returns a task ID which can be\ntracked for progress.\n" + "\nPickup updated mappings by performing an update by query operation on all\ndocuments matching the passed in query. Returns a task ID which can be\ntracked for progress.\n" ], "signature": [ "(client: ", @@ -1346,7 +1346,9 @@ "section": "def-common.ElasticsearchClient", "text": "ElasticsearchClient" }, - ", index: string, batchSize: number) => ", + ", index: string, batchSize: number, query?: ", + "QueryDslQueryContainer", + " | undefined) => ", "TaskEither", "<", "RetryableEsClientError", @@ -1414,6 +1416,22 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-migration-server-internal", + "id": "def-common.pickupUpdatedMappings.$4", + "type": "Object", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "QueryDslQueryContainer", + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/pickup_updated_mappings.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [], @@ -1746,7 +1764,7 @@ "\nUpdates an index's mappings and runs an pickupUpdatedMappings task so that the mapping\nchanges are \"picked up\". Returns a taskId to track progress." ], "signature": [ - "({ client, index, mappings, batchSize, }: ", + "({ client, index, mappings, batchSize, query, }: ", "UpdateAndPickupMappingsParams", ") => ", "TaskEither", @@ -1765,7 +1783,7 @@ "id": "def-common.updateAndPickupMappings.$1", "type": "Object", "tags": [], - "label": "{\n client,\n index,\n mappings,\n batchSize,\n}", + "label": "{\n client,\n index,\n mappings,\n batchSize,\n query,\n}", "description": [], "signature": [ "UpdateAndPickupMappingsParams" 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 b04305fac4f0da..04170c694d3a71 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 123 | 0 | 89 | 46 | +| 124 | 0 | 90 | 46 | ## Common 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 d78a63e5b0821e..36da373f97bb06 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 d99d4ea8528ca7..e22e39d5954d2e 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-06-30 +date: 2023-07-01 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 b193ab1fff041b..17725c68d14bd9 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 1c1fe623094b0b..c756087ce49f24 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 f25d9886ec4af7..732f885b553766 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-06-30 +date: 2023-07-01 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 098b77d3a5be44..4fdadc5c7f8d8d 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-06-30 +date: 2023-07-01 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 f3b3cb0d5f2d34..816e447f68da3c 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 b2615ef588e507..8cd89a8208a48b 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-06-30 +date: 2023-07-01 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 33a59a6da2ac87..637236edb4b63d 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 08e898d63952d1..d08251261cb739 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 fb9cfe5e06eda8..a718c5bd3f4f89 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-06-30 +date: 2023-07-01 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 29b267c229a225..feba5441145fb7 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 6835fa78db7147..c19c3e7aad6918 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index cec382dd67f993..10666ef670d7bf 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-06-30 +date: 2023-07-01 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 2ef04f83820509..a714ad7ef5fd6b 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 f7c4977627024c..ec3b19a6dc0a1c 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index c4f34300dd40a3..4b01960f63c4ea 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index b06fc8d98390ae..6d36bb8fa411db 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 92824665b90516..5f03c7bf614044 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 e36154decf4808..5f9b226846e85d 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 f3f0d04629090e..5862e5479682bf 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 1c86bc3581739f..33624373d7365f 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-06-30 +date: 2023-07-01 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 d1191aae7a3e66..193e734bb811a0 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-06-30 +date: 2023-07-01 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 1527eee1a5ab3e..3b459a4845f40c 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 197fbf81d7eb7e..522c3b7de87072 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 b8ebf1dc853dce..8c70bb798947be 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-06-30 +date: 2023-07-01 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 29af37cbe10198..9810be226d58b0 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 7f08c460849507..c42a120b4099bf 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 5b45a9ecf9ee5c..5ad14647fdb4c2 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-06-30 +date: 2023-07-01 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 5f97644173576b..375fe8cac8cd60 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-06-30 +date: 2023-07-01 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 050770ee7f4bfa..afabebf91aaf0a 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 91ac99d5373133..2a497ed3fdec01 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-06-30 +date: 2023-07-01 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 c7c180037c65a3..3ac6fa9aa045f6 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index e6e7c8e90d2b6d..42f1f813b06477 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 08c01439606dc0..355b30ce946685 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index ab7a457ca29737..5deea2bf85fbe0 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-06-30 +date: 2023-07-01 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 bc29e3db1a242e..012f366b275c66 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-06-30 +date: 2023-07-01 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 746d744ec21e61..d78e6736c9e105 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-06-30 +date: 2023-07-01 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 0805671dc905cb..1855190cf31370 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-06-30 +date: 2023-07-01 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 ef8961d35cec14..a3d2955c852852 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-06-30 +date: 2023-07-01 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 5bb85866f3529b..c42259090282b4 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-06-30 +date: 2023-07-01 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 aa6ad4b0817dbe..c739b1a904c7f2 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-06-30 +date: 2023-07-01 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 0fe33103acb2ec..a86d3cc28be127 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-06-30 +date: 2023-07-01 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 e9e9a3976b1b46..4b7b88022a6794 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-06-30 +date: 2023-07-01 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 06c7cd0227d3c9..e19b6a8c891316 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-06-30 +date: 2023-07-01 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 1e0c9b2fbf3a5a..5d7244de5e2b44 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-06-30 +date: 2023-07-01 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 2c35736b115b53..54375a41d32a53 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-06-30 +date: 2023-07-01 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 2c92f09a74ba59..f378cb6feec663 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-06-30 +date: 2023-07-01 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 03f904c56b50fd..73ef71ac81f78f 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-06-30 +date: 2023-07-01 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 976f85187ad6f3..231c242f14ac42 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index db9b6d0b85d0b8..96d5d3e16bc7f3 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-06-30 +date: 2023-07-01 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 f911e310903ccd..e69f57d27e6e29 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 e01a14c6c1ec23..f59e4466d831d9 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-06-30 +date: 2023-07-01 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 aa6acb99d617aa..4bfce1e749f9f6 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-06-30 +date: 2023-07-01 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 635d7c5314ee47..759b92e0b971f1 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-06-30 +date: 2023-07-01 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 69a8ef8bcb2167..d6d5f3daf17c1a 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 76d40eae7cbe4d..bd6ec3e22a5126 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 8f5a641fc5a374..497452eb2271b7 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-06-30 +date: 2023-07-01 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 62b55c2cbe6ea0..85256a910bcb92 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-06-30 +date: 2023-07-01 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 b542ac45909214..8feba3a1d6dfcf 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-06-30 +date: 2023-07-01 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 2dc931afb9ac64..970f436b91b226 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-06-30 +date: 2023-07-01 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 a688291dcb4661..37c82a3546288a 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-06-30 +date: 2023-07-01 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 2ac3fbec286f1e..8aa3ae23c63d09 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 817316ee50a299..ce50720645de46 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-06-30 +date: 2023-07-01 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 9db7ac2995823a..1bb070d1d00b97 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 5e918d373f28e4..6d64c386bbc6f0 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-06-30 +date: 2023-07-01 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 08df7c49d423f5..2939dcb1027493 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 5db131ac2aa64e..25e30356fc4ea3 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-06-30 +date: 2023-07-01 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 134885dce4e314..c06d70ec88d237 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-06-30 +date: 2023-07-01 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 29277fd4362684..2351b7f1bf1f78 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 08cb04241e202e..1e6b05e205c780 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index a0b070753b4afb..6d4fcb8fe49efb 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-06-30 +date: 2023-07-01 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 6053a1722a4624..5809c8904bb057 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-06-30 +date: 2023-07-01 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 46d6377ce2fd5c..a6facf3d48dc64 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 8af183c664100a..063e560b9d2a07 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-06-30 +date: 2023-07-01 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 3da9b96032b867..d6f6527f3323b5 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-06-30 +date: 2023-07-01 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 97225879065a07..8c14d2aac7f3c3 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-06-30 +date: 2023-07-01 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 6d95092b2fb2a2..1ee8d396c85d92 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-06-30 +date: 2023-07-01 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 34e812c2a97244..b06caea81a3bdf 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-06-30 +date: 2023-07-01 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 08c68565ae2b1e..242151c2255311 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-06-30 +date: 2023-07-01 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 0a01ba4056433b..fe4e513c8a6860 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-06-30 +date: 2023-07-01 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 818fce8ad7e93c..e8a495b894da0a 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-06-30 +date: 2023-07-01 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 0d332dec34ec3e..f24fc054813c8d 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 8161ced3eb36b1..47bf87a3bc84c8 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-06-30 +date: 2023-07-01 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 cf2f98e7566f33..b7037e0c3591ca 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-06-30 +date: 2023-07-01 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 6116993499422d..fa2de724fd1aaf 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-06-30 +date: 2023-07-01 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 0af28696305124..c0310d96747002 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-06-30 +date: 2023-07-01 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 f2261e06cb1e23..7c7ffa50236f5e 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 337cf5640c3ae7..cbb00747d2be5c 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-06-30 +date: 2023-07-01 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 ed7a25e96af4d3..39c6667b632815 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 27686b46252de2..9409f726f3d2be 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-06-30 +date: 2023-07-01 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.devdocs.json b/api_docs/kbn_management_cards_navigation.devdocs.json new file mode 100644 index 00000000000000..35116d25824c52 --- /dev/null +++ b/api_docs/kbn_management_cards_navigation.devdocs.json @@ -0,0 +1,191 @@ +{ + "id": "@kbn/management-cards-navigation", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigation", + "type": "Function", + "tags": [], + "label": "CardsNavigation", + "description": [], + "signature": [ + "({ sections, appBasePath, onCardClick, hideLinksTo, }: ", + { + "pluginId": "@kbn/management-cards-navigation", + "scope": "common", + "docId": "kibKbnManagementCardsNavigationPluginApi", + "section": "def-common.CardsNavigationComponentProps", + "text": "CardsNavigationComponentProps" + }, + ") => JSX.Element" + ], + "path": "packages/kbn-management/cards_navigation/src/cards_navigation.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigation.$1", + "type": "Object", + "tags": [], + "label": "{\n sections,\n appBasePath,\n onCardClick,\n hideLinksTo = [],\n}", + "description": [], + "signature": [ + { + "pluginId": "@kbn/management-cards-navigation", + "scope": "common", + "docId": "kibKbnManagementCardsNavigationPluginApi", + "section": "def-common.CardsNavigationComponentProps", + "text": "CardsNavigationComponentProps" + } + ], + "path": "packages/kbn-management/cards_navigation/src/cards_navigation.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps", + "type": "Interface", + "tags": [], + "label": "CardsNavigationComponentProps", + "description": [], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps.sections", + "type": "Array", + "tags": [], + "label": "sections", + "description": [], + "signature": [ + "AppRegistrySections", + "[]" + ], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps.appBasePath", + "type": "string", + "tags": [], + "label": "appBasePath", + "description": [], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps.onCardClick", + "type": "Function", + "tags": [], + "label": "onCardClick", + "description": [], + "signature": [ + "((e: React.MouseEvent) => void) | undefined" + ], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps.onCardClick.$1", + "type": "Object", + "tags": [], + "label": "e", + "description": [], + "signature": [ + "React.MouseEvent" + ], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.CardsNavigationComponentProps.hideLinksTo", + "type": "Array", + "tags": [], + "label": "hideLinksTo", + "description": [], + "signature": [ + "(\"transform\" | \"tags\" | \"maintenanceWindows\" | \"dataViews\" | \"data_view\" | \"filesManagement\" | \"reporting\" | \"api_keys\" | \"index_management\" | \"ingest_pipelines\" | \"jobsListLink\" | \"objects\" | \"pipelines\" | \"triggersActions\" | \"triggersActionsConnectors\")[] | undefined" + ], + "path": "packages/kbn-management/cards_navigation/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.appIds", + "type": "Enum", + "tags": [], + "label": "appIds", + "description": [], + "path": "packages/kbn-management/cards_navigation/src/consts.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "@kbn/management-cards-navigation", + "id": "def-common.AppId", + "type": "Type", + "tags": [], + "label": "AppId", + "description": [], + "signature": [ + "\"transform\" | \"tags\" | \"maintenanceWindows\" | \"dataViews\" | \"data_view\" | \"filesManagement\" | \"reporting\" | \"api_keys\" | \"index_management\" | \"ingest_pipelines\" | \"jobsListLink\" | \"objects\" | \"pipelines\" | \"triggersActions\" | \"triggersActionsConnectors\"" + ], + "path": "packages/kbn-management/cards_navigation/src/consts.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx new file mode 100644 index 00000000000000..06594d6050b4b0 --- /dev/null +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -0,0 +1,39 @@ +--- +#### +#### 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: kibKbnManagementCardsNavigationPluginApi +slug: /kibana-dev-docs/api/kbn-management-cards-navigation +title: "@kbn/management-cards-navigation" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/management-cards-navigation plugin +date: 2023-07-01 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] +--- +import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; + + + +Contact [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 10 | 0 | 10 | 1 | + +## Common + +### Functions + + +### Interfaces + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/kbn_management_storybook_config.devdocs.json b/api_docs/kbn_management_storybook_config.devdocs.json new file mode 100644 index 00000000000000..7615017ad39020 --- /dev/null +++ b/api_docs/kbn_management_storybook_config.devdocs.json @@ -0,0 +1,62 @@ +{ + "id": "@kbn/management-storybook-config", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/management-storybook-config", + "id": "def-common.TITLE", + "type": "string", + "tags": [], + "label": "TITLE", + "description": [ + "The title of the Storybook." + ], + "signature": [ + "\"kbn-management storybook\"" + ], + "path": "packages/kbn-management/storybook/config/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/management-storybook-config", + "id": "def-common.URL", + "type": "string", + "tags": [], + "label": "URL", + "description": [ + "The remote URL of the root from which Storybook loads stories for kbn-management." + ], + "signature": [ + "\"https://github.com/elastic/kibana/tree/main/packages/kbn-management\"" + ], + "path": "packages/kbn-management/storybook/config/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx new file mode 100644 index 00000000000000..d89fa6752a3730 --- /dev/null +++ b/api_docs/kbn_management_storybook_config.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: kibKbnManagementStorybookConfigPluginApi +slug: /kibana-dev-docs/api/kbn-management-storybook-config +title: "@kbn/management-storybook-config" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/management-storybook-config plugin +date: 2023-07-01 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] +--- +import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; + + + +Contact [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 0 | 0 | + +## Common + +### Consts, variables and types + + diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 5147299e37663e..95853867cf8496 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-06-30 +date: 2023-07-01 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 51b5793e598f9e..51c648628b5d62 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 f7d230fc983595..451a434e585db1 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 79858ac6c6b984..f09e64cb1023f0 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 404c6677a8d455..a937a196c490cc 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 3cf0bd8fc0b5f3..b80759a3c98571 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-06-30 +date: 2023-07-01 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 fcc436bd1a59ea..ee88250204b67d 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-06-30 +date: 2023-07-01 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 ceb975a261cc3e..d526a8a2f7f6e5 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 4183652a9393ad..c0319e14cf1411 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 58ba1539b3081e..6bed7525b237fb 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-06-30 +date: 2023-07-01 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 2d2f89cdd93358..06683c7591b271 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-06-30 +date: 2023-07-01 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 850f72a2d8a252..a60ffca5d533f6 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-06-30 +date: 2023-07-01 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 49e2245c6a7a5c..ee58a072d6bf14 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-06-30 +date: 2023-07-01 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 3e9f27b990006e..7d45dcff22b284 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-06-30 +date: 2023-07-01 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 c56e7b9337574c..27f519de3e34bb 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 48d8e0fbc1f91d..7af33b1870dad6 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 8c5c2c7b50af15..73cad7f7b768f4 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 e666f90f6b589e..d992a41c07a499 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 e12985330e7f70..0a207eef5155dd 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 81b53da1eeec39..3f1e0790444340 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-06-30 +date: 2023-07-01 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 322b7df40f21ce..7838e98c20bae4 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index a0dee28b430bbd..5ebb549cef814e 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 3609f9c080732f..3c80862669f726 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-06-30 +date: 2023-07-01 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 e5d61420d7f787..ac2e442ff24db2 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-06-30 +date: 2023-07-01 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 4299751793d519..c9dba8fc7b496e 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 7fd8398aa88f7b..b4490a5884e67f 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-06-30 +date: 2023-07-01 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 23af54fccf2408..3fe7bb663be0bf 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-06-30 +date: 2023-07-01 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 7cd16c465206b1..feae10f25c6203 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 4492c489282603..e9b165a80fa8a0 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index ff9a96c9e9bcae..9dbb61221719c6 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-06-30 +date: 2023-07-01 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 b8368fa20e46a3..6e1cb7c047d729 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index cc67c47f1bc569..c7f1ef72909873 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-06-30 +date: 2023-07-01 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 9c530b7779f8bf..c6fd8cbe234b31 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index a8f3d0a8052f9e..2ef81b6c133e69 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-06-30 +date: 2023-07-01 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 bbae305f56b894..0b560a2fa4a113 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-06-30 +date: 2023-07-01 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 ad629e2e80480e..e30ef23a5ecb1f 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-06-30 +date: 2023-07-01 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 ee4a70da1444ee..3f0dc805c5587a 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-06-30 +date: 2023-07-01 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 e627c153b06f5e..48808594d9f990 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 87a9a08671452f..2540ca71bb3ce3 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 7a5fac77e05f9e..7dcc673d546955 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 02407a5984e2bf..d0e40282acd9ee 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 13c1d7da7e2f01..b10e0e04199e68 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-06-30 +date: 2023-07-01 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 89fe6d2bd164f5..d2650651f63337 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-06-30 +date: 2023-07-01 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 9c9daeef2a6407..e6a2e11e8b8af2 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-06-30 +date: 2023-07-01 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 f32526c450d3d6..8f2971135ba042 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-06-30 +date: 2023-07-01 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 3c9938634b490d..2505ad7354ced0 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-06-30 +date: 2023-07-01 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 4268bd21f81afe..feb5f9d6112eb0 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 ea9e79cec7dbf9..3fac847ba133ed 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-06-30 +date: 2023-07-01 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 e3ca628a7c42ed..3814a5c735a236 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-06-30 +date: 2023-07-01 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 bcd97e2dd84ef4..e1606e8cedcca6 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 d928173ce54407..7e05c3b87b013a 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-06-30 +date: 2023-07-01 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 bf4e174dfded91..84c0eccfc346e7 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-06-30 +date: 2023-07-01 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 911ffe07505e00..2bdaf3d91dae33 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-06-30 +date: 2023-07-01 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 b21fbeff5c570a..f5aabff2dcc467 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 f443ca6f68e2fc..4bde517249f7d8 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-06-30 +date: 2023-07-01 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 81e2ff61db05c9..18ca9d6b710b31 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-06-30 +date: 2023-07-01 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 097841300a909b..0d1cf06cbc5318 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-06-30 +date: 2023-07-01 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 341bb67f0408fb..34a6cd28b63b28 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 307a04514254f4..867266875c7bbe 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-06-30 +date: 2023-07-01 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 fcd16e9555d1cc..0d2d86e2b5f9eb 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-06-30 +date: 2023-07-01 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 77a10967c2f882..011488503994c6 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-06-30 +date: 2023-07-01 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 abbf73d8236c64..b76b121acf1436 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-06-30 +date: 2023-07-01 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 c24b60a20f9570..783a84965b54db 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 175977dbb6e22d..1ac8722e820ff4 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 21a2e8c25e2752..90dcd761088c6c 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-06-30 +date: 2023-07-01 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 35505d2bd1a9ae..9740834b51668b 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-06-30 +date: 2023-07-01 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 04dc5f3adbc902..a5dd85a270d533 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index c369b145a8f0e3..e182a1d1b989ed 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 3f567e4cff42a3..70b485aabd7dd3 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index c52d19e9d35f60..9f61649c0f80aa 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 0eb23afa597057..604e16c3db80d4 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-06-30 +date: 2023-07-01 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 17f6c66d58c890..299848ea3f9849 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-06-30 +date: 2023-07-01 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 eeb6f991db1d3a..81fe9003747780 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 cbb0de7496c595..01a8560de63bb2 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index fe577411235cbd..f0fe276c08959d 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-06-30 +date: 2023-07-01 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 858151006d8ce7..a04b7451314324 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-06-30 +date: 2023-07-01 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 247be558cbcefa..c445e9dbfc0b3e 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 dbf4cef7d443b2..a9f75168f37592 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 ac3367f4297436..863f1fe7c17320 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-06-30 +date: 2023-07-01 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 e2ed1b93b8fd32..e508b2ec0be2c7 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-06-30 +date: 2023-07-01 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 2d77fc33b7d0f2..1fcb43a3dfb4f8 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-06-30 +date: 2023-07-01 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 a11a68075dc78f..f3df07c76b20d7 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-06-30 +date: 2023-07-01 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 7b4d15989dbd4b..1791452e49f84c 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-06-30 +date: 2023-07-01 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 f7aafa18bf14d3..5eb55a3aee1b17 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 5e009794043e18..72a04b84f9a514 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-06-30 +date: 2023-07-01 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 98bbbd98e3067b..cd9718f1953b28 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 e2048cf8bf66c0..946314be1933c3 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-06-30 +date: 2023-07-01 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 41baeb7fc84ef2..eeb5154639e584 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 a77471c0ebd2b3..6d93616a378dfe 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-06-30 +date: 2023-07-01 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 a20da4872dce36..bdb121409874bc 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 67eb3fdc9d2da7..3cb87c2e6d37fb 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-06-30 +date: 2023-07-01 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 5b09648ce10259..97e89e2bcbd070 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 f34e531d7be380..9998920d49abc7 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-06-30 +date: 2023-07-01 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 784c60782d1b67..1e5dd1cd0d152a 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-06-30 +date: 2023-07-01 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 463881879d1d6b..32f6e986e4aab1 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 a7ea6142f14a4d..316783b5846c72 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 a9aee4d9a09871..e08bd5287ede89 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-06-30 +date: 2023-07-01 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 7a28991b6db2f4..76dc0f76b08023 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-06-30 +date: 2023-07-01 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 4b9d7785fb315c..3e9a1fd68ca766 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 7768c002563e00..91015a2e48c4af 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-06-30 +date: 2023-07-01 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 0a4267873f834f..628de0bcd00173 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-06-30 +date: 2023-07-01 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 460135a134d2ae..b1aba19e1cc999 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-06-30 +date: 2023-07-01 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 33d552a1318eb1..cbf005e8a76f4c 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-06-30 +date: 2023-07-01 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 149982eb03f10d..500c557b556ec4 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-06-30 +date: 2023-07-01 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 1cbc67ee4a11e1..939d2b21a60507 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-06-30 +date: 2023-07-01 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 b085b172ac32ec..100186441aa9ea 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-06-30 +date: 2023-07-01 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 d7269e4f87a709..2dc3eefef452a4 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 3ee76d8ce57bb5..ec9396d8dd665f 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-06-30 +date: 2023-07-01 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 8951131d9c1b30..76f71d6bccf149 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-06-30 +date: 2023-07-01 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 94802cce7aabcc..f285c119a1b63e 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-06-30 +date: 2023-07-01 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 b9c5a4ed5a588c..8f3af791202ce9 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-06-30 +date: 2023-07-01 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 a28269b45d0fcc..59bee27d04908c 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 56e27ec9a1ea48..8412482fb708b3 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-06-30 +date: 2023-07-01 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 02d2aadd706f9a..2aeb616de2d6be 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-06-30 +date: 2023-07-01 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 5daf28cd7d244c..484dcb76a268eb 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-06-30 +date: 2023-07-01 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 7ee9dd44938f0b..6a897205db4ff4 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 6104ee6e57500e..2420b25760652d 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-06-30 +date: 2023-07-01 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 f57367798f2aae..bebf5b02024dc4 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-06-30 +date: 2023-07-01 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 032c531cca7f65..4f593db31806b7 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-06-30 +date: 2023-07-01 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 d9303de280b06d..f538ba872df103 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-06-30 +date: 2023-07-01 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 a6390418bffdcb..97f25a83f2bcaf 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 3a57dc997ac597..8d4707caa8c703 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index d20cd31a79a8f5..af90e441b7df56 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index f677f876d2f8e1..4bcf4dea51cd40 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-06-30 +date: 2023-07-01 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 95b56c597ae28d..e1497819ed1874 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-06-30 +date: 2023-07-01 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 c46479a9ff44d4..86ea07749dec95 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-06-30 +date: 2023-07-01 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 9813607dc45aab..3c64564ace6514 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 36757ad29f0f30..4ffdda08138474 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index e794ae8bd88ba5..d19633fd370d79 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-06-30 +date: 2023-07-01 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 1cc1cc3031f0d0..8c386f16bf1974 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-06-30 +date: 2023-07-01 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 25766d27a39fe4..6c6f89609aa5b3 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-06-30 +date: 2023-07-01 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 5e648fe9f92996..23f69c5fa821f9 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index a3dca011ebc799..e151c4ab1fe459 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -8593,7 +8593,7 @@ "CustomXDomain", " | undefined>; ariaDescription?: string | undefined; ariaDescribedBy?: string | undefined; ariaLabelledBy?: string | undefined; ariaTableCaption?: string | undefined; legendAction?: \"ignore\" | undefined; legendStrategy?: ", "LegendStrategy", - " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>>) | undefined" + " | undefined; onLegendItemClick?: \"ignore\" | undefined; customLegend?: \"ignore\" | undefined; onLegendItemMinusClick?: \"ignore\" | undefined; onLegendItemOut?: \"ignore\" | undefined; onLegendItemOver?: \"ignore\" | undefined; onLegendItemPlusClick?: \"ignore\" | undefined; debugState?: boolean | undefined; onProjectionClick?: \"ignore\" | undefined; onElementClick?: \"ignore\" | undefined; onElementOver?: \"ignore\" | undefined; onElementOut?: \"ignore\" | undefined; onBrushEnd?: \"ignore\" | undefined; onProjectionAreaChange?: \"ignore\" | undefined; onAnnotationClick?: \"ignore\" | undefined; pointerUpdateDebounce?: number | undefined; roundHistogramBrushValues?: boolean | undefined; noResults?: React.ReactChild | React.ComponentType<{}> | undefined; legendSort?: \"ignore\" | undefined; }>> & Partial>) | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts", "deprecated": false, diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 2d6aeddb761825..269e5c4d593edf 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-06-30 +date: 2023-07-01 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 f804fffc159a2b..0d9f0753d392f2 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-06-30 +date: 2023-07-01 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 658e0af2a18ce2..9add4e8c52f836 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 afdf76d7d70ab8..d238ff43a7a520 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index c6a99e06ba8e11..52c0abbd90c73d 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.devdocs.json b/api_docs/management.devdocs.json index 4ca34adc10ea7d..6e970de9f2c57b 100644 --- a/api_docs/management.devdocs.json +++ b/api_docs/management.devdocs.json @@ -804,6 +804,40 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setupCardsNavigation", + "type": "Function", + "tags": [], + "label": "setupCardsNavigation", + "description": [], + "signature": [ + "({ enabled, hideLinksTo }: ", + "NavigationCardsSubject", + ") => void" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setupCardsNavigation.$1", + "type": "Object", + "tags": [], + "label": "{ enabled, hideLinksTo }", + "description": [], + "signature": [ + "NavigationCardsSubject" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] } ], "lifecycle": "start", diff --git a/api_docs/management.mdx b/api_docs/management.mdx index b2a35b6b9817aa..e4099b8e79753c 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './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 | |-------------------|-----------|------------------------|-----------------| -| 43 | 0 | 43 | 6 | +| 45 | 0 | 45 | 7 | ## Client diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index dad1b50e463308..ea69cba58789a4 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-06-30 +date: 2023-07-01 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 01e4450d3db409..1e48c3b5456f6e 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index bb16b0f9297d37..f5e3da113860b6 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 051fd4068fd1cd..d53db399c06431 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-06-30 +date: 2023-07-01 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 f1330e88a88dff..420fff32e61b7e 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-06-30 +date: 2023-07-01 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 64f059808d0011..fda42a5b2c1617 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-06-30 +date: 2023-07-01 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 4228c5757a3991..42bb8d105a4e73 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index d42daba287f873..7b387f6acd541f 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-06-30 +date: 2023-07-01 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 f659ad371e4585..3eafde41fea3d9 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index f537d388682704..c1703e29d78fd0 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-06-30 +date: 2023-07-01 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 70f73a7877b818..f1fc4fe1b7ed3a 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-06-30 +date: 2023-07-01 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 003296222d067d..25da2b1cd889ad 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 51ac1717b3c957..103e70349756f3 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,19 +15,19 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 642 | 533 | 38 | +| 644 | 535 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70934 | 544 | 60753 | 1406 | +| 70948 | 544 | 60765 | 1410 | ## Plugin Directory | Plugin name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 268 | 10 | 263 | 27 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 270 | 10 | 265 | 27 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 1 | 32 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 45 | 0 | 27 | 1 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 635 | 1 | 611 | 47 | @@ -37,7 +37,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 91 | 1 | 75 | 2 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 80 | 0 | 65 | 26 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 271 | 16 | 256 | 10 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 268 | 16 | 253 | 10 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 52 | 0 | 11 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 3 | 0 | 2 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | This plugin exists as a workaround for using `cloudChat` plugin in plugins which can't have a direct dependency on security plugin. | 5 | 0 | 5 | 0 | @@ -123,7 +123,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 210 | 0 | 94 | 51 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 43 | 0 | 43 | 6 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 266 | 0 | 265 | 28 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 33 | @@ -177,7 +177,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 257 | 1 | 213 | 22 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [@elastic/kibana-localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 547 | 11 | 521 | 49 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 547 | 11 | 521 | 50 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 144 | 2 | 102 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 206 | 0 | 140 | 9 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 52 | 0 | 23 | 2 | @@ -228,7 +228,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 11 | 0 | 11 | 0 | | | [@elastic/kibana-qa](https://github.com/orgs/elastic/teams/kibana-qa) | - | 12 | 0 | 12 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 19 | 0 | 17 | 0 | -| | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 62 | 1 | 44 | 2 | +| | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 62 | 1 | 44 | 3 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 11 | 0 | 8 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 78 | 0 | 78 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 7 | 0 | 2 | 0 | @@ -371,7 +371,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 73 | 0 | 40 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 26 | 0 | 23 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 123 | 0 | 89 | 46 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 124 | 0 | 90 | 46 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 12 | 0 | 12 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 535 | 1 | 115 | 4 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 69 | 0 | 69 | 4 | @@ -463,6 +463,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 27 | 0 | 1 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 8 | 0 | 8 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 6 | 0 | 1 | 1 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 10 | 0 | 10 | 1 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 2 | 0 | 0 | 0 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 535 | 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) | - | 96 | 2 | 61 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 1eeb613f16ae58..a7f1d296080a3f 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-06-30 +date: 2023-07-01 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 bc9128a687c973..8b2228245a5f0f 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 8c6210ad985e67..dc6e58f5b9210f 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-06-30 +date: 2023-07-01 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 0ace0410ae071e..476cb1739d4aa8 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index c2e8d52c452a07..d2588a5cfadc50 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 1f587ce70bc3e1..7078e87cd6324a 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-06-30 +date: 2023-07-01 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 84ee443e918cb7..c8ece42510a29d 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-06-30 +date: 2023-07-01 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 4dba794d349ef2..8071caeb0c5aec 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-06-30 +date: 2023-07-01 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 09365c173b96d2..0808d53f269814 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-06-30 +date: 2023-07-01 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 9855c48ba90d0f..b0c13e53e3332a 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-06-30 +date: 2023-07-01 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 a5ca9791cb2a18..a4280a21eeb95b 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-06-30 +date: 2023-07-01 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 08fa5f5248fb19..540afdc13298b1 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-06-30 +date: 2023-07-01 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 21a0222377b4fd..a49cede4e7053a 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-06-30 +date: 2023-07-01 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 5ac6c566d99da0..fb49a6088d7e41 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-06-30 +date: 2023-07-01 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 72396d4b8a61ec..1b960866aaa34c 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-06-30 +date: 2023-07-01 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 e1235d8166475d..396f9ac7228f82 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-06-30 +date: 2023-07-01 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 853737ae7926c3..8f01fd49866d7e 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-06-30 +date: 2023-07-01 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 48e99976757b0d..4b9922889c5be4 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index fa97a61d51f977..6f8f4bb513122f 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-06-30 +date: 2023-07-01 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 841267119dd751..96afad72f333ac 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-06-30 +date: 2023-07-01 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 f4f8947f7fb957..dfe7597f3534fa 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index 83f20833a99891..9438f77d41e214 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 5b36b725abe614..2404fadea1d4d2 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-06-30 +date: 2023-07-01 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 3c9dae710a2089..af003c840feebc 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-06-30 +date: 2023-07-01 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 d64d97325ed719..a7248525a6ccac 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-06-30 +date: 2023-07-01 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 67ce44f89e6826..efa1263443622b 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-06-30 +date: 2023-07-01 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 cb6387b7e76c05..72c5db40b78d0c 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-06-30 +date: 2023-07-01 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 fe24915d6997e6..6bad751d5a1c8f 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-06-30 +date: 2023-07-01 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 582f37104d9473..cd91ef931b02cd 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-06-30 +date: 2023-07-01 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 24cf8c09595855..9ac752da2a1b2e 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-06-30 +date: 2023-07-01 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 35577ec87cc3c8..40aab05f868541 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-06-30 +date: 2023-07-01 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 db07655083e359..60ed328aeff72a 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-06-30 +date: 2023-07-01 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 765d85612f9203..6fe5a1b4c223ac 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-06-30 +date: 2023-07-01 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 f01d9a90cd4434..616e41b7a88b50 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-06-30 +date: 2023-07-01 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 f1f950e32747e6..3c9b796ba2d129 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-06-30 +date: 2023-07-01 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 2f36fbd5ebf85c..c561fc4d9ea48b 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-06-30 +date: 2023-07-01 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 80a02b2c69b24b..5f53242023d280 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-06-30 +date: 2023-07-01 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 d883772477845c..cc371e21344979 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -5616,6 +5616,8 @@ "signature": [ "PreConfiguredActionConnector", " | ", + "SystemAction", + " | ", "UserConfiguredActionConnector", "" ], diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index e9e1c36ee918f3..78edc3f55bcc1a 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 547 | 11 | 521 | 49 | +| 547 | 11 | 521 | 50 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 1820485d397f6b..43f87bffa9b216 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-06-30 +date: 2023-07-01 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 daecbdd0d463ab..3ef74c95039a62 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 26e8b03a31cebb..21da66d46a878f 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-06-30 +date: 2023-07-01 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 9ca7e0c48c8558..36633709b3c62c 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-06-30 +date: 2023-07-01 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 44e0532cc60b48..7f91b88d7955ef 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 3eef30cddca4e8..d04499f05c9fc4 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-06-30 +date: 2023-07-01 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 8fbcaf41c54123..420df299d3954e 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-06-30 +date: 2023-07-01 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 84718215e6148e..3741f2cc41172a 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-06-30 +date: 2023-07-01 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 3445683bb5db48..710ce5222aacdc 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-06-30 +date: 2023-07-01 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 5252022e724014..fad26b275bb063 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-06-30 +date: 2023-07-01 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 75e41b1380b808..08edda8c1d6487 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-06-30 +date: 2023-07-01 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 70cb5ba73fa29f..5d9cb6d19b1cfa 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-06-30 +date: 2023-07-01 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 b677cc575d14bf..f3d53a6d0e3510 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-06-30 +date: 2023-07-01 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 342f57da12f1b9..6a1a9643fe2a53 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-06-30 +date: 2023-07-01 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 ac3272a9bd92e0..1b355904b2c7ff 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-06-30 +date: 2023-07-01 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 d7373253c1ba20..3eb4fc9f00f38a 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-06-30 +date: 2023-07-01 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 950bd297eb8be9..10cdc760633ba2 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-06-30 +date: 2023-07-01 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 375a42ed70b705..bebdbe3246f2e7 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 835dfbe6bf1f41..cd97b619b8a941 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index adcda94576e48b..e51e594a608f10 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-06-30 +date: 2023-07-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 055a1046793d1380022fad563559987b6b2b4c8a Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Sat, 1 Jul 2023 08:08:21 +0100 Subject: [PATCH 04/98] [ML] Integrating into serverless kibana (#159433) - Adds function to ML plugin server side setup contract (`setFeaturesEnabled`) to enable/disable features. Features being, anomaly detection, data frame analytics or natural language processing. - Each serverless plugin (search, observability and security) now calls `setFeaturesEnabled` to enable different features on setup. - Adds three new feature capabilities, `isADEnabled`, `isDFAEnabled`, `isNLPEnabled` - Updates the capabilities switcher to toggle these capabilities based on the shared feature API. This currently has a bug where the switcher isn't triggered for API tag checking. - deeplinks are now only registered based on the feature capabilities, these control what is shown in the nav menu for search and observability projects. - Adds the Machine Learning nav menu section to the `serverless_search` plugin, to match the `serverless_observability` plugin. - Does not updated the `serverless_security` plugin's nav menu. (update, serverless_observability nav menu also now does not contain ML) Relates to https://github.com/elastic/kibana/issues/160891 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/default-nav/ml/default_navigation.ts | 16 +- .../routes/enterprise_search/indices.test.ts | 23 +- .../plugins/ml/common/types/capabilities.ts | 75 ++- x-pack/plugins/ml/public/application/app.tsx | 13 +- .../components/ml_page/ml_page.tsx | 37 +- .../contexts/kibana/use_is_serverless.ts | 14 - .../memory_usage/memory_usage_page.tsx | 10 +- .../model_management/model_actions.tsx | 2 +- .../components/notifications_list.tsx | 10 +- .../overview/components/content.tsx | 20 +- .../application/overview/overview_page.tsx | 4 +- .../routing/routes/notifications.tsx | 2 +- .../application/routing/routes/overview.tsx | 2 +- x-pack/plugins/ml/public/plugin.ts | 7 +- .../register_search_links.ts | 8 +- .../search_deep_links.ts | 443 ++++++++++-------- .../lib/capabilities/capabilities_switcher.ts | 53 ++- .../capabilities/check_capabilities.test.ts | 26 +- .../notifications_service_provider.ts | 33 +- x-pack/plugins/ml/server/plugin.ts | 37 +- .../plugins/ml/server/routes/notifications.ts | 16 +- x-pack/plugins/ml/server/types.ts | 3 + .../serverless_observability/kibana.jsonc | 2 +- .../serverless_observability/server/plugin.ts | 20 +- .../serverless_observability/server/types.ts | 9 + .../serverless_observability/tsconfig.json | 1 + x-pack/plugins/serverless_search/kibana.jsonc | 17 +- .../serverless_search/public/layout/nav.tsx | 10 +- .../serverless_search/server/plugin.ts | 37 +- .../plugins/serverless_search/server/types.ts | 10 + .../plugins/serverless_search/tsconfig.json | 1 + .../plugins/serverless_security/kibana.jsonc | 5 +- .../serverless_security/server/plugin.ts | 8 +- .../serverless_security/server/types.ts | 4 +- .../plugins/serverless_security/tsconfig.json | 3 +- .../apis/ml/system/capabilities.ts | 8 +- .../apis/ml/system/space_capabilities.ts | 14 +- 37 files changed, 665 insertions(+), 338 deletions(-) delete mode 100644 x-pack/plugins/ml/public/application/contexts/kibana/use_is_serverless.ts diff --git a/packages/default-nav/ml/default_navigation.ts b/packages/default-nav/ml/default_navigation.ts index 166307439ca8fe..5eb99482fd68ca 100644 --- a/packages/default-nav/ml/default_navigation.ts +++ b/packages/default-nav/ml/default_navigation.ts @@ -23,9 +23,9 @@ export type MlNodeDefinition = NodeDefinitionWithChildren { }); describe('GET /internal/enterprise_search/indices/{indexName}/ml_inference/pipeline_processors', () => { - let mockMl: SharedServices; + let mockMl: MlPluginSetup; let mockTrainedModelsProvider: MlTrainedModels; beforeEach(() => { @@ -195,7 +194,7 @@ describe('Enterprise Search Managed Indices', () => { mockMl = { trainedModelsProvider: () => Promise.resolve(mockTrainedModelsProvider), - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; registerIndexRoutes({ ...mockDependencies, @@ -1069,7 +1068,7 @@ describe('Enterprise Search Managed Indices', () => { describe('GET /internal/enterprise_search/pipelines/ml_inference', () => { let mockTrainedModelsProvider: MlTrainedModels; - let mockMl: SharedServices; + let mockMl: MlPluginSetup; beforeEach(() => { const context = { @@ -1095,7 +1094,7 @@ describe('Enterprise Search Managed Indices', () => { mockMl = { trainedModelsProvider: () => Promise.resolve(mockTrainedModelsProvider), - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; registerIndexRoutes({ ...mockDependencies, @@ -1134,7 +1133,7 @@ describe('Enterprise Search Managed Indices', () => { }); describe('POST /internal/enterprise_search/ml/models/{modelName}', () => { - let mockMl: SharedServices; + let mockMl: MlPluginSetup; let mockTrainedModelsProvider: MlTrainedModels; beforeEach(() => { @@ -1156,7 +1155,7 @@ describe('Enterprise Search Managed Indices', () => { mockMl = { trainedModelsProvider: () => Promise.resolve(mockTrainedModelsProvider), - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; registerIndexRoutes({ ...mockDependencies, @@ -1198,7 +1197,7 @@ describe('Enterprise Search Managed Indices', () => { }); describe('POST /internal/enterprise_search/ml/models/{modelName}/deploy', () => { - let mockMl: SharedServices; + let mockMl: MlPluginSetup; let mockTrainedModelsProvider: MlTrainedModels; beforeEach(() => { @@ -1220,7 +1219,7 @@ describe('Enterprise Search Managed Indices', () => { mockMl = { trainedModelsProvider: () => Promise.resolve(mockTrainedModelsProvider), - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; registerIndexRoutes({ ...mockDependencies, @@ -1262,7 +1261,7 @@ describe('Enterprise Search Managed Indices', () => { }); describe('GET /internal/enterprise_search/ml/models/{modelName}', () => { - let mockMl: SharedServices; + let mockMl: MlPluginSetup; let mockTrainedModelsProvider: MlTrainedModels; beforeEach(() => { @@ -1283,7 +1282,7 @@ describe('Enterprise Search Managed Indices', () => { mockMl = { trainedModelsProvider: () => Promise.resolve(mockTrainedModelsProvider), - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; registerIndexRoutes({ ...mockDependencies, diff --git a/x-pack/plugins/ml/common/types/capabilities.ts b/x-pack/plugins/ml/common/types/capabilities.ts index 23d641ffa4d1b1..c6bf7e9e1c7e51 100644 --- a/x-pack/plugins/ml/common/types/capabilities.ts +++ b/x-pack/plugins/ml/common/types/capabilities.ts @@ -18,6 +18,12 @@ export const apmUserMlCapabilities = { canGetJobs: false, }; +export const featureMlCapabilities = { + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, +}; + export const userMlCapabilities = { // Anomaly Detection canGetJobs: false, @@ -80,19 +86,21 @@ export const adminMlCapabilities = { canStartStopTrainedModels: false, }; +export type FeatureMlCapabilities = typeof featureMlCapabilities; export type UserMlCapabilities = typeof userMlCapabilities; export type AdminMlCapabilities = typeof adminMlCapabilities; -export type MlCapabilities = UserMlCapabilities & AdminMlCapabilities; +export type MlCapabilities = FeatureMlCapabilities & UserMlCapabilities & AdminMlCapabilities; export type MlCapabilitiesKey = keyof MlCapabilities; -export const basicLicenseMlCapabilities = [ +export const basicLicenseMlCapabilities: MlCapabilitiesKey[] = [ 'canFindFileStructure', 'canGetFieldInfo', 'canGetMlInfo', -] as Array; +]; export function getDefaultCapabilities(): MlCapabilities { return { + ...featureMlCapabilities, ...userMlCapabilities, ...adminMlCapabilities, }; @@ -101,8 +109,13 @@ export function getDefaultCapabilities(): MlCapabilities { export function getPluginPrivileges() { const apmUserMlCapabilitiesKeys = Object.keys(apmUserMlCapabilities); const userMlCapabilitiesKeys = Object.keys(userMlCapabilities); + const featureMlCapabilitiesKeys = Object.keys(featureMlCapabilities); const adminMlCapabilitiesKeys = Object.keys(adminMlCapabilities); - const allMlCapabilitiesKeys = [...adminMlCapabilitiesKeys, ...userMlCapabilitiesKeys]; + const allMlCapabilitiesKeys = [ + ...featureMlCapabilitiesKeys, + ...adminMlCapabilitiesKeys, + ...userMlCapabilitiesKeys, + ]; const savedObjects = [ 'index-pattern', @@ -143,10 +156,13 @@ export function getPluginPrivileges() { }, user: { ...privilege, - api: ['fileUpload:analyzeFile', ...userMlCapabilitiesKeys.map((k) => `ml:${k}`)], + api: [ + 'fileUpload:analyzeFile', + ...[...featureMlCapabilitiesKeys, ...userMlCapabilitiesKeys].map((k) => `ml:${k}`), + ], catalogue: [PLUGIN_ID], management: { insightsAndAlerting: [] }, - ui: userMlCapabilitiesKeys, + ui: [...featureMlCapabilitiesKeys, ...userMlCapabilitiesKeys], savedObject: { all: [], read: savedObjects, @@ -182,3 +198,50 @@ export interface MlCapabilitiesResponse { } export type ResolveMlCapabilities = (request: KibanaRequest) => Promise; + +interface FeatureCapabilities { + ad: MlCapabilitiesKey[]; + dfa: MlCapabilitiesKey[]; + nlp: MlCapabilitiesKey[]; +} + +export const featureCapabilities: FeatureCapabilities = { + ad: [ + 'canGetJobs', + 'canGetDatafeeds', + 'canGetCalendars', + 'canGetAnnotations', + 'canCreateAnnotation', + 'canDeleteAnnotation', + 'canCreateJob', + 'canDeleteJob', + 'canOpenJob', + 'canCloseJob', + 'canResetJob', + 'canUpdateJob', + 'canForecastJob', + 'canCreateDatafeed', + 'canDeleteDatafeed', + 'canStartStopDatafeed', + 'canUpdateDatafeed', + 'canPreviewDatafeed', + 'canGetFilters', + 'canCreateCalendar', + 'canDeleteCalendar', + 'canCreateFilter', + 'canDeleteFilter', + ], + dfa: [ + 'canGetDataFrameAnalytics', + 'canCreateDataFrameAnalytics', + 'canDeleteDataFrameAnalytics', + 'canStartStopDataFrameAnalytics', + ], + nlp: [ + 'canGetTrainedModels', + 'canTestTrainedModels', + 'canCreateTrainedModels', + 'canDeleteTrainedModels', + 'canStartStopTrainedModels', + ], +}; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index 1cc165acfbcdbc..559ec601da4d79 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -9,7 +9,8 @@ import React, { type FC, useMemo } from 'react'; import './_index.scss'; import ReactDOM from 'react-dom'; import { pick } from 'lodash'; -import { AppMountParameters, CoreStart, HttpStart } from '@kbn/core/public'; + +import type { AppMountParameters, CoreStart, HttpStart } from '@kbn/core/public'; import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { DatePickerContextProvider } from '@kbn/ml-date-picker'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -33,6 +34,7 @@ import { mlUsageCollectionProvider } from './services/usage_collection'; import { MlRouter } from './routing'; import { mlApiServicesProvider } from './services/ml_api_service'; import { HttpService } from './services/http_service'; +import type { PageDependencies } from './routing/router'; export type MlDependencies = Omit< MlSetupDependencies, @@ -48,12 +50,6 @@ interface AppProps { const localStorage = new Storage(window.localStorage); -// temporary function to hardcode the serverless state -// this will be replaced by the true serverless information from kibana -export function isServerless() { - return false; -} - /** * Provides global services available across the entire ML app. */ @@ -65,7 +61,6 @@ export function getMlGlobalServices(httpStart: HttpStart, usageCollection?: Usag httpService, mlApiServices, mlUsageCollection: mlUsageCollectionProvider(usageCollection), - isServerless, mlCapabilities: new MlCapabilitiesService(mlApiServices), mlLicense: new MlLicense(), }; @@ -78,7 +73,7 @@ export interface MlServicesContext { export type MlGlobalServices = ReturnType; const App: FC = ({ coreStart, deps, appMountParams }) => { - const pageDeps = { + const pageDeps: PageDependencies = { history: appMountParams.history, setHeaderActionMenu: appMountParams.setHeaderActionMenu, setBreadcrumbs: coreStart.chrome!.setBreadcrumbs, diff --git a/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx b/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx index 84cb353aa580b8..6c981351d5f634 100644 --- a/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx @@ -6,7 +6,7 @@ */ import React, { createContext, FC, useEffect, useMemo, useState } from 'react'; -import { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal'; +import { createHtmlPortalNode, type HtmlPortalNode } from 'react-reverse-portal'; import { Redirect } from 'react-router-dom'; import { Routes, Route } from '@kbn/shared-ux-router'; import { Subscription } from 'rxjs'; @@ -21,13 +21,14 @@ import { DatePickerWrapper } from '@kbn/ml-date-picker'; import * as routes from '../../routing/routes'; import { MlPageWrapper } from '../../routing/ml_page_wrapper'; import { useMlKibana, useNavigateToPath } from '../../contexts/kibana'; -import { MlRoute, PageDependencies } from '../../routing/router'; +import type { MlRoute, PageDependencies } from '../../routing/router'; import { useActiveRoute } from '../../routing/use_active_route'; import { useDocTitle } from '../../routing/use_doc_title'; import { MlPageHeaderRenderer } from '../page_header/page_header'; import { useSideNavItems } from './side_nav'; +import { usePermissionCheck } from '../../capabilities/check_capabilities'; const ML_APP_SELECTOR = '[data-test-subj="mlApp"]'; @@ -60,6 +61,17 @@ export const MlPage: FC<{ pageDeps: PageDependencies }> = React.memo(({ pageDeps const [isHeaderMounted, setIsHeaderMounted] = useState(false); const [isLoading, setIsLoading] = useState(false); + const [isADEnabled, isDFAEnabled, isNLPEnabled] = usePermissionCheck([ + 'isADEnabled', + 'isDFAEnabled', + 'isNLPEnabled', + ]); + + const navMenuEnabled = useMemo( + () => isADEnabled && isDFAEnabled && isNLPEnabled, + [isADEnabled, isDFAEnabled, isNLPEnabled] + ); + useEffect(() => { const subscriptions = new Subscription(); @@ -68,7 +80,6 @@ export const MlPage: FC<{ pageDeps: PageDependencies }> = React.memo(({ pageDeps setIsLoading(v !== 0); }) ); - return function cleanup() { subscriptions.unsubscribe(); }; @@ -111,6 +122,8 @@ export const MlPage: FC<{ pageDeps: PageDependencies }> = React.memo(({ pageDeps } }, [activeRoute]); + const sideNavItems = useSideNavItems(activeRoute); + return ( = React.memo(({ pageDeps className={'ml-app'} data-test-subj={'mlApp'} restrictWidth={false} - solutionNav={{ - name: i18n.translate('xpack.ml.plugin.title', { - defaultMessage: 'Machine Learning', - }), - icon: 'machineLearningApp', - items: useSideNavItems(activeRoute), - }} + solutionNav={ + navMenuEnabled + ? { + name: i18n.translate('xpack.ml.plugin.title', { + defaultMessage: 'Machine Learning', + }), + icon: 'machineLearningApp', + items: sideNavItems, + } + : undefined + } pageHeader={{ pageTitle: , rightSideItems, diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_is_serverless.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_is_serverless.ts deleted file mode 100644 index 120ae02b8d466c..00000000000000 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_is_serverless.ts +++ /dev/null @@ -1,14 +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 { useMemo } from 'react'; -import { useMlKibana } from './kibana_context'; - -export const useIsServerless = () => { - const isServerless = useMlKibana().services.mlServices.isServerless; - return useMemo(() => isServerless(), [isServerless]); -}; diff --git a/x-pack/plugins/ml/public/application/memory_usage/memory_usage_page.tsx b/x-pack/plugins/ml/public/application/memory_usage/memory_usage_page.tsx index 24e3dbab771b54..9fe3261aec74c4 100644 --- a/x-pack/plugins/ml/public/application/memory_usage/memory_usage_page.tsx +++ b/x-pack/plugins/ml/public/application/memory_usage/memory_usage_page.tsx @@ -12,8 +12,8 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { NodesList } from './nodes_overview'; import { MlPageHeader } from '../components/page_header'; import { MemoryPage, JobMemoryTreeMap } from './memory_tree_map'; -import { useIsServerless } from '../contexts/kibana/use_is_serverless'; import { SavedObjectsWarning } from '../components/saved_objects_warning'; +import { usePermissionCheck } from '../capabilities/check_capabilities'; enum TAB { NODES, @@ -21,9 +21,13 @@ enum TAB { } export const MemoryUsagePage: FC = () => { - const serverless = useIsServerless(); const [selectedTab, setSelectedTab] = useState(TAB.NODES); useTimefilter({ timeRangeSelector: false, autoRefreshSelector: true }); + const [isADEnabled, isDFAEnabled, isNLPEnabled] = usePermissionCheck([ + 'isADEnabled', + 'isDFAEnabled', + 'isNLPEnabled', + ]); const refresh = useCallback(() => { mlTimefilterRefresh$.next({ @@ -46,7 +50,7 @@ export const MemoryUsagePage: FC = () => { - {serverless ? ( + {isADEnabled && isDFAEnabled && isNLPEnabled ? ( ) : ( <> diff --git a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx index 1868ae0b8d85bf..09ba11f56c747f 100644 --- a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx +++ b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx @@ -80,7 +80,7 @@ export function useModelActions({ cluster: ['manage_ingest_pipelines'], }) .then((result) => { - const canManagePipelines = result.cluster.manage_ingest_pipelines; + const canManagePipelines = result.cluster?.manage_ingest_pipelines; if (isMounted) { setCanManageIngestPipelines(canManagePipelines); } diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx index 7b08bcec0331fc..4c04333b71e616 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx @@ -73,10 +73,12 @@ export const NotificationsList: FC = () => { const timeRange = useTimeRangeUpdates(); useMount(function setTimeRangeOnMount() { - timeFilter.setTime({ - from: moment(latestRequestedAt).toISOString(), - to: 'now', - }); + if (latestRequestedAt !== null) { + timeFilter.setTime({ + from: moment(latestRequestedAt).toISOString(), + to: 'now', + }); + } }); const [isLoading, setIsLoading] = useState(true); diff --git a/x-pack/plugins/ml/public/application/overview/components/content.tsx b/x-pack/plugins/ml/public/application/overview/components/content.tsx index 992a64015e7e4b..15998b9f58b935 100644 --- a/x-pack/plugins/ml/public/application/overview/components/content.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/content.tsx @@ -13,6 +13,7 @@ import { AnalyticsPanel } from './analytics_panel'; import { AnomalyTimelineService } from '../../services/anomaly_timeline_service'; import { mlResultsServiceProvider } from '../../services/results_service'; import { useMlKibana } from '../../contexts/kibana'; +import { usePermissionCheck } from '../../capabilities/check_capabilities'; interface Props { createAnomalyDetectionJobDisabled: boolean; @@ -32,6 +33,8 @@ export const OverviewContent: FC = ({ }, } = useMlKibana(); + const [isADEnabled, isDFAEnabled] = usePermissionCheck(['isADEnabled', 'isDFAEnabled']); + const timefilter = useTimefilter(); const [anomalyTimelineService, setAnomalyTimelineService] = useState(); @@ -49,12 +52,17 @@ export const OverviewContent: FC = ({ return ( <> - - - + {isADEnabled ? ( + <> + + + + ) : null} + + {isDFAEnabled ? : null} ); }; diff --git a/x-pack/plugins/ml/public/application/overview/overview_page.tsx b/x-pack/plugins/ml/public/application/overview/overview_page.tsx index 6772125bb95326..aad0dc45a35484 100644 --- a/x-pack/plugins/ml/public/application/overview/overview_page.tsx +++ b/x-pack/plugins/ml/public/application/overview/overview_page.tsx @@ -27,7 +27,6 @@ import { useMlKibana, useMlLink } from '../contexts/kibana'; import { NodesList } from '../memory_usage/nodes_overview'; import { MlPageHeader } from '../components/page_header'; import { PageTitle } from '../components/page_title'; -import { useIsServerless } from '../contexts/kibana/use_is_serverless'; import { getMlNodesCount } from '../ml_nodes_check/check_ml_nodes'; export const overviewPanelDefaultState = Object.freeze({ @@ -37,7 +36,6 @@ export const overviewPanelDefaultState = Object.freeze({ }); export const OverviewPage: FC = () => { - const serverless = useIsServerless(); const [canViewMlNodes, canCreateJob] = usePermissionCheck(['canViewMlNodes', 'canCreateJob']); const disableCreateAnomalyDetectionJob = !canCreateJob || !mlNodesAvailable(); @@ -83,7 +81,7 @@ export const OverviewPage: FC = () => { /> - {canViewMlNodes && serverless === false ? ( + {canViewMlNodes ? ( <> { - const { context } = useRouteResolver('full', ['canGetJobs'], { + const { context } = useRouteResolver('full', ['canGetMlInfo'], { getMlNodeCount, loadMlServerInfo, }); diff --git a/x-pack/plugins/ml/public/application/routing/routes/overview.tsx b/x-pack/plugins/ml/public/application/routing/routes/overview.tsx index 3dec773e24a1fc..33346b0d0fe72a 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/overview.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/overview.tsx @@ -42,7 +42,7 @@ export const overviewRouteFactory = ( }); const PageWrapper: FC = () => { - const { context } = useRouteResolver('full', ['canGetJobs'], { + const { context } = useRouteResolver('full', ['canGetMlInfo'], { getMlNodeCount, loadMlServerInfo, }); diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index f8362b3a92353b..f9f3b6d22b0fc1 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -25,7 +25,7 @@ import type { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/pu import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; -import { AppStatus, AppUpdater, DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; +import { AppStatus, type AppUpdater, DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; import type { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { LicenseManagementUIPluginSetup } from '@kbn/license-management-plugin/public'; @@ -47,11 +47,12 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { CasesUiSetup, CasesUiStart } from '@kbn/cases-plugin/public'; import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public'; import { registerManagementSection } from './application/management'; -import { MlLocatorDefinition, MlLocator } from './locator'; +import { MlLocatorDefinition, type MlLocator } from './locator'; import { setDependencyCache } from './application/util/dependency_cache'; import { registerFeature } from './register_feature'; import { isFullLicense, isMlEnabled } from '../common/license'; import { PLUGIN_ICON_SOLUTION, PLUGIN_ID } from '../common/constants/app'; +import type { MlCapabilities } from './shared'; export interface MlStartDependencies { data: DataPublicPluginStart; @@ -195,7 +196,7 @@ export class MlPlugin implements Plugin { } if (mlEnabled) { - registerSearchLinks(this.appUpdater$, fullLicense); + registerSearchLinks(this.appUpdater$, fullLicense, capabilities.ml as MlCapabilities); if (fullLicense) { registerEmbeddables(pluginsSetup.embeddable, core); diff --git a/x-pack/plugins/ml/public/register_helper/register_search_links/register_search_links.ts b/x-pack/plugins/ml/public/register_helper/register_search_links/register_search_links.ts index a25d7e24a7274f..35c37c56ecdffe 100644 --- a/x-pack/plugins/ml/public/register_helper/register_search_links/register_search_links.ts +++ b/x-pack/plugins/ml/public/register_helper/register_search_links/register_search_links.ts @@ -8,12 +8,14 @@ import { i18n } from '@kbn/i18n'; import { BehaviorSubject } from 'rxjs'; -import { AppUpdater } from '@kbn/core/public'; +import type { AppUpdater } from '@kbn/core/public'; import { getDeepLinks } from './search_deep_links'; +import type { MlCapabilities } from '../../shared'; export function registerSearchLinks( appUpdater: BehaviorSubject, - isFullLicense: boolean + isFullLicense: boolean, + mlCapabilities: MlCapabilities ) { appUpdater.next(() => ({ keywords: [ @@ -21,6 +23,6 @@ export function registerSearchLinks( defaultMessage: 'ML', }), ], - deepLinks: getDeepLinks(isFullLicense), + deepLinks: getDeepLinks(isFullLicense, mlCapabilities), })); } diff --git a/x-pack/plugins/ml/public/register_helper/register_search_links/search_deep_links.ts b/x-pack/plugins/ml/public/register_helper/register_search_links/search_deep_links.ts index d892c949b1d524..38e48db3787af7 100644 --- a/x-pack/plugins/ml/public/register_helper/register_search_links/search_deep_links.ts +++ b/x-pack/plugins/ml/public/register_helper/register_search_links/search_deep_links.ts @@ -8,203 +8,266 @@ import { i18n } from '@kbn/i18n'; import type { LinkId } from '@kbn/deeplinks-ml'; -import type { AppDeepLink } from '@kbn/core/public'; +import { type AppDeepLink, AppNavLinkStatus } from '@kbn/core/public'; import { ML_PAGES } from '../../../common/constants/locator'; +import type { MlCapabilities } from '../../shared'; -const OVERVIEW_LINK_DEEP_LINK: AppDeepLink = { - id: 'overview', - title: i18n.translate('xpack.ml.deepLink.overview', { - defaultMessage: 'Overview', - }), - path: `/${ML_PAGES.OVERVIEW}`, -}; - -const ANOMALY_DETECTION_DEEP_LINK: AppDeepLink = { - id: 'anomalyDetection', - title: i18n.translate('xpack.ml.deepLink.anomalyDetection', { - defaultMessage: 'Anomaly Detection', - }), - path: `/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`, - deepLinks: [ - { - id: 'anomalyExplorer', - title: i18n.translate('xpack.ml.deepLink.anomalyExplorer', { - defaultMessage: 'Anomaly explorer', - }), - path: `/${ML_PAGES.ANOMALY_EXPLORER}`, - }, - { - id: 'singleMetricViewer', - title: i18n.translate('xpack.ml.deepLink.singleMetricViewer', { - defaultMessage: 'Single metric viewer', - }), - path: `/${ML_PAGES.SINGLE_METRIC_VIEWER}`, - }, - ], -}; - -const DATA_FRAME_ANALYTICS_DEEP_LINK: AppDeepLink = { - id: 'dataFrameAnalytics', - title: i18n.translate('xpack.ml.deepLink.dataFrameAnalytics', { - defaultMessage: 'Data Frame Analytics', - }), - path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`, - deepLinks: [ - { - id: 'resultExplorer', - title: i18n.translate('xpack.ml.deepLink.resultExplorer', { - defaultMessage: 'Results explorer', - }), - path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION}`, - }, - { - id: 'analyticsMap', - title: i18n.translate('xpack.ml.deepLink.analyticsMap', { - defaultMessage: 'Analytics map', - }), - path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_MAP}`, - }, - ], -}; - -const AIOPS_DEEP_LINK: AppDeepLink = { - id: 'aiOps', - title: i18n.translate('xpack.ml.deepLink.aiOps', { - defaultMessage: 'AIOps', - }), - // Default to the index select page for the explain log rate spikes since we don't have an AIops overview page - path: `/${ML_PAGES.AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT}`, - deepLinks: [ - { - id: 'explainLogRateSpikes', - title: i18n.translate('xpack.ml.deepLink.explainLogRateSpikes', { - defaultMessage: 'Explain Log Rate Spikes', - }), - path: `/${ML_PAGES.AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT}`, - }, - { - id: 'logPatternAnalysis', - title: i18n.translate('xpack.ml.deepLink.logPatternAnalysis', { - defaultMessage: 'Log Pattern Analysis', - }), - path: `/${ML_PAGES.AIOPS_LOG_CATEGORIZATION_INDEX_SELECT}`, - }, - { - id: 'changePointDetections', - title: i18n.translate('xpack.ml.deepLink.changePointDetection', { - defaultMessage: 'Change Point Detection', - }), - path: `/${ML_PAGES.AIOPS_CHANGE_POINT_DETECTION_INDEX_SELECT}`, - }, - ], -}; - -const MODEL_MANAGEMENT_DEEP_LINK: AppDeepLink = { - id: 'modelManagement', - title: i18n.translate('xpack.ml.deepLink.modelManagement', { - defaultMessage: 'Model Management', - }), - path: `/${ML_PAGES.TRAINED_MODELS_MANAGE}`, - deepLinks: [ - { - id: 'nodesOverview', - title: i18n.translate('xpack.ml.deepLink.trainedModels', { - defaultMessage: 'Trained Models', - }), - path: `/${ML_PAGES.TRAINED_MODELS_MANAGE}`, - }, - { - id: 'nodes', - title: i18n.translate('xpack.ml.deepLink.nodes', { - defaultMessage: 'Nodes', - }), - path: `/${ML_PAGES.NODES}`, - }, - ], -}; - -const MEMORY_USAGE_DEEP_LINK: AppDeepLink = { - id: 'memoryUsage', - title: i18n.translate('xpack.ml.deepLink.memoryUsage', { - defaultMessage: 'Memory Usage', - }), - path: `/${ML_PAGES.MEMORY_USAGE}`, -}; - -const DATA_VISUALIZER_DEEP_LINK: AppDeepLink = { - id: 'dataVisualizer', - title: i18n.translate('xpack.ml.deepLink.dataVisualizer', { - defaultMessage: 'Data Visualizer', - }), - path: `/${ML_PAGES.DATA_VISUALIZER}`, -}; - -const FILE_UPLOAD_DEEP_LINK: AppDeepLink = { - id: 'fileUpload', - title: i18n.translate('xpack.ml.deepLink.fileUpload', { - defaultMessage: 'File Upload', - }), - keywords: ['CSV', 'JSON'], - path: `/${ML_PAGES.DATA_VISUALIZER_FILE}`, -}; - -const INDEX_DATA_VISUALIZER_DEEP_LINK: AppDeepLink = { - id: 'indexDataVisualizer', - title: i18n.translate('xpack.ml.deepLink.indexDataVisualizer', { - defaultMessage: 'Index Data Visualizer', - }), - path: `/${ML_PAGES.DATA_VISUALIZER_INDEX_SELECT}`, -}; - -const SETTINGS_DEEP_LINK: AppDeepLink = { - id: 'settings', - title: i18n.translate('xpack.ml.deepLink.settings', { - defaultMessage: 'Settings', - }), - path: `/${ML_PAGES.SETTINGS}`, - deepLinks: [ - { - id: 'calendarSettings', - title: i18n.translate('xpack.ml.deepLink.calendarSettings', { - defaultMessage: 'Calendars', - }), - path: `/${ML_PAGES.CALENDARS_MANAGE}`, - }, - { - id: 'filterListsSettings', - title: i18n.translate('xpack.ml.deepLink.filterListsSettings', { - defaultMessage: 'Filter Lists', - }), - path: `/${ML_PAGES.SETTINGS}`, // Link to settings page as read only users cannot view filter lists. - }, - ], -}; - -const NOTIFICATIONS_DEEP_LINK: AppDeepLink = { - id: 'notifications', - title: i18n.translate('xpack.ml.deepLink.notifications', { - defaultMessage: 'Notifications', - }), - path: `/${ML_PAGES.NOTIFICATIONS}`, -}; - -export function getDeepLinks(isFullLicense: boolean) { +function getNavStatus( + mlCapabilities: MlCapabilities, + statusIfServerless: boolean +): AppNavLinkStatus | undefined { + if (mlCapabilities.isADEnabled && mlCapabilities.isDFAEnabled && mlCapabilities.isNLPEnabled) { + // if all features are enabled we can assume that we are not running in serverless mode. + // returning default will not add the link to the nav menu, but the link will be registered for searching + return AppNavLinkStatus.default; + } + + return statusIfServerless ? AppNavLinkStatus.visible : AppNavLinkStatus.hidden; +} + +function getOverviewLinkDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'overview', + title: i18n.translate('xpack.ml.deepLink.overview', { + defaultMessage: 'Overview', + }), + path: `/${ML_PAGES.OVERVIEW}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }; +} + +function getAnomalyDetectionDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + const navLinkStatus = getNavStatus(mlCapabilities, mlCapabilities.isADEnabled); + return { + id: 'anomalyDetection', + title: i18n.translate('xpack.ml.deepLink.anomalyDetection', { + defaultMessage: 'Anomaly Detection', + }), + path: `/${ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE}`, + navLinkStatus, + deepLinks: [ + { + id: 'anomalyExplorer', + title: i18n.translate('xpack.ml.deepLink.anomalyExplorer', { + defaultMessage: 'Anomaly explorer', + }), + path: `/${ML_PAGES.ANOMALY_EXPLORER}`, + navLinkStatus, + }, + { + id: 'singleMetricViewer', + title: i18n.translate('xpack.ml.deepLink.singleMetricViewer', { + defaultMessage: 'Single metric viewer', + }), + path: `/${ML_PAGES.SINGLE_METRIC_VIEWER}`, + navLinkStatus, + }, + ], + }; +} + +function getDataFrameAnalyticsDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + const navLinkStatus = getNavStatus(mlCapabilities, mlCapabilities.isDFAEnabled); + return { + id: 'dataFrameAnalytics', + title: i18n.translate('xpack.ml.deepLink.dataFrameAnalytics', { + defaultMessage: 'Data Frame Analytics', + }), + path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE}`, + navLinkStatus, + deepLinks: [ + { + id: 'resultExplorer', + title: i18n.translate('xpack.ml.deepLink.resultExplorer', { + defaultMessage: 'Results explorer', + }), + path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION}`, + navLinkStatus, + }, + { + id: 'analyticsMap', + title: i18n.translate('xpack.ml.deepLink.analyticsMap', { + defaultMessage: 'Analytics map', + }), + path: `/${ML_PAGES.DATA_FRAME_ANALYTICS_MAP}`, + navLinkStatus, + }, + ], + }; +} + +function getAiopsDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + const navLinkStatus = getNavStatus(mlCapabilities, mlCapabilities.canUseAiops); + return { + id: 'aiOps', + title: i18n.translate('xpack.ml.deepLink.aiOps', { + defaultMessage: 'AIOps', + }), + // Default to the index select page for the explain log rate spikes since we don't have an AIops overview page + path: `/${ML_PAGES.AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT}`, + navLinkStatus, + deepLinks: [ + { + id: 'explainLogRateSpikes', + title: i18n.translate('xpack.ml.deepLink.explainLogRateSpikes', { + defaultMessage: 'Explain Log Rate Spikes', + }), + path: `/${ML_PAGES.AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT}`, + navLinkStatus, + }, + { + id: 'logPatternAnalysis', + title: i18n.translate('xpack.ml.deepLink.logPatternAnalysis', { + defaultMessage: 'Log Pattern Analysis', + }), + path: `/${ML_PAGES.AIOPS_LOG_CATEGORIZATION_INDEX_SELECT}`, + navLinkStatus, + }, + { + id: 'changePointDetections', + title: i18n.translate('xpack.ml.deepLink.changePointDetection', { + defaultMessage: 'Change Point Detection', + }), + path: `/${ML_PAGES.AIOPS_CHANGE_POINT_DETECTION_INDEX_SELECT}`, + navLinkStatus, + }, + ], + }; +} + +function getModelManagementDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + const navLinkStatus = getNavStatus(mlCapabilities, mlCapabilities.isNLPEnabled); + return { + id: 'modelManagement', + title: i18n.translate('xpack.ml.deepLink.modelManagement', { + defaultMessage: 'Model Management', + }), + path: `/${ML_PAGES.TRAINED_MODELS_MANAGE}`, + navLinkStatus, + deepLinks: [ + { + id: 'nodesOverview', + title: i18n.translate('xpack.ml.deepLink.trainedModels', { + defaultMessage: 'Trained Models', + }), + path: `/${ML_PAGES.TRAINED_MODELS_MANAGE}`, + navLinkStatus, + }, + { + id: 'nodes', + title: i18n.translate('xpack.ml.deepLink.nodes', { + defaultMessage: 'Nodes', + }), + path: `/${ML_PAGES.NODES}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }, + ], + }; +} + +function getMemoryUsageDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'memoryUsage', + title: i18n.translate('xpack.ml.deepLink.memoryUsage', { + defaultMessage: 'Memory Usage', + }), + path: `/${ML_PAGES.MEMORY_USAGE}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }; +} + +function getDataVisualizerDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'dataVisualizer', + title: i18n.translate('xpack.ml.deepLink.dataVisualizer', { + defaultMessage: 'Data Visualizer', + }), + path: `/${ML_PAGES.DATA_VISUALIZER}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }; +} + +function getFileUploadDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'fileUpload', + title: i18n.translate('xpack.ml.deepLink.fileUpload', { + defaultMessage: 'File Upload', + }), + keywords: ['CSV', 'JSON'], + path: `/${ML_PAGES.DATA_VISUALIZER_FILE}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }; +} + +function getIndexDataVisualizerDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'indexDataVisualizer', + title: i18n.translate('xpack.ml.deepLink.indexDataVisualizer', { + defaultMessage: 'Index Data Visualizer', + }), + path: `/${ML_PAGES.DATA_VISUALIZER_INDEX_SELECT}`, + navLinkStatus: getNavStatus(mlCapabilities, false), + }; +} + +function getSettingsDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + const navLinkStatus = getNavStatus(mlCapabilities, mlCapabilities.isADEnabled); + return { + id: 'settings', + title: i18n.translate('xpack.ml.deepLink.settings', { + defaultMessage: 'Settings', + }), + path: `/${ML_PAGES.SETTINGS}`, + navLinkStatus, + deepLinks: [ + { + id: 'calendarSettings', + title: i18n.translate('xpack.ml.deepLink.calendarSettings', { + defaultMessage: 'Calendars', + }), + path: `/${ML_PAGES.CALENDARS_MANAGE}`, + navLinkStatus, + }, + { + id: 'filterListsSettings', + title: i18n.translate('xpack.ml.deepLink.filterListsSettings', { + defaultMessage: 'Filter Lists', + }), + path: `/${ML_PAGES.SETTINGS}`, // Link to settings page as read only users cannot view filter lists. + navLinkStatus, + }, + ], + }; +} + +function getNotificationsDeepLink(mlCapabilities: MlCapabilities): AppDeepLink { + return { + id: 'notifications', + title: i18n.translate('xpack.ml.deepLink.notifications', { + defaultMessage: 'Notifications', + }), + path: `/${ML_PAGES.NOTIFICATIONS}`, + navLinkStatus: getNavStatus(mlCapabilities, true), + }; +} + +export function getDeepLinks(isFullLicense: boolean, mlCapabilities: MlCapabilities) { const deepLinks: Array> = [ - DATA_VISUALIZER_DEEP_LINK, - FILE_UPLOAD_DEEP_LINK, - INDEX_DATA_VISUALIZER_DEEP_LINK, + getDataVisualizerDeepLink(mlCapabilities), + getFileUploadDeepLink(mlCapabilities), + getIndexDataVisualizerDeepLink(mlCapabilities), ]; if (isFullLicense === true) { deepLinks.push( - OVERVIEW_LINK_DEEP_LINK, - ANOMALY_DETECTION_DEEP_LINK, - DATA_FRAME_ANALYTICS_DEEP_LINK, - MODEL_MANAGEMENT_DEEP_LINK, - MEMORY_USAGE_DEEP_LINK, - SETTINGS_DEEP_LINK, - AIOPS_DEEP_LINK, - NOTIFICATIONS_DEEP_LINK + getOverviewLinkDeepLink(mlCapabilities), + getAnomalyDetectionDeepLink(mlCapabilities), + getDataFrameAnalyticsDeepLink(mlCapabilities), + getModelManagementDeepLink(mlCapabilities), + getMemoryUsageDeepLink(mlCapabilities), + getSettingsDeepLink(mlCapabilities), + getAiopsDeepLink(mlCapabilities), + getNotificationsDeepLink(mlCapabilities) ); } diff --git a/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts b/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts index bc90437e8fcc66..2be5bd877552ac 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts @@ -7,20 +7,30 @@ import { cloneDeep } from 'lodash'; import { firstValueFrom, Observable } from 'rxjs'; -import { CapabilitiesSwitcher, CoreSetup, Logger } from '@kbn/core/server'; -import { ILicense } from '@kbn/licensing-plugin/common/types'; +import type { CapabilitiesSwitcher, CoreSetup, Logger } from '@kbn/core/server'; +import type { ILicense } from '@kbn/licensing-plugin/common/types'; import { isFullLicense, isMinimumLicense, isMlEnabled } from '../../../common/license'; -import { MlCapabilities, basicLicenseMlCapabilities } from '../../../common/types/capabilities'; +import { + type MlCapabilities, + basicLicenseMlCapabilities, + featureCapabilities, +} from '../../../common/types/capabilities'; +import type { MlFeatures } from '../../types'; export const setupCapabilitiesSwitcher = ( coreSetup: CoreSetup, license$: Observable, + enabledFeatures: MlFeatures, logger: Logger ) => { - coreSetup.capabilities.registerSwitcher(getSwitcher(license$, logger)); + coreSetup.capabilities.registerSwitcher(getSwitcher(license$, logger, enabledFeatures)); }; -function getSwitcher(license$: Observable, logger: Logger): CapabilitiesSwitcher { +function getSwitcher( + license$: Observable, + logger: Logger, + enabledFeatures: MlFeatures +): CapabilitiesSwitcher { return async (request, capabilities) => { const isAnonymousRequest = !request.route.options.authRequired; if (isAnonymousRequest) { @@ -31,15 +41,15 @@ function getSwitcher(license$: Observable, logger: Logger): Capabiliti const license = await firstValueFrom(license$); const mlEnabled = isMlEnabled(license); + const originalCapabilities = capabilities.ml as MlCapabilities; + const mlCaps = cloneDeep(originalCapabilities); + // full license, leave capabilities as they were if (mlEnabled && isFullLicense(license)) { - return {}; + return { ml: applyEnabledFeatures(mlCaps, enabledFeatures) }; } - const originalCapabilities = capabilities.ml as MlCapabilities; - const mlCaps = cloneDeep(originalCapabilities); - - // not full licence, switch off all capabilities + // not full license, switch off all capabilities Object.keys(mlCaps).forEach((k) => { mlCaps[k as keyof MlCapabilities] = false; }); @@ -49,10 +59,31 @@ function getSwitcher(license$: Observable, logger: Logger): Capabiliti basicLicenseMlCapabilities.forEach((c) => (mlCaps[c] = originalCapabilities[c])); } - return { ml: mlCaps }; + return { ml: applyEnabledFeatures(mlCaps, enabledFeatures) }; } catch (e) { logger.debug(`Error updating capabilities for ML based on licensing: ${e}`); return {}; } }; } + +function applyEnabledFeatures(mlCaps: MlCapabilities, enabledFeatures: MlFeatures) { + mlCaps.isADEnabled = enabledFeatures.ad; + mlCaps.isDFAEnabled = enabledFeatures.dfa; + mlCaps.isNLPEnabled = enabledFeatures.nlp; + + mlCaps.canViewMlNodes = + mlCaps.canViewMlNodes && mlCaps.isADEnabled && mlCaps.isDFAEnabled && mlCaps.isNLPEnabled; + + if (enabledFeatures.ad === false) { + featureCapabilities.ad.forEach((c) => (mlCaps[c] = false)); + } + if (enabledFeatures.dfa === false) { + featureCapabilities.dfa.forEach((c) => (mlCaps[c] = false)); + } + if (enabledFeatures.nlp === false) { + featureCapabilities.nlp.forEach((c) => (mlCaps[c] = false)); + } + + return mlCaps; +} diff --git a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts index 93e22c7e099ce8..b66af28faff262 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts @@ -47,7 +47,7 @@ describe('check_capabilities', () => { ); const { capabilities } = await getCapabilities(); const count = Object.keys(capabilities).length; - expect(count).toBe(39); + expect(count).toBe(42); }); }); @@ -105,6 +105,10 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(false); expect(capabilities.canDeleteTrainedModels).toBe(false); expect(capabilities.canStartStopTrainedModels).toBe(false); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); test('full capabilities', async () => { @@ -160,6 +164,10 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(true); expect(capabilities.canDeleteTrainedModels).toBe(true); expect(capabilities.canStartStopTrainedModels).toBe(true); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); test('upgrade in progress with full capabilities', async () => { @@ -215,6 +223,10 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(false); expect(capabilities.canDeleteTrainedModels).toBe(false); expect(capabilities.canStartStopTrainedModels).toBe(false); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); test('upgrade in progress with partial capabilities', async () => { @@ -270,6 +282,10 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(false); expect(capabilities.canDeleteTrainedModels).toBe(false); expect(capabilities.canStartStopTrainedModels).toBe(false); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); test('full capabilities, ml disabled in space', async () => { @@ -325,6 +341,10 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(false); expect(capabilities.canDeleteTrainedModels).toBe(false); expect(capabilities.canStartStopTrainedModels).toBe(false); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); }); @@ -381,5 +401,9 @@ describe('check_capabilities', () => { expect(capabilities.canCreateTrainedModels).toBe(false); expect(capabilities.canDeleteTrainedModels).toBe(false); expect(capabilities.canStartStopTrainedModels).toBe(false); + + expect(capabilities.isADEnabled).toBe(true); + expect(capabilities.isDFAEnabled).toBe(true); + expect(capabilities.isNLPEnabled).toBe(true); }); }); diff --git a/x-pack/plugins/ml/server/models/notifications_service/notifications_service_provider.ts b/x-pack/plugins/ml/server/models/notifications_service/notifications_service_provider.ts index 57f117561463c6..4ee191693e4516 100644 --- a/x-pack/plugins/ml/server/models/notifications_service/notifications_service_provider.ts +++ b/x-pack/plugins/ml/server/models/notifications_service/notifications_service_provider.ts @@ -19,13 +19,20 @@ import type { NotificationsCountResponse, NotificationsSearchResponse, } from '../../../common/types/notifications'; +import type { MlFeatures } from '../../types'; const MAX_NOTIFICATIONS_SIZE = 10000; +interface EntityIdsPerType { + type: 'anomaly_detector' | 'data_frame_analytics' | 'inference' | 'system'; + ids?: Array; +} + export class NotificationsService { constructor( private readonly scopedClusterClient: IScopedClusterClient, - private readonly mlSavedObjectService: MLSavedObjectService + private readonly mlSavedObjectService: MLSavedObjectService, + private readonly enabledFeatures: MlFeatures ) {} private getDefaultCountResponse() { @@ -42,17 +49,23 @@ export class NotificationsService { */ private async _getEntityIdsPerType() { const [adJobIds, dfaJobIds, modelIds] = await Promise.all([ - this.mlSavedObjectService.getAnomalyDetectionJobIds(), - this.mlSavedObjectService.getDataFrameAnalyticsJobIds(), - this.mlSavedObjectService.getTrainedModelsIds(), + this.enabledFeatures.ad ? this.mlSavedObjectService.getAnomalyDetectionJobIds() : [], + this.enabledFeatures.dfa ? this.mlSavedObjectService.getDataFrameAnalyticsJobIds() : [], + this.enabledFeatures.nlp ? this.mlSavedObjectService.getTrainedModelsIds() : [], ]); + const idsPerType: EntityIdsPerType[] = [{ type: 'system' }]; + + if (this.enabledFeatures.ad) { + idsPerType.push({ type: 'anomaly_detector', ids: adJobIds }); + } + if (this.enabledFeatures.dfa) { + idsPerType.push({ type: 'data_frame_analytics', ids: dfaJobIds }); + } + if (this.enabledFeatures.ad) { + idsPerType.push({ type: 'inference', ids: modelIds as string[] }); + } - return [ - { type: 'anomaly_detector', ids: adJobIds }, - { type: 'data_frame_analytics', ids: dfaJobIds }, - { type: 'inference', ids: modelIds }, - { type: 'system' }, - ].filter((v) => v.ids === undefined || v.ids.length > 0); + return idsPerType.filter((v) => v.ids === undefined || v.ids.length > 0); } /** diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index db150f7c42f323..bb6fc5460761b0 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -26,7 +26,7 @@ import { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import type { HomeServerPluginSetup } from '@kbn/home-plugin/server'; import { jsonSchemaRoutes } from './routes/json_schema'; import { notificationsRoutes } from './routes/notifications'; -import type { PluginsSetup, PluginsStart, RouteInitialization } from './types'; +import type { MlFeatures, PluginsSetup, PluginsStart, RouteInitialization } from './types'; import { PLUGIN_ID } from '../common/constants/app'; import type { MlCapabilities } from '../common/types/capabilities'; @@ -73,7 +73,13 @@ import { CASE_ATTACHMENT_TYPE_ID_ANOMALY_EXPLORER_CHARTS, } from '../common/constants/cases'; -export type MlPluginSetup = SharedServices; +type SetFeaturesEnabled = (features: MlFeatures) => void; + +interface MlSetup { + setFeaturesEnabled: SetFeaturesEnabled; +} + +export type MlPluginSetup = SharedServices & MlSetup; export type MlPluginStart = void; export class MlServerPlugin @@ -93,6 +99,11 @@ export class MlServerPlugin private isMlReady: Promise; private setMlReady: () => void = () => {}; private savedObjectsSyncService: SavedObjectsSyncService; + private enabledFeatures: MlFeatures = { + ad: true, + dfa: true, + nlp: true, + }; constructor(ctx: PluginInitializerContext) { this.log = ctx.logger.get(); @@ -149,7 +160,12 @@ export class MlServerPlugin registerKibanaSettings(coreSetup); // initialize capabilities switcher to add license filter to ml capabilities - setupCapabilitiesSwitcher(coreSetup, plugins.licensing.license$, this.log); + setupCapabilitiesSwitcher( + coreSetup, + plugins.licensing.license$, + this.enabledFeatures, + this.log + ); setupSavedObjects(coreSetup.savedObjects); this.savedObjectsSyncService.registerSyncTask( plugins.taskManager, @@ -208,6 +224,7 @@ export class MlServerPlugin coreSetup.getStartServices ), mlLicense: this.mlLicense, + enabledFeatures: this.enabledFeatures, }; annotationRoutes(routeInit, plugins.security); @@ -269,7 +286,19 @@ export class MlServerPlugin }); } - return sharedServicesProviders; + const setFeaturesEnabled = (features: MlFeatures) => { + if (features.ad !== undefined) { + this.enabledFeatures.ad = features.ad; + } + if (features.dfa !== undefined) { + this.enabledFeatures.dfa = features.dfa; + } + if (features.nlp !== undefined) { + this.enabledFeatures.nlp = features.nlp; + } + }; + + return { ...sharedServicesProviders, setFeaturesEnabled }; } public start(coreStart: CoreStart, plugins: PluginsStart): MlPluginStart { diff --git a/x-pack/plugins/ml/server/routes/notifications.ts b/x-pack/plugins/ml/server/routes/notifications.ts index 8e67136e83ddda..f9c64543dd0425 100644 --- a/x-pack/plugins/ml/server/routes/notifications.ts +++ b/x-pack/plugins/ml/server/routes/notifications.ts @@ -12,9 +12,9 @@ import { getNotificationsQuerySchema, } from './schemas/notifications_schema'; import { wrapError } from '../client/error_wrapper'; -import { RouteInitialization } from '../types'; +import type { RouteInitialization } from '../types'; -export function notificationsRoutes({ router, routeGuard }: RouteInitialization) { +export function notificationsRoutes({ router, routeGuard, enabledFeatures }: RouteInitialization) { /** * @apiGroup Notifications * @@ -46,7 +46,11 @@ export function notificationsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard( async ({ client, request, response, mlSavedObjectService }) => { try { - const notificationsService = new NotificationsService(client, mlSavedObjectService); + const notificationsService = new NotificationsService( + client, + mlSavedObjectService, + enabledFeatures + ); const results = await notificationsService.searchMessages(request.query); @@ -91,7 +95,11 @@ export function notificationsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard( async ({ client, mlSavedObjectService, request, response }) => { try { - const notificationsService = new NotificationsService(client, mlSavedObjectService); + const notificationsService = new NotificationsService( + client, + mlSavedObjectService, + enabledFeatures + ); const results = await notificationsService.countMessages(request.query); diff --git a/x-pack/plugins/ml/server/types.ts b/x-pack/plugins/ml/server/types.ts index d054a2289be50b..4bca1336ae0b91 100644 --- a/x-pack/plugins/ml/server/types.ts +++ b/x-pack/plugins/ml/server/types.ts @@ -80,4 +80,7 @@ export interface RouteInitialization { router: IRouter; mlLicense: MlLicense; routeGuard: RouteGuard; + enabledFeatures: MlFeatures; } + +export type MlFeatures = Record<'ad' | 'dfa' | 'nlp', boolean>; diff --git a/x-pack/plugins/serverless_observability/kibana.jsonc b/x-pack/plugins/serverless_observability/kibana.jsonc index af3fca8d819388..0f85a1033c2eae 100644 --- a/x-pack/plugins/serverless_observability/kibana.jsonc +++ b/x-pack/plugins/serverless_observability/kibana.jsonc @@ -8,7 +8,7 @@ "server": true, "browser": true, "configPath": ["xpack", "serverless", "observability"], - "requiredPlugins": ["serverless", "observabilityShared", "kibanaReact", "management"], + "requiredPlugins": ["serverless", "observabilityShared", "kibanaReact", "management", "ml"], "optionalPlugins": [], "requiredBundles": [] } diff --git a/x-pack/plugins/serverless_observability/server/plugin.ts b/x-pack/plugins/serverless_observability/server/plugin.ts index 8b28ba2b0a4ac4..ae7bcd8baa0648 100644 --- a/x-pack/plugins/serverless_observability/server/plugin.ts +++ b/x-pack/plugins/serverless_observability/server/plugin.ts @@ -5,16 +5,28 @@ * 2.0. */ -import { PluginInitializerContext, Plugin } from '@kbn/core/server'; +import type { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; -import { ServerlessObservabilityPluginSetup, ServerlessObservabilityPluginStart } from './types'; +import type { + ServerlessObservabilityPluginSetup, + ServerlessObservabilityPluginStart, + SetupDependencies, + StartDependencies, +} from './types'; export class ServerlessObservabilityPlugin - implements Plugin + implements + Plugin< + ServerlessObservabilityPluginSetup, + ServerlessObservabilityPluginStart, + SetupDependencies, + StartDependencies + > { constructor(_initializerContext: PluginInitializerContext) {} - public setup() { + public setup(_coreSetup: CoreSetup, pluginsSetup: SetupDependencies) { + pluginsSetup.ml.setFeaturesEnabled({ ad: true, dfa: false, nlp: false }); return {}; } diff --git a/x-pack/plugins/serverless_observability/server/types.ts b/x-pack/plugins/serverless_observability/server/types.ts index f8a587103e8862..5ebad2274b9a5f 100644 --- a/x-pack/plugins/serverless_observability/server/types.ts +++ b/x-pack/plugins/serverless_observability/server/types.ts @@ -5,7 +5,16 @@ * 2.0. */ +import type { MlPluginSetup } from '@kbn/ml-plugin/server'; + // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ServerlessObservabilityPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ServerlessObservabilityPluginStart {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface StartDependencies {} + +export interface SetupDependencies { + ml: MlPluginSetup; +} diff --git a/x-pack/plugins/serverless_observability/tsconfig.json b/x-pack/plugins/serverless_observability/tsconfig.json index 5617f682781932..c45e5484f3ca30 100644 --- a/x-pack/plugins/serverless_observability/tsconfig.json +++ b/x-pack/plugins/serverless_observability/tsconfig.json @@ -22,6 +22,7 @@ "@kbn/observability-shared-plugin", "@kbn/kibana-react-plugin", "@kbn/shared-ux-chrome-navigation", + "@kbn/ml-plugin", "@kbn/i18n", "@kbn/management-cards-navigation", ] diff --git a/x-pack/plugins/serverless_search/kibana.jsonc b/x-pack/plugins/serverless_search/kibana.jsonc index 95484ec54dc43f..a8c6b8c3b77ee9 100644 --- a/x-pack/plugins/serverless_search/kibana.jsonc +++ b/x-pack/plugins/serverless_search/kibana.jsonc @@ -9,18 +9,19 @@ "browser": true, "configPath": ["xpack", "serverless", "search"], "requiredPlugins": [ - "serverless", "cloud", - "management", - "security", - "share", - "devTools", "console", - "searchprofiler", + "dashboard", + "devTools", + "discover", "grokdebugger", + "management", + "ml", "painlessLab", - "discover", - "dashboard", + "searchprofiler", + "security", + "serverless", + "share", "visualizations" ], "optionalPlugins": [], diff --git a/x-pack/plugins/serverless_search/public/layout/nav.tsx b/x-pack/plugins/serverless_search/public/layout/nav.tsx index b1576c539a6491..afc8aba90cbc81 100644 --- a/x-pack/plugins/serverless_search/public/layout/nav.tsx +++ b/x-pack/plugins/serverless_search/public/layout/nav.tsx @@ -5,16 +5,16 @@ * 2.0. */ -import { CoreStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import { DefaultNavigation, NavigationKibanaProvider, - NavigationTreeDefinition, + type NavigationTreeDefinition, getPresets, } from '@kbn/shared-ux-chrome-navigation'; import React from 'react'; import { i18n } from '@kbn/i18n'; -import { ServerlessPluginStart } from '@kbn/serverless/public'; +import type { ServerlessPluginStart } from '@kbn/serverless/public'; const navigationTree: NavigationTreeDefinition = { body: [ @@ -100,6 +100,10 @@ const navigationTree: NavigationTreeDefinition = { }, ], }, + { + type: 'navGroup', + ...getPresets('ml'), + }, ], }; diff --git a/x-pack/plugins/serverless_search/server/plugin.ts b/x-pack/plugins/serverless_search/server/plugin.ts index 760e59f82199c4..767d51ff0c4392 100644 --- a/x-pack/plugins/serverless_search/server/plugin.ts +++ b/x-pack/plugins/serverless_search/server/plugin.ts @@ -5,17 +5,25 @@ * 2.0. */ -import { IRouter, Logger, PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; -import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import type { + IRouter, + Logger, + PluginInitializerContext, + Plugin, + CoreSetup, +} from '@kbn/core/server'; +import type { SecurityPluginStart } from '@kbn/security-plugin/server'; import { registerApiKeyRoutes } from './routes/api_key_routes'; import { registerIndicesRoutes } from './routes/indices_routes'; -import { ServerlessSearchConfig } from './config'; -import { ServerlessSearchPluginSetup, ServerlessSearchPluginStart } from './types'; +import type { ServerlessSearchConfig } from './config'; +import type { + ServerlessSearchPluginSetup, + ServerlessSearchPluginStart, + SetupDependencies, + StartDependencies, +} from './types'; -interface StartDependencies { - security: SecurityPluginStart; -} export interface RouteDependencies { logger: Logger; router: IRouter; @@ -23,7 +31,13 @@ export interface RouteDependencies { } export class ServerlessSearchPlugin - implements Plugin + implements + Plugin< + ServerlessSearchPluginSetup, + ServerlessSearchPluginStart, + SetupDependencies, + StartDependencies + > { // @ts-ignore config is not used for now private readonly config: ServerlessSearchConfig; @@ -35,7 +49,10 @@ export class ServerlessSearchPlugin this.logger = initializerContext.logger.get(); } - public setup({ getStartServices, http }: CoreSetup) { + public setup( + { getStartServices, http }: CoreSetup, + pluginsSetup: SetupDependencies + ) { const router = http.createRouter(); getStartServices().then(([, { security }]) => { this.security = security; @@ -44,6 +61,8 @@ export class ServerlessSearchPlugin registerApiKeyRoutes(dependencies); registerIndicesRoutes(dependencies); }); + + pluginsSetup.ml.setFeaturesEnabled({ ad: false, dfa: false, nlp: true }); return {}; } diff --git a/x-pack/plugins/serverless_search/server/types.ts b/x-pack/plugins/serverless_search/server/types.ts index 6011e2eb60fa01..8e8f7f15a81241 100644 --- a/x-pack/plugins/serverless_search/server/types.ts +++ b/x-pack/plugins/serverless_search/server/types.ts @@ -5,7 +5,17 @@ * 2.0. */ +import type { SecurityPluginStart } from '@kbn/security-plugin/server'; +import type { MlPluginSetup } from '@kbn/ml-plugin/server'; + // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ServerlessSearchPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ServerlessSearchPluginStart {} + +export interface StartDependencies { + security: SecurityPluginStart; +} +export interface SetupDependencies { + ml: MlPluginSetup; +} diff --git a/x-pack/plugins/serverless_search/tsconfig.json b/x-pack/plugins/serverless_search/tsconfig.json index 1a52fe61875698..91a3f465ca4c63 100644 --- a/x-pack/plugins/serverless_search/tsconfig.json +++ b/x-pack/plugins/serverless_search/tsconfig.json @@ -27,6 +27,7 @@ "@kbn/security-plugin", "@kbn/cloud-plugin", "@kbn/share-plugin", + "@kbn/ml-plugin", "@kbn/management-cards-navigation", "@kbn/core-elasticsearch-server", ] diff --git a/x-pack/plugins/serverless_security/kibana.jsonc b/x-pack/plugins/serverless_security/kibana.jsonc index 4e9fcabdffd7d8..daa7490a386510 100644 --- a/x-pack/plugins/serverless_security/kibana.jsonc +++ b/x-pack/plugins/serverless_security/kibana.jsonc @@ -13,10 +13,11 @@ "security" ], "requiredPlugins": [ - "serverless", + "kibanaReact", + "ml", "security", "securitySolution", - "kibanaReact" + "serverless" ], "optionalPlugins": [ "essSecurity" diff --git a/x-pack/plugins/serverless_security/server/plugin.ts b/x-pack/plugins/serverless_security/server/plugin.ts index 6cf98846bcd239..aae5106d9a0d21 100644 --- a/x-pack/plugins/serverless_security/server/plugin.ts +++ b/x-pack/plugins/serverless_security/server/plugin.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; -import { ServerlessSecurityConfig } from './config'; +import type { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; +import type { ServerlessSecurityConfig } from './config'; import { getProductAppFeatures } from '../common/pli/pli_features'; -import { +import type { ServerlessSecurityPluginSetup, ServerlessSecurityPluginStart, ServerlessSecurityPluginSetupDependencies, @@ -41,6 +41,8 @@ export class ServerlessSecurityPlugin pluginsSetup.securitySolution.setAppFeatures(getProductAppFeatures(this.config.productTypes)); } + pluginsSetup.ml.setFeaturesEnabled({ ad: true, dfa: true, nlp: false }); + return {}; } diff --git a/x-pack/plugins/serverless_security/server/types.ts b/x-pack/plugins/serverless_security/server/types.ts index 6756351c9bf6e6..9cd615265338d4 100644 --- a/x-pack/plugins/serverless_security/server/types.ts +++ b/x-pack/plugins/serverless_security/server/types.ts @@ -7,12 +7,13 @@ import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import type { PluginSetupContract, PluginStartContract } from '@kbn/features-plugin/server'; -import { +import type { PluginSetup as SecuritySolutionPluginSetup, PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/server'; import type { EssSecurityPluginSetup } from '@kbn/ess-security/server'; +import type { MlPluginSetup } from '@kbn/ml-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ServerlessSecurityPluginSetup {} @@ -24,6 +25,7 @@ export interface ServerlessSecurityPluginSetupDependencies { securitySolution: SecuritySolutionPluginSetup; features: PluginSetupContract; essSecurity: EssSecurityPluginSetup; + ml: MlPluginSetup; } export interface ServerlessSecurityPluginStartDependencies { diff --git a/x-pack/plugins/serverless_security/tsconfig.json b/x-pack/plugins/serverless_security/tsconfig.json index 9fa63eb6ed210b..69d976d3241057 100644 --- a/x-pack/plugins/serverless_security/tsconfig.json +++ b/x-pack/plugins/serverless_security/tsconfig.json @@ -29,6 +29,7 @@ "@kbn/shared-ux-page-kibana-template", "@kbn/features-plugin", "@kbn/ess-security", - "@kbn/kibana-utils-plugin", + "@kbn/ml-plugin", + "@kbn/kibana-utils-plugin" ] } diff --git a/x-pack/test/api_integration/apis/ml/system/capabilities.ts b/x-pack/test/api_integration/apis/ml/system/capabilities.ts index 814ebb7fbaa212..dcfeba197026cd 100644 --- a/x-pack/test/api_integration/apis/ml/system/capabilities.ts +++ b/x-pack/test/api_integration/apis/ml/system/capabilities.ts @@ -12,7 +12,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { getCommonRequestHeader } from '../../../../functional/services/ml/common_api'; import { USER } from '../../../../functional/services/ml/security_common'; -const NUMBER_OF_CAPABILITIES = 39; +const NUMBER_OF_CAPABILITIES = 42; export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); @@ -93,6 +93,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: false, canDeleteTrainedModels: false, canStartStopTrainedModels: false, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); @@ -139,6 +142,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: true, canDeleteTrainedModels: true, canStartStopTrainedModels: true, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); }); diff --git a/x-pack/test/api_integration/apis/ml/system/space_capabilities.ts b/x-pack/test/api_integration/apis/ml/system/space_capabilities.ts index c746c6d316efa2..f2c62a19886a06 100644 --- a/x-pack/test/api_integration/apis/ml/system/space_capabilities.ts +++ b/x-pack/test/api_integration/apis/ml/system/space_capabilities.ts @@ -15,7 +15,7 @@ import { USER } from '../../../../functional/services/ml/security_common'; const idSpaceWithMl = 'space_with_ml'; const idSpaceNoMl = 'space_no_ml'; -const NUMBER_OF_CAPABILITIES = 39; +const NUMBER_OF_CAPABILITIES = 42; export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); @@ -122,6 +122,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: false, canDeleteTrainedModels: false, canStartStopTrainedModels: false, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); @@ -167,6 +170,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: false, canDeleteTrainedModels: false, canStartStopTrainedModels: false, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); @@ -212,6 +218,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: true, canDeleteTrainedModels: true, canStartStopTrainedModels: true, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); @@ -257,6 +266,9 @@ export default ({ getService }: FtrProviderContext) => { canCreateTrainedModels: false, canDeleteTrainedModels: false, canStartStopTrainedModels: false, + isADEnabled: true, + isDFAEnabled: true, + isNLPEnabled: true, }); }); }); From b83f8819d91972c698f74652380b14fc00e123a1 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Sat, 1 Jul 2023 09:51:37 +0200 Subject: [PATCH 05/98] [Defend Workflows] Add API versioning to Osquery (#160243) --- x-pack/plugins/osquery/common/constants.ts | 9 + .../osquery/cypress/e2e/all/packs.cy.ts | 34 +- .../osquery/cypress/tasks/api_fixtures.ts | 40 +- .../plugins/osquery/cypress/tasks/common.ts | 2 +- x-pack/plugins/osquery/cypress/tasks/packs.ts | 4 + .../action_results/use_action_privileges.tsx | 3 +- .../public/actions/use_all_live_queries.ts | 2 + .../public/actions/use_live_query_details.ts | 3 +- .../agent_policies/use_agent_policies.ts | 36 +- .../public/agent_policies/use_agent_policy.ts | 6 +- .../public/agents/use_agent_details.ts | 6 +- .../public/agents/use_agent_policies.ts | 6 +- .../agents/use_agent_policy_agent_ids.ts | 2 + .../osquery/public/agents/use_agent_status.ts | 11 +- .../osquery/public/agents/use_all_agents.ts | 2 + .../public/agents/use_osquery_policies.ts | 4 +- .../public/assets/use_assets_status.ts | 13 +- .../public/assets/use_import_assets.ts | 26 +- .../common/hooks/use_osquery_integration.tsx | 4 +- .../fleet_integration/use_fetch_status.tsx | 5 +- .../use_create_live_query_action.tsx | 2 + .../osquery/public/packs/use_create_pack.ts | 2 + .../osquery/public/packs/use_delete_pack.ts | 45 +- .../plugins/osquery/public/packs/use_pack.ts | 3 +- .../plugins/osquery/public/packs/use_packs.ts | 2 + .../osquery/public/packs/use_update_pack.ts | 2 + .../saved_queries/use_create_saved_query.ts | 2 + .../saved_queries/use_delete_saved_query.ts | 41 +- .../public/saved_queries/use_saved_queries.ts | 2 + .../public/saved_queries/use_saved_query.ts | 4 +- .../saved_queries/use_update_saved_query.ts | 2 + .../use_is_osquery_available_simple.tsx | 7 +- .../routes/asset/get_assets_status_route.ts | 140 +++-- .../routes/asset/update_assets_route.ts | 336 +++++----- .../routes/fleet_wrapper/get_agent_details.ts | 46 +- .../fleet_wrapper/get_agent_policies.ts | 92 +-- .../routes/fleet_wrapper/get_agent_policy.ts | 44 +- .../get_agent_status_for_agent_policy.ts | 52 +- .../server/routes/fleet_wrapper/get_agents.ts | 46 +- .../fleet_wrapper/get_package_policies.ts | 50 +- .../live_query/create_live_query_route.ts | 172 ++--- .../live_query/find_live_query_route.ts | 110 ++-- .../get_live_query_details_route.ts | 184 +++--- .../get_live_query_results_route.ts | 152 ++--- .../server/routes/pack/create_pack_route.ts | 324 +++++----- .../server/routes/pack/delete_pack_route.ts | 109 ++-- .../server/routes/pack/find_pack_route.ts | 112 ++-- .../server/routes/pack/read_pack_route.ts | 94 +-- .../server/routes/pack/update_pack_route.ts | 589 +++++++++--------- .../privileges_check_route.ts | 50 +- .../saved_query/create_saved_query_route.ts | 174 +++--- .../saved_query/delete_saved_query_route.ts | 60 +- .../saved_query/find_saved_query_route.ts | 174 +++--- .../saved_query/read_saved_query_route.ts | 138 ++-- .../saved_query/update_saved_query_route.ts | 237 +++---- .../routes/status/create_status_route.ts | 344 +++++----- 56 files changed, 2253 insertions(+), 1908 deletions(-) diff --git a/x-pack/plugins/osquery/common/constants.ts b/x-pack/plugins/osquery/common/constants.ts index 1c0498dc4217a5..fe3454090277a3 100644 --- a/x-pack/plugins/osquery/common/constants.ts +++ b/x-pack/plugins/osquery/common/constants.ts @@ -20,3 +20,12 @@ export const ACTION_RESPONSES_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.action. export const DEFAULT_PLATFORM = 'linux,windows,darwin'; export const CASE_ATTACHMENT_TYPE_ID = 'osquery'; + +export const API_VERSIONS = { + public: { + v1: '2023-10-31', + }, + internal: { + v1: '1', + }, +}; diff --git a/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts index 933e80435960b4..6819186c5bbae5 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts @@ -7,6 +7,8 @@ import { recurse } from 'cypress-recurse'; import { find } from 'lodash'; +import type { PackagePolicy } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../../common/constants'; import { FLEET_AGENT_POLICIES, navigateTo } from '../../tasks/navigation'; import { checkActionItemsInResults, @@ -46,6 +48,7 @@ import { loadPack, cleanupAgentPolicy, } from '../../tasks/api_fixtures'; +import { request } from '../../tasks/common'; describe('ALL - Packs', () => { let savedQueryId: string; @@ -225,12 +228,17 @@ describe('ALL - Packs', () => { query: 'select * from uptime;', }, }; - cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => { + request<{ items: PackagePolicy[] }>({ + url: '/internal/osquery/fleet_wrapper/package_policies', + headers: { + 'Elastic-Api-Version': API_VERSIONS.internal.v1, + }, + }).then((response) => { const item = response.body.items.find( - (policy: { policy_id: string }) => policy.policy_id === 'fleet-server-policy' + (policy: PackagePolicy) => policy.policy_id === 'fleet-server-policy' ); - expect(item.inputs[0].config.osquery.value.packs[packName].queries).to.deep.equal( + expect(item?.inputs[0].config?.osquery.value.packs[packName].queries).to.deep.equal( queries ); }); @@ -829,10 +837,15 @@ describe('ALL - Packs', () => { addIntegration(agentPolicy); cy.contains('Add Elastic Agent later').click(); cy.contains('osquery_manager-'); - cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => { + request<{ items: PackagePolicy[] }>({ + url: '/internal/osquery/fleet_wrapper/package_policies', + headers: { + 'Elastic-Api-Version': API_VERSIONS.internal.v1, + }, + }).then((response) => { const item = find(response.body.items, ['policy_id', agentPolicyId]); - expect(item.inputs[0].config.osquery.value.packs[globalPack]).to.deep.equal({ + expect(item?.inputs[0].config?.osquery.value.packs[globalPack]).to.deep.equal({ shard: 100, queries: {}, }); @@ -879,12 +892,17 @@ describe('ALL - Packs', () => { cy.contains(`Successfully created "${shardPack}" pack`); closeToastIfVisible(); - cy.request('/internal/osquery/fleet_wrapper/package_policies').then((response) => { + request<{ items: PackagePolicy[] }>({ + url: '/internal/osquery/fleet_wrapper/package_policies', + headers: { + 'Elastic-Api-Version': API_VERSIONS.internal.v1, + }, + }).then((response) => { const shardPolicy = response.body.items.find( - (policy: { policy_id: string }) => policy.policy_id === 'fleet-server-policy' + (policy: PackagePolicy) => policy.policy_id === 'fleet-server-policy' ); - expect(shardPolicy.inputs[0].config.osquery.value.packs[shardPack]).to.deep.equal({ + expect(shardPolicy?.inputs[0].config?.osquery.value.packs[shardPack]).to.deep.equal({ shard: 15, queries: {}, }); diff --git a/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts b/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts index 2a19019ea3ffb7..a87869d693348d 100644 --- a/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts +++ b/x-pack/plugins/osquery/cypress/tasks/api_fixtures.ts @@ -11,6 +11,7 @@ import type { } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import type { AgentPolicy } from '@kbn/fleet-plugin/common'; import type { Case } from '@kbn/cases-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import type { SavedQuerySOFormData } from '../../public/saved_queries/form/use_saved_query_form'; import type { LiveQueryDetailsItem } from '../../public/actions/use_live_query_details'; import type { PackSavedObject, PackItem } from '../../public/packs/types'; @@ -72,11 +73,20 @@ export const loadSavedQuery = (payload: SavedQuerySOFormData = savedQueryFixture ...payload, id: payload.id ?? generateRandomStringName(1)[0], }, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, url: '/api/osquery/saved_queries', }).then((response) => response.body.data); export const cleanupSavedQuery = (id: string) => { - request({ method: 'DELETE', url: `/api/osquery/saved_queries/${id}` }); + request({ + method: 'DELETE', + url: `/api/osquery/saved_queries/${id}`, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, + }); }; export const loadPack = (payload: Partial = {}, space = 'default') => @@ -89,11 +99,20 @@ export const loadPack = (payload: Partial = {}, space = 'default') => queries: payload.queries ?? {}, enabled: payload.enabled || true, }, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, url: `/s/${space}/api/osquery/packs`, }).then((response) => response.body.data); export const cleanupPack = (id: string, space = 'default') => { - request({ method: 'DELETE', url: `/s/${space}/api/osquery/packs/${id}` }); + request({ + method: 'DELETE', + url: `/s/${space}/api/osquery/packs/${id}`, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, + }); }; export const loadLiveQuery = ( @@ -108,6 +127,9 @@ export const loadLiveQuery = ( method: 'POST', body: payload, url: `/api/osquery/live_queries`, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, }).then((response) => response.body.data); export const loadRule = (includeResponseActions = false) => @@ -177,7 +199,13 @@ export const loadRule = (includeResponseActions = false) => }).then((response) => response.body); export const cleanupRule = (id: string) => { - request({ method: 'DELETE', url: `/api/detection_engine/rules?id=${id}` }); + request({ + method: 'DELETE', + url: `/api/detection_engine/rules?id=${id}`, + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, + }); }; export const loadCase = (owner: string) => @@ -197,7 +225,11 @@ export const loadCase = (owner: string) => }).then((response) => response.body); export const cleanupCase = (id: string) => { - request({ method: 'DELETE', url: '/api/cases', qs: { ids: JSON.stringify([id]) } }); + request({ + method: 'DELETE', + url: '/api/cases', + qs: { ids: JSON.stringify([id]) }, + }); }; export const loadSpace = () => { diff --git a/x-pack/plugins/osquery/cypress/tasks/common.ts b/x-pack/plugins/osquery/cypress/tasks/common.ts index c56378642d235c..5704796c10b0be 100644 --- a/x-pack/plugins/osquery/cypress/tasks/common.ts +++ b/x-pack/plugins/osquery/cypress/tasks/common.ts @@ -17,6 +17,6 @@ export const request = ( ): Cypress.Chainable> => cy.request({ auth: API_AUTH, - headers: API_HEADERS, ...options, + headers: { ...API_HEADERS, ...options.headers }, }); diff --git a/x-pack/plugins/osquery/cypress/tasks/packs.ts b/x-pack/plugins/osquery/cypress/tasks/packs.ts index 43a007394a485b..f8bd23f2c7b100 100644 --- a/x-pack/plugins/osquery/cypress/tasks/packs.ts +++ b/x-pack/plugins/osquery/cypress/tasks/packs.ts @@ -6,6 +6,7 @@ */ import { some } from 'lodash'; +import { API_VERSIONS } from '../../common/constants'; import type { UsePacksResponse } from '../../public/packs/use_packs'; import { request } from './common'; import { closeModalIfVisible, closeToastIfVisible } from './integrations'; @@ -45,6 +46,9 @@ export const cleanupAllPrebuiltPacks = () => { request({ method: 'GET', url: '/api/osquery/packs', + headers: { + 'Elastic-Api-Version': API_VERSIONS.public.v1, + }, }).then((response) => { const prebuiltPacks = response.body.data?.filter((pack) => some(pack.references, { type: 'osquery-pack-asset' }) diff --git a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx index 83508def6a4838..f55b3d8ad0effb 100644 --- a/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx +++ b/x-pack/plugins/osquery/public/action_results/use_action_privileges.tsx @@ -6,6 +6,7 @@ */ import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; export const useActionResultsPrivileges = () => { @@ -13,7 +14,7 @@ export const useActionResultsPrivileges = () => { return useQuery( ['actionResultsPrivileges'], - () => http.get('/internal/osquery/privileges_check'), + () => http.get('/internal/osquery/privileges_check', { version: API_VERSIONS.internal.v1 }), { keepPreviousData: true, } diff --git a/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts b/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts index 2f540a3eaf09c3..ec124b552b2aab 100644 --- a/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts +++ b/x-pack/plugins/osquery/public/actions/use_all_live_queries.ts @@ -8,6 +8,7 @@ import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { createFilter } from '../common/helpers'; import { useKibana } from '../common/lib/kibana'; import type { ActionEdges, ActionsStrategyResponse } from '../../common/search_strategy'; @@ -50,6 +51,7 @@ export const useAllLiveQueries = ({ http.get<{ data: Omit & { items: ActionEdges } }>( '/api/osquery/live_queries', { + version: API_VERSIONS.public.v1, query: { filterQuery: createFilter(filterQuery), page: activePage, diff --git a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts index 2a3f070ae19920..bea2a0bc6b6fb6 100644 --- a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts +++ b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts @@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { filter } from 'lodash'; import type { ECSMapping } from '@kbn/osquery-io-ts-types'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import type { ESTermQuery } from '../../common/typed_json'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -63,7 +64,7 @@ export const useLiveQueryDetails = ({ return useQuery<{ data: LiveQueryDetailsItem }, Error, LiveQueryDetailsItem>( ['liveQueries', { actionId, filterQuery, queryIds }], - () => http.get(`/api/osquery/live_queries/${actionId}`), + () => http.get(`/api/osquery/live_queries/${actionId}`, { version: API_VERSIONS.public.v1 }), { enabled: !skip && !!actionId, refetchInterval: isLive ? 5000 : false, diff --git a/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts b/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts index 37f1789a964de2..acc36d4961c30b 100644 --- a/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts +++ b/x-pack/plugins/osquery/public/agent_policies/use_agent_policies.ts @@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import type { GetAgentPoliciesResponseItem } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -24,19 +25,26 @@ export const useAgentPolicies = () => { agentPoliciesById: Record; agentPolicies: GetAgentPoliciesResponseItem[]; } - >(['agentPolicies'], () => http.get('/internal/osquery/fleet_wrapper/agent_policies'), { - initialData: [], - keepPreviousData: true, - select: (response) => ({ - agentPoliciesById: mapKeys(response, 'id'), - agentPolicies: response, - }), - onSuccess: () => setErrorToast(), - onError: (error) => - setErrorToast(error as Error, { - title: i18n.translate('xpack.osquery.agent_policies.fetchError', { - defaultMessage: 'Error while fetching agent policies', - }), + >( + ['agentPolicies'], + () => + http.get('/internal/osquery/fleet_wrapper/agent_policies', { + version: API_VERSIONS.internal.v1, + }), + { + initialData: [], + keepPreviousData: true, + select: (response) => ({ + agentPoliciesById: mapKeys(response, 'id'), + agentPolicies: response, }), - }); + onSuccess: () => setErrorToast(), + onError: (error) => + setErrorToast(error as Error, { + title: i18n.translate('xpack.osquery.agent_policies.fetchError', { + defaultMessage: 'Error while fetching agent policies', + }), + }), + } + ); }; diff --git a/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts b/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts index 7a819e1118ad28..6fe6db18e2f2de 100644 --- a/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts +++ b/x-pack/plugins/osquery/public/agent_policies/use_agent_policy.ts @@ -9,6 +9,7 @@ import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import type { AgentPolicy } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -24,7 +25,10 @@ export const useAgentPolicy = ({ policyId, skip, silent }: UseAgentPolicy) => { return useQuery<{ item: AgentPolicy }, Error, AgentPolicy>( ['agentPolicy', { policyId }], - () => http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`), + () => + http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`, { + version: API_VERSIONS.internal.v1, + }), { enabled: !!(policyId && !skip), keepPreviousData: true, diff --git a/x-pack/plugins/osquery/public/agents/use_agent_details.ts b/x-pack/plugins/osquery/public/agents/use_agent_details.ts index d75987f38e93b3..57110d6fa1f7d4 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_details.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_details.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { useQuery } from '@tanstack/react-query'; import type { GetOneAgentResponse } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { useKibana } from '../common/lib/kibana'; @@ -24,7 +25,10 @@ export const useAgentDetails = ({ agentId, silent, skip }: UseAgentDetails) => { return useQuery( ['agentDetails', agentId], - () => http.get(`/internal/osquery/fleet_wrapper/agents/${agentId}`), + () => + http.get(`/internal/osquery/fleet_wrapper/agents/${agentId}`, { + version: API_VERSIONS.internal.v1, + }), { enabled: !skip, retry: false, diff --git a/x-pack/plugins/osquery/public/agents/use_agent_policies.ts b/x-pack/plugins/osquery/public/agents/use_agent_policies.ts index 737a64226c2bc8..235789ef548a3e 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_policies.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_policies.ts @@ -10,6 +10,7 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQueries } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import type { GetOneAgentPolicyResponse } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -20,7 +21,10 @@ export const useAgentPolicies = (policyIds: string[] = []) => { const agentResponse = useQueries({ queries: policyIds.map((policyId) => ({ queryKey: ['agentPolicy', policyId], - queryFn: () => http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`), + queryFn: () => + http.get(`/internal/osquery/fleet_wrapper/agent_policies/${policyId}`, { + version: API_VERSIONS.internal.v1, + }), enabled: policyIds.length > 0, onSuccess: () => setErrorToast(), diff --git a/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts b/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts index cd30baf32d52d9..3f03122bcbb8bd 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_policy_agent_ids.ts @@ -11,6 +11,7 @@ import { useQuery } from '@tanstack/react-query'; import type { Agent } from '@kbn/fleet-plugin/common'; import { AGENTS_PREFIX } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { useKibana } from '../common/lib/kibana'; @@ -34,6 +35,7 @@ export const useAgentPolicyAgentIds = ({ const kuery = `${AGENTS_PREFIX}.policy_id:${agentPolicyId}`; return http.get(`/internal/osquery/fleet_wrapper/agents`, { + version: API_VERSIONS.internal.v1, query: { kuery, perPage: 10000, diff --git a/x-pack/plugins/osquery/public/agents/use_agent_status.ts b/x-pack/plugins/osquery/public/agents/use_agent_status.ts index bc0d4e6323f620..a83f4116933a3b 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_status.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_status.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { useQuery } from '@tanstack/react-query'; import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { useKibana } from '../common/lib/kibana'; @@ -24,16 +25,16 @@ export const useAgentStatus = ({ policyId, skip }: UseAgentStatus) => { return useQuery( ['agentStatus', policyId], () => - http.get( - `/internal/osquery/fleet_wrapper/agent_status`, - policyId + http.get(`/internal/osquery/fleet_wrapper/agent_status`, { + version: API_VERSIONS.internal.v1, + ...(policyId ? { query: { policyId, }, } - : {} - ), + : {}), + }), { enabled: !skip, select: (response) => response.results, diff --git a/x-pack/plugins/osquery/public/agents/use_all_agents.ts b/x-pack/plugins/osquery/public/agents/use_all_agents.ts index 4f2aa8826f85fb..98985b1c385050 100644 --- a/x-pack/plugins/osquery/public/agents/use_all_agents.ts +++ b/x-pack/plugins/osquery/public/agents/use_all_agents.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { useQuery } from '@tanstack/react-query'; import type { ListResult, Agent } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../common/constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { useKibana } from '../common/lib/kibana'; import { useOsqueryPolicies } from './use_osquery_policies'; @@ -40,6 +41,7 @@ export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: } return http.get(`/internal/osquery/fleet_wrapper/agents`, { + version: API_VERSIONS.internal.v1, query: { kuery, perPage, diff --git a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts index 589deab5334b11..52fa6e4da10ea7 100644 --- a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts +++ b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts @@ -8,6 +8,7 @@ import { uniq } from 'lodash'; import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -19,7 +20,8 @@ export const useOsqueryPolicies = () => { ['osqueryPolicies'], () => http.get<{ items: Array<{ policy_id: string }> }>( - '/internal/osquery/fleet_wrapper/package_policies' + '/internal/osquery/fleet_wrapper/package_policies', + { version: API_VERSIONS.internal.v1 } ), { select: (response) => uniq(response.items.map((p) => p.policy_id)), diff --git a/x-pack/plugins/osquery/public/assets/use_assets_status.ts b/x-pack/plugins/osquery/public/assets/use_assets_status.ts index ba0e60e937a2b9..3a111eaafe3bf2 100644 --- a/x-pack/plugins/osquery/public/assets/use_assets_status.ts +++ b/x-pack/plugins/osquery/public/assets/use_assets_status.ts @@ -7,6 +7,7 @@ import type { KibanaAssetReference } from '@kbn/fleet-plugin/common'; import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { INTEGRATION_ASSETS_STATUS_ID } from './constants'; @@ -17,8 +18,12 @@ export const useAssetsStatus = () => { install: KibanaAssetReference[]; update: KibanaAssetReference[]; upToDate: KibanaAssetReference[]; - }>([INTEGRATION_ASSETS_STATUS_ID], () => http.get('/internal/osquery/assets'), { - keepPreviousData: true, - retry: false, - }); + }>( + [INTEGRATION_ASSETS_STATUS_ID], + () => http.get('/internal/osquery/assets', { version: API_VERSIONS.internal.v1 }), + { + keepPreviousData: true, + retry: false, + } + ); }; diff --git a/x-pack/plugins/osquery/public/assets/use_import_assets.ts b/x-pack/plugins/osquery/public/assets/use_import_assets.ts index 4ae6d8549d6fa6..6740df46ee9366 100644 --- a/x-pack/plugins/osquery/public/assets/use_import_assets.ts +++ b/x-pack/plugins/osquery/public/assets/use_import_assets.ts @@ -6,6 +6,7 @@ */ import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { PACKS_ID } from '../packs/constants'; @@ -23,15 +24,18 @@ export const useImportAssets = ({ successToastText }: UseImportAssetsProps) => { } = useKibana().services; const setErrorToast = useErrorToast(); - return useMutation(() => http.post('/internal/osquery/assets/update'), { - onSuccess: () => { - setErrorToast(); - queryClient.invalidateQueries([PACKS_ID]); - queryClient.invalidateQueries([INTEGRATION_ASSETS_STATUS_ID]); - toasts.addSuccess(successToastText); - }, - onError: (error) => { - setErrorToast(error); - }, - }); + return useMutation( + () => http.post('/internal/osquery/assets/update', { version: API_VERSIONS.internal.v1 }), + { + onSuccess: () => { + setErrorToast(); + queryClient.invalidateQueries([PACKS_ID]); + queryClient.invalidateQueries([INTEGRATION_ASSETS_STATUS_ID]); + toasts.addSuccess(successToastText); + }, + onError: (error) => { + setErrorToast(error); + }, + } + ); }; diff --git a/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx b/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx index 4602b8df24d788..4f34515c3b1fd4 100644 --- a/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx +++ b/x-pack/plugins/osquery/public/common/hooks/use_osquery_integration.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../../common/constants'; import { useKibana } from '../lib/kibana'; import { useErrorToast } from './use_error_toast'; @@ -19,7 +20,8 @@ export const useOsqueryIntegrationStatus = () => { ['integration'], () => http.get<{ name: string; version: string; title: string; install_status: string }>( - '/internal/osquery/status' + '/internal/osquery/status', + { version: API_VERSIONS.internal.v1 } ), { onError: (error: Error) => diff --git a/x-pack/plugins/osquery/public/fleet_integration/use_fetch_status.tsx b/x-pack/plugins/osquery/public/fleet_integration/use_fetch_status.tsx index 051897eca12592..120d539620af18 100644 --- a/x-pack/plugins/osquery/public/fleet_integration/use_fetch_status.tsx +++ b/x-pack/plugins/osquery/public/fleet_integration/use_fetch_status.tsx @@ -6,6 +6,7 @@ */ import { useState, useEffect } from 'react'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; export const useFetchStatus = () => { @@ -17,7 +18,9 @@ export const useFetchStatus = () => { useEffect(() => { const fetchStatus = () => { http - .get<{ install_status: string }>('/internal/osquery/status') + .get<{ install_status: string }>('/internal/osquery/status', { + version: API_VERSIONS.internal.v1, + }) .then((response) => { setLoading(false); setDisabled(response?.install_status !== 'installed'); diff --git a/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx b/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx index 51c7f4ad272c02..0fa7c538e6737b 100644 --- a/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx +++ b/x-pack/plugins/osquery/public/live_queries/use_create_live_query_action.tsx @@ -7,6 +7,7 @@ import { useMutation } from '@tanstack/react-query'; import type { AgentSelection } from '@kbn/osquery-io-ts-types'; +import { API_VERSIONS } from '../../common/constants'; import type { CreateLiveQueryRequestBodySchema } from '../../common/schemas/routes/live_query'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -36,6 +37,7 @@ export const useCreateLiveQuery = ({ onSuccess }: UseLiveQueryProps) => { const response = await http.post<{ data: LiveQueryDetailsItem }>( '/api/osquery/live_queries', { + version: API_VERSIONS.public.v1, body: JSON.stringify({ ...payload, agent_all: agentSelection.allAgentsSelected, diff --git a/x-pack/plugins/osquery/public/packs/use_create_pack.ts b/x-pack/plugins/osquery/public/packs/use_create_pack.ts index 9c81f71e441f2f..b96732af1cd77b 100644 --- a/x-pack/plugins/osquery/public/packs/use_create_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_create_pack.ts @@ -8,6 +8,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -35,6 +36,7 @@ export const useCreatePack = ({ withRedirect }: UseCreatePackProps) => { >( (payload) => http.post('/api/osquery/packs', { + version: API_VERSIONS.public.v1, body: JSON.stringify(payload), }), { diff --git a/x-pack/plugins/osquery/public/packs/use_delete_pack.ts b/x-pack/plugins/osquery/public/packs/use_delete_pack.ts index 8b5e7f0fb1450b..31c9af2e3a21ab 100644 --- a/x-pack/plugins/osquery/public/packs/use_delete_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_delete_pack.ts @@ -8,6 +8,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -28,24 +29,30 @@ export const useDeletePack = ({ packId, withRedirect }: UseDeletePackProps) => { } = useKibana().services; const setErrorToast = useErrorToast(); - return useMutation(() => http.delete(`/api/osquery/packs/${packId}`), { - onError: (error: { body: { error: string; message: string } }) => { - setErrorToast(error, { - title: error.body.error, - toastMessage: error.body.message, - }); - }, - onSuccess: () => { - queryClient.invalidateQueries([PACKS_ID]); - if (withRedirect) { - navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() }); - } + return useMutation( + () => + http.delete(`/api/osquery/packs/${packId}`, { + version: API_VERSIONS.public.v1, + }), + { + onError: (error: { body: { error: string; message: string } }) => { + setErrorToast(error, { + title: error.body.error, + toastMessage: error.body.message, + }); + }, + onSuccess: () => { + queryClient.invalidateQueries([PACKS_ID]); + if (withRedirect) { + navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() }); + } - toasts.addSuccess( - i18n.translate('xpack.osquery.deletePack.successToastMessageText', { - defaultMessage: 'Successfully deleted pack', - }) - ); - }, - }); + toasts.addSuccess( + i18n.translate('xpack.osquery.deletePack.successToastMessageText', { + defaultMessage: 'Successfully deleted pack', + }) + ); + }, + } + ); }; diff --git a/x-pack/plugins/osquery/public/packs/use_pack.ts b/x-pack/plugins/osquery/public/packs/use_pack.ts index 9fac2175cc1b2c..db8447c6b00a99 100644 --- a/x-pack/plugins/osquery/public/packs/use_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_pack.ts @@ -6,6 +6,7 @@ */ import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import type { PackItem } from './types'; @@ -19,7 +20,7 @@ export const usePack = ({ packId, skip = false }: UsePack) => { return useQuery<{ data: PackItem }, unknown, PackItem>( ['pack', { packId }], - () => http.get(`/api/osquery/packs/${packId}`), + () => http.get(`/api/osquery/packs/${packId}`, { version: API_VERSIONS.public.v1 }), { select: (response) => response?.data, keepPreviousData: true, diff --git a/x-pack/plugins/osquery/public/packs/use_packs.ts b/x-pack/plugins/osquery/public/packs/use_packs.ts index afe612094f6603..aac8cc204cb9e7 100644 --- a/x-pack/plugins/osquery/public/packs/use_packs.ts +++ b/x-pack/plugins/osquery/public/packs/use_packs.ts @@ -7,6 +7,7 @@ import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PACKS_ID } from './constants'; import type { PackSavedObject } from './types'; @@ -29,6 +30,7 @@ export const usePacks = ({ [PACKS_ID, { pageIndex, pageSize, sortField, sortOrder }], () => http.get('/api/osquery/packs', { + version: API_VERSIONS.public.v1, query: { pageIndex, pageSize, sortField, sortOrder }, }), { diff --git a/x-pack/plugins/osquery/public/packs/use_update_pack.ts b/x-pack/plugins/osquery/public/packs/use_update_pack.ts index c5d7fc8b432105..6597cbe215f511 100644 --- a/x-pack/plugins/osquery/public/packs/use_update_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_update_pack.ts @@ -9,6 +9,7 @@ import type { UseMutationOptions } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -41,6 +42,7 @@ export const useUpdatePack = ({ withRedirect, options }: UseUpdatePackProps) => >( ({ id, ...payload }) => http.put(`/api/osquery/packs/${id}`, { + version: API_VERSIONS.public.v1, body: JSON.stringify(payload), }), { diff --git a/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts index ce79fb25ace3e0..94fcccc1337937 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts @@ -8,6 +8,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -36,6 +37,7 @@ export const useCreateSavedQuery = ({ withRedirect }: UseCreateSavedQueryProps) >( (payload) => http.post('/api/osquery/saved_queries', { + version: API_VERSIONS.public.v1, body: JSON.stringify(payload), }), { diff --git a/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts index f03ac709db1eeb..58ef47ff683aa3 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_delete_saved_query.ts @@ -8,6 +8,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -27,21 +28,27 @@ export const useDeleteSavedQuery = ({ savedQueryId }: UseDeleteSavedQueryProps) } = useKibana().services; const setErrorToast = useErrorToast(); - return useMutation(() => http.delete(`/api/osquery/saved_queries/${savedQueryId}`), { - onError: (error: { body: { error: string; message: string } }) => { - setErrorToast(error, { - title: error.body.error, - toastMessage: error.body.message, - }); - }, - onSuccess: () => { - queryClient.invalidateQueries([SAVED_QUERIES_ID]); - navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); - toasts.addSuccess( - i18n.translate('xpack.osquery.editSavedQuery.deleteSuccessToastMessageText', { - defaultMessage: 'Successfully deleted saved query', - }) - ); - }, - }); + return useMutation( + () => + http.delete(`/api/osquery/saved_queries/${savedQueryId}`, { + version: API_VERSIONS.public.v1, + }), + { + onError: (error: { body: { error: string; message: string } }) => { + setErrorToast(error, { + title: error.body.error, + toastMessage: error.body.message, + }); + }, + onSuccess: () => { + queryClient.invalidateQueries([SAVED_QUERIES_ID]); + navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() }); + toasts.addSuccess( + i18n.translate('xpack.osquery.editSavedQuery.deleteSuccessToastMessageText', { + defaultMessage: 'Successfully deleted saved query', + }) + ); + }, + } + ); }; diff --git a/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts b/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts index f56bd9c0ec010a..955987a353ca8c 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_saved_queries.ts @@ -7,6 +7,7 @@ import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { SAVED_QUERIES_ID } from './constants'; @@ -34,6 +35,7 @@ export const useSavedQueries = ({ [SAVED_QUERIES_ID, { pageIndex, pageSize, sortField, sortOrder }], () => http.get('/api/osquery/saved_queries', { + version: API_VERSIONS.public.v1, query: { page: pageIndex + 1, pageSize, sort: sortField, sortOrder }, }), { diff --git a/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts index 96192c2b7abdc7..d7ae3575038632 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_saved_query.ts @@ -7,6 +7,7 @@ import { useQuery } from '@tanstack/react-query'; +import { API_VERSIONS } from '../../common/constants'; import { PLUGIN_ID } from '../../common'; import { useKibana } from '../common/lib/kibana'; import { pagePathGetters } from '../common/page_paths'; @@ -36,7 +37,8 @@ export const useSavedQuery = ({ savedQueryId }: UseSavedQueryProps) => { SavedQuerySO & { error?: { error: string; message: string } } >( [SAVED_QUERY_ID, { savedQueryId }], - () => http.get(`/api/osquery/saved_queries/${savedQueryId}`), + () => + http.get(`/api/osquery/saved_queries/${savedQueryId}`, { version: API_VERSIONS.public.v1 }), { keepPreviousData: true, refetchOnWindowFocus: false, diff --git a/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts index 58fcc06740c459..f6707257f4721f 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_update_saved_query.ts @@ -8,6 +8,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; +import { API_VERSIONS } from '../../common/constants'; import { useKibana } from '../common/lib/kibana'; import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; @@ -31,6 +32,7 @@ export const useUpdateSavedQuery = ({ savedQueryId }: UseUpdateSavedQueryProps) return useMutation( (payload) => http.put(`/api/osquery/saved_queries/${savedQueryId}`, { + version: API_VERSIONS.public.v1, body: JSON.stringify(payload), }), { diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx index 574ca04480c696..4e13d02ef4e75d 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx @@ -9,6 +9,7 @@ import { useEffect, useState } from 'react'; import { find } from 'lodash'; import type { AgentPolicy, FleetServerAgent, NewPackagePolicy } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../../common/constants'; import { useKibana } from '../../common/lib/kibana'; import { OSQUERY_INTEGRATION_NAME } from '../../../common'; @@ -23,10 +24,12 @@ export const useIsOsqueryAvailableSimple = ({ agentId }: IProps) => { (async () => { try { const { item: agentInfo }: { item: FleetServerAgent } = await http.get( - `/internal/osquery/fleet_wrapper/agents/${agentId}` + `/internal/osquery/fleet_wrapper/agents/${agentId}`, + { version: API_VERSIONS.internal.v1 } ); const { item: packageInfo }: { item: AgentPolicy } = await http.get( - `/internal/osquery/fleet_wrapper/agent_policies/${agentInfo.policy_id}` + `/internal/osquery/fleet_wrapper/agent_policies/${agentInfo.policy_id}`, + { version: API_VERSIONS.internal.v1 } ); const osqueryPackageInstalled = find(packageInfo?.package_policies, [ 'package.name', diff --git a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts index c40e1488ca11ea..a76ec52350adeb 100644 --- a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts @@ -11,89 +11,97 @@ import { asyncForEach } from '@kbn/std'; import type { IRouter } from '@kbn/core/server'; import type { KibanaAssetReference } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../../common/constants'; import { packAssetSavedObjectType, packSavedObjectType } from '../../../common/types'; import { PLUGIN_ID, OSQUERY_INTEGRATION_NAME } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; export const getAssetsStatusRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/assets', - validate: { - params: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, - }, - async (context, request, response) => { - const savedObjectsClient = (await context.core).savedObjects.client; + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + params: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + const savedObjectsClient = (await context.core).savedObjects.client; - let installation; + let installation; - try { - installation = await osqueryContext.service - .getPackageService() - ?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME); - } catch (err) { - return response.notFound(); - } + try { + installation = await osqueryContext.service + .getPackageService() + ?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME); + } catch (err) { + return response.notFound(); + } - if (installation) { - const installationPackAssets = filter( - ['type', packAssetSavedObjectType], - installation.installed_kibana - ); + if (installation) { + const installationPackAssets = filter( + ['type', packAssetSavedObjectType], + installation.installed_kibana + ); - const install: KibanaAssetReference[] = []; - const update: KibanaAssetReference[] = []; - const upToDate: KibanaAssetReference[] = []; + const install: KibanaAssetReference[] = []; + const update: KibanaAssetReference[] = []; + const upToDate: KibanaAssetReference[] = []; - await asyncForEach(installationPackAssets, async (installationPackAsset) => { - const isInstalled = await savedObjectsClient.find<{ version: number }>({ - type: packSavedObjectType, - hasReference: { - type: installationPackAsset.type, - id: installationPackAsset.id, - }, - }); + await asyncForEach(installationPackAssets, async (installationPackAsset) => { + const isInstalled = await savedObjectsClient.find<{ version: number }>({ + type: packSavedObjectType, + hasReference: { + type: installationPackAsset.type, + id: installationPackAsset.id, + }, + }); - if (!isInstalled.total) { - install.push(installationPackAsset); - } + if (!isInstalled.total) { + install.push(installationPackAsset); + } - if (isInstalled.total) { - const packAssetSavedObject = await savedObjectsClient.get<{ version: number }>( - installationPackAsset.type, - installationPackAsset.id - ); + if (isInstalled.total) { + const packAssetSavedObject = await savedObjectsClient.get<{ version: number }>( + installationPackAsset.type, + installationPackAsset.id + ); - if (packAssetSavedObject) { - if ( - !packAssetSavedObject.attributes.version || - !isInstalled.saved_objects[0].attributes.version - ) { - install.push(installationPackAsset); - } else if ( - packAssetSavedObject.attributes.version > - isInstalled.saved_objects[0].attributes.version - ) { - update.push(installationPackAsset); - } else { - upToDate.push(installationPackAsset); + if (packAssetSavedObject) { + if ( + !packAssetSavedObject.attributes.version || + !isInstalled.saved_objects[0].attributes.version + ) { + install.push(installationPackAsset); + } else if ( + packAssetSavedObject.attributes.version > + isInstalled.saved_objects[0].attributes.version + ) { + update.push(installationPackAsset); + } else { + upToDate.push(installationPackAsset); + } } } - } - }); + }); - return response.ok({ - body: { - install, - update, - upToDate, - }, - }); - } + return response.ok({ + body: { + install, + update, + upToDate, + }, + }); + } - return response.ok(); - } - ); + return response.ok(); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts index dbc1844cd7d636..5cfef0d84c2893 100644 --- a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts @@ -13,6 +13,7 @@ import deepmerge from 'deepmerge'; import type { IRouter } from '@kbn/core/server'; import type { KibanaAssetReference } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../../common/constants'; import { packAssetSavedObjectType, packSavedObjectType } from '../../../common/types'; import { combineMerge } from './utils'; import { PLUGIN_ID, OSQUERY_INTEGRATION_NAME } from '../../../common'; @@ -21,184 +22,191 @@ import { convertSOQueriesToPack, convertPackQueriesToSO } from '../pack/utils'; import type { PackSavedObject } from '../../common/types'; export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.post( - { + router.versioned + .post({ + access: 'internal', path: '/internal/osquery/assets/update', - validate: { - params: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, - }, - async (context, request, response) => { - const savedObjectsClient = (await context.core).savedObjects.client; - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - - let installation; - - try { - installation = await osqueryContext.service - .getPackageService() - ?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME); - } catch (err) { - return response.notFound(); - } + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + params: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + const savedObjectsClient = (await context.core).savedObjects.client; + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; + + let installation; + + try { + installation = await osqueryContext.service + .getPackageService() + ?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME); + } catch (err) { + return response.notFound(); + } + + if (installation) { + const installationPackAssets = filter(installation.installed_kibana, [ + 'type', + packAssetSavedObjectType, + ]); + + const install: KibanaAssetReference[] = []; + const update: KibanaAssetReference[] = []; + const upToDate: KibanaAssetReference[] = []; + + await asyncForEach(installationPackAssets, async (installationPackAsset) => { + const isInstalled = await savedObjectsClient.find<{ version: number }>({ + type: packSavedObjectType, + hasReference: { + type: installationPackAsset.type, + id: installationPackAsset.id, + }, + }); - if (installation) { - const installationPackAssets = filter(installation.installed_kibana, [ - 'type', - packAssetSavedObjectType, - ]); - - const install: KibanaAssetReference[] = []; - const update: KibanaAssetReference[] = []; - const upToDate: KibanaAssetReference[] = []; - - await asyncForEach(installationPackAssets, async (installationPackAsset) => { - const isInstalled = await savedObjectsClient.find<{ version: number }>({ - type: packSavedObjectType, - hasReference: { - type: installationPackAsset.type, - id: installationPackAsset.id, - }, - }); + if (!isInstalled.total) { + install.push(installationPackAsset); + } - if (!isInstalled.total) { - install.push(installationPackAsset); - } - - if (isInstalled.total) { - const packAssetSavedObject = await savedObjectsClient.get<{ version: number }>( - installationPackAsset.type, - installationPackAsset.id - ); - - if (packAssetSavedObject) { - if ( - !packAssetSavedObject.attributes.version || - !isInstalled.saved_objects[0].attributes.version - ) { - install.push(installationPackAsset); - } else if ( - packAssetSavedObject.attributes.version > - isInstalled.saved_objects[0].attributes.version - ) { - update.push(installationPackAsset); - } else { - upToDate.push(installationPackAsset); + if (isInstalled.total) { + const packAssetSavedObject = await savedObjectsClient.get<{ version: number }>( + installationPackAsset.type, + installationPackAsset.id + ); + + if (packAssetSavedObject) { + if ( + !packAssetSavedObject.attributes.version || + !isInstalled.saved_objects[0].attributes.version + ) { + install.push(installationPackAsset); + } else if ( + packAssetSavedObject.attributes.version > + isInstalled.saved_objects[0].attributes.version + ) { + update.push(installationPackAsset); + } else { + upToDate.push(installationPackAsset); + } } } - } - }); + }); - await Promise.all([ - ...install.map(async (installationPackAsset) => { - const packAssetSavedObject = await savedObjectsClient.get( - installationPackAsset.type, - installationPackAsset.id - ); + await Promise.all([ + ...install.map(async (installationPackAsset) => { + const packAssetSavedObject = await savedObjectsClient.get( + installationPackAsset.type, + installationPackAsset.id + ); - const conflictingEntries = await savedObjectsClient.find({ - type: packSavedObjectType, - filter: `${packSavedObjectType}.attributes.name: "${packAssetSavedObject.attributes.name}"`, - }); + const conflictingEntries = await savedObjectsClient.find({ + type: packSavedObjectType, + filter: `${packSavedObjectType}.attributes.name: "${packAssetSavedObject.attributes.name}"`, + }); + + const name = + conflictingEntries.saved_objects.length && + some(conflictingEntries.saved_objects, [ + 'attributes.name', + packAssetSavedObject.attributes.name, + ]) + ? `${packAssetSavedObject.attributes.name}-elastic` + : packAssetSavedObject.attributes.name; + + await savedObjectsClient.create( + packSavedObjectType, + { + name, + description: packAssetSavedObject.attributes.description, + queries: packAssetSavedObject.attributes.queries, + enabled: false, + created_at: moment().toISOString(), + created_by: currentUser, + updated_at: moment().toISOString(), + updated_by: currentUser, + version: packAssetSavedObject.attributes.version ?? 1, + }, + { + references: [ + ...packAssetSavedObject.references, + { + type: packAssetSavedObject.type, + id: packAssetSavedObject.id, + name: packAssetSavedObject.attributes.name, + }, + ], + refresh: 'wait_for', + } + ); + }), + ...update.map(async (updatePackAsset) => { + const packAssetSavedObject = await savedObjectsClient.get( + updatePackAsset.type, + updatePackAsset.id + ); - const name = - conflictingEntries.saved_objects.length && - some(conflictingEntries.saved_objects, [ - 'attributes.name', - packAssetSavedObject.attributes.name, - ]) - ? `${packAssetSavedObject.attributes.name}-elastic` - : packAssetSavedObject.attributes.name; - - await savedObjectsClient.create( - packSavedObjectType, - { - name, - description: packAssetSavedObject.attributes.description, - queries: packAssetSavedObject.attributes.queries, - enabled: false, - created_at: moment().toISOString(), - created_by: currentUser, - updated_at: moment().toISOString(), - updated_by: currentUser, - version: packAssetSavedObject.attributes.version ?? 1, - }, - { - references: [ - ...packAssetSavedObject.references, - { - type: packAssetSavedObject.type, - id: packAssetSavedObject.id, - name: packAssetSavedObject.attributes.name, - }, - ], - refresh: 'wait_for', + const packSavedObjectsResponse = await savedObjectsClient.find({ + type: 'osquery-pack', + hasReference: { + type: updatePackAsset.type, + id: updatePackAsset.id, + }, + }); + + if (packSavedObjectsResponse.total) { + await savedObjectsClient.update( + packSavedObjectsResponse.saved_objects[0].type, + packSavedObjectsResponse.saved_objects[0].id, + deepmerge.all([ + omit(packSavedObjectsResponse.saved_objects[0].attributes, 'queries'), + omit(packAssetSavedObject.attributes, 'queries'), + { + updated_at: moment().toISOString(), + updated_by: currentUser, + queries: convertPackQueriesToSO( + deepmerge( + convertSOQueriesToPack( + packSavedObjectsResponse.saved_objects[0].attributes.queries + ), + convertSOQueriesToPack(packAssetSavedObject.attributes.queries), + { + arrayMerge: combineMerge, + } + ) + ), + }, + { + arrayMerge: combineMerge, + }, + ]), + { refresh: 'wait_for' } + ); } - ); - }), - ...update.map(async (updatePackAsset) => { - const packAssetSavedObject = await savedObjectsClient.get( - updatePackAsset.type, - updatePackAsset.id - ); - - const packSavedObjectsResponse = await savedObjectsClient.find({ - type: 'osquery-pack', - hasReference: { - type: updatePackAsset.type, - id: updatePackAsset.id, - }, - }); - - if (packSavedObjectsResponse.total) { - await savedObjectsClient.update( - packSavedObjectsResponse.saved_objects[0].type, - packSavedObjectsResponse.saved_objects[0].id, - deepmerge.all([ - omit(packSavedObjectsResponse.saved_objects[0].attributes, 'queries'), - omit(packAssetSavedObject.attributes, 'queries'), - { - updated_at: moment().toISOString(), - updated_by: currentUser, - queries: convertPackQueriesToSO( - deepmerge( - convertSOQueriesToPack( - packSavedObjectsResponse.saved_objects[0].attributes.queries - ), - convertSOQueriesToPack(packAssetSavedObject.attributes.queries), - { - arrayMerge: combineMerge, - } - ) - ), - }, - { - arrayMerge: combineMerge, - }, - ]), - { refresh: 'wait_for' } - ); - } - }), - ]); + }), + ]); + + return response.ok({ + body: { + install, + update, + upToDate, + }, + }); + } return response.ok({ body: { - install, - update, - upToDate, + install: 0, + update: 0, + upToDate: 0, }, }); } - - return response.ok({ - body: { - install: 0, - update: 0, - upToDate: 0, - }, - }); - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts index 016675b9585d2c..65622569a446e9 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts @@ -7,31 +7,39 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; export const getAgentDetailsRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/agents/{id}', - validate: { - params: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - let agent; + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + params: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + let agent; - try { - agent = await osqueryContext.service - .getAgentService() - ?.asInternalUser // @ts-expect-error update types - ?.getAgent(request.params.id); - } catch (err) { - return response.notFound(); - } + try { + agent = await osqueryContext.service + .getAgentService() + ?.asInternalUser // @ts-expect-error update types + ?.getAgent(request.params.id); + } catch (err) { + return response.notFound(); + } - return response.ok({ body: { item: agent } }); - } - ); + return response.ok({ body: { item: agent } }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts index cf4ce574030a6d..0fc992c69760ba 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts @@ -12,57 +12,65 @@ import { satisfies } from 'semver'; import type { GetAgentPoliciesResponseItem, PackagePolicy } from '@kbn/fleet-plugin/common'; import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { OSQUERY_INTEGRATION_NAME, PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { getInternalSavedObjectsClient } from '../utils'; export const getAgentPoliciesRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/agent_policies', - validate: { - params: schema.object({}, { unknowns: 'allow' }), - query: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const agentService = osqueryContext.service.getAgentService(); - const agentPolicyService = osqueryContext.service.getAgentPolicyService(); - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + params: schema.object({}, { unknowns: 'allow' }), + query: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const agentService = osqueryContext.service.getAgentService(); + const agentPolicyService = osqueryContext.service.getAgentPolicyService(); + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + + const { items: packagePolicies } = (await packagePolicyService?.list( + internalSavedObjectsClient, + { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, + perPage: 1000, + page: 1, + } + )) ?? { items: [] as PackagePolicy[] }; + const supportedPackagePolicyIds = filter(packagePolicies, (packagePolicy) => + satisfies(packagePolicy.package?.version ?? '', '>=0.6.0') + ); + const agentPolicyIds = uniq(map(supportedPackagePolicyIds, 'policy_id')); + const agentPolicies = await agentPolicyService?.getByIds( + internalSavedObjectsClient, + agentPolicyIds + ); - const { items: packagePolicies } = (await packagePolicyService?.list( - internalSavedObjectsClient, - { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, - perPage: 1000, - page: 1, + if (agentPolicies?.length) { + await pMap( + agentPolicies, + (agentPolicy: GetAgentPoliciesResponseItem) => + agentService?.asInternalUser + .getAgentStatusForAgentPolicy(agentPolicy.id) + .then(({ total: agentTotal }) => (agentPolicy.agents = agentTotal)), + { concurrency: 10 } + ); } - )) ?? { items: [] as PackagePolicy[] }; - const supportedPackagePolicyIds = filter(packagePolicies, (packagePolicy) => - satisfies(packagePolicy.package?.version ?? '', '>=0.6.0') - ); - const agentPolicyIds = uniq(map(supportedPackagePolicyIds, 'policy_id')); - const agentPolicies = await agentPolicyService?.getByIds( - internalSavedObjectsClient, - agentPolicyIds - ); - if (agentPolicies?.length) { - await pMap( - agentPolicies, - (agentPolicy: GetAgentPoliciesResponseItem) => - agentService?.asInternalUser - .getAgentStatusForAgentPolicy(agentPolicy.id) - .then(({ total: agentTotal }) => (agentPolicy.agents = agentTotal)), - { concurrency: 10 } - ); + return response.ok({ body: agentPolicies }); } - - return response.ok({ body: agentPolicies }); - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts index aa1855bbfaac3e..b5fe59aa9d34df 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts @@ -7,30 +7,38 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { getInternalSavedObjectsClient } from '../utils'; export const getAgentPolicyRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/agent_policies/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const packageInfo = await osqueryContext.service - .getAgentPolicyService() - ?.get(internalSavedObjectsClient, request.params.id); + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const packageInfo = await osqueryContext.service + .getAgentPolicyService() + ?.get(internalSavedObjectsClient, request.params.id); - return response.ok({ body: { item: packageInfo } }); - } - ); + return response.ok({ body: { item: packageInfo } }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts index f59a2f38d6c86d..61a7e24ddaa766 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; @@ -15,31 +16,38 @@ export const getAgentStatusForAgentPolicyRoute = ( router: IRouter, osqueryContext: OsqueryAppContext ) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/agent_status', - validate: { - query: schema.object({ - policyId: schema.string(), - kuery: schema.maybe(schema.string()), - }), - params: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const results = await osqueryContext.service - .getAgentService() - ?.asScoped(request) - .getAgentStatusForAgentPolicy(request.query.policyId, request.query.kuery); + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + query: schema.object({ + policyId: schema.string(), + kuery: schema.maybe(schema.string()), + }), + params: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + const results = await osqueryContext.service + .getAgentService() + ?.asScoped(request) + .getAgentStatusForAgentPolicy(request.query.policyId, request.query.kuery); - if (!results) { - return response.ok({ body: {} }); - } + if (!results) { + return response.ok({ body: {} }); + } - const body: GetAgentStatusResponse = { results }; + const body: GetAgentStatusResponse = { results }; - return response.ok({ body }); - } - ); + return response.ok({ body }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts index 7f8f472ba578e4..9b86261aa07b42 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts @@ -7,30 +7,38 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; export const getAgentsRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/agents', - validate: { - query: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - let agents; - try { - agents = await osqueryContext.service - .getAgentService() - ?.asInternalUser // @ts-expect-error update types - .listAgents(request.query); - } catch (error) { - return response.badRequest({ body: error }); - } + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + query: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + let agents; + try { + agents = await osqueryContext.service + .getAgentService() + ?.asInternalUser // @ts-expect-error update types + .listAgents(request.query); + } catch (error) { + return response.badRequest({ body: error }); + } - return response.ok({ body: agents }); - } - ); + return response.ok({ body: agents }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts index 2b9004ee3c882d..cbf5414eb4f879 100644 --- a/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts +++ b/x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts @@ -8,33 +8,41 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID, OSQUERY_INTEGRATION_NAME } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { getInternalSavedObjectsClient } from '../utils'; export const getPackagePoliciesRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/fleet_wrapper/package_policies', - validate: { - query: schema.object({}, { unknowns: 'allow' }), - }, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const kuery = `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.attributes.package.name: ${OSQUERY_INTEGRATION_NAME}`; - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); - const policies = await packagePolicyService?.list(internalSavedObjectsClient, { - kuery, - perPage: 1000, - }); + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: { + request: { + query: schema.object({}, { unknowns: 'allow' }), + }, + }, + }, + async (context, request, response) => { + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const kuery = `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.attributes.package.name: ${OSQUERY_INTEGRATION_NAME}`; + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + const policies = await packagePolicyService?.list(internalSavedObjectsClient, { + kuery, + perPage: 1000, + }); - return response.ok({ - body: policies, - }); - } - ); + return response.ok({ + body: policies, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts b/x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts index d9bb8eb8efb255..971f2c3b45a4c9 100644 --- a/x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts @@ -11,6 +11,7 @@ import markdown from 'remark-parse-no-trim'; import { some, filter } from 'lodash'; import deepEqual from 'fast-deep-equal'; import type { ECSMappingOrUndefined } from '@kbn/osquery-io-ts-types'; +import { API_VERSIONS } from '../../../common/constants'; import { PARAMETER_NOT_FOUND } from '../../../common/translations/errors'; import { replaceParamsQuery } from '../../../common/utils/replace_params_query'; import { createLiveQueryRequestBodySchema } from '../../../common/schemas/routes/live_query'; @@ -21,107 +22,114 @@ import { createActionHandler } from '../../handlers'; import { parser as OsqueryParser } from './osquery_parser'; export const createLiveQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.post( - { + router.versioned + .post({ + access: 'public', path: '/api/osquery/live_queries', - validate: { - body: buildRouteValidation< - typeof createLiveQueryRequestBodySchema, - CreateLiveQueryRequestBodySchema - >(createLiveQueryRequestBodySchema), + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + body: buildRouteValidation< + typeof createLiveQueryRequestBodySchema, + CreateLiveQueryRequestBodySchema + >(createLiveQueryRequestBodySchema), + }, + }, }, - }, - async (context, request, response) => { - const [coreStartServices] = await osqueryContext.getStartServices(); - const soClient = (await context.core).savedObjects.client; + async (context, request, response) => { + const [coreStartServices] = await osqueryContext.getStartServices(); + const soClient = (await context.core).savedObjects.client; - const { - osquery: { writeLiveQueries, runSavedQueries }, - } = await coreStartServices.capabilities.resolveCapabilities(request); + const { + osquery: { writeLiveQueries, runSavedQueries }, + } = await coreStartServices.capabilities.resolveCapabilities(request); - const isInvalid = !( - writeLiveQueries || - (runSavedQueries && (request.body.saved_query_id || request.body.pack_id)) - ); + const isInvalid = !( + writeLiveQueries || + (runSavedQueries && (request.body.saved_query_id || request.body.pack_id)) + ); - const client = await osqueryContext.service - .getRuleRegistryService() - ?.getRacClientWithRequest(request); + const client = await osqueryContext.service + .getRuleRegistryService() + ?.getRacClientWithRequest(request); - const alertData = request.body.alert_ids?.length - ? await client?.get({ id: request.body.alert_ids[0] }) - : undefined; + const alertData = request.body.alert_ids?.length + ? await client?.get({ id: request.body.alert_ids[0] }) + : undefined; - if (isInvalid) { - if (request.body.alert_ids?.length) { - try { - if (alertData?.['kibana.alert.rule.note']) { - const parsedAlertInvestigationGuide = unified() - .use([[markdown, {}], OsqueryParser]) - .parse(alertData?.['kibana.alert.rule.note']); + if (isInvalid) { + if (request.body.alert_ids?.length) { + try { + if (alertData?.['kibana.alert.rule.note']) { + const parsedAlertInvestigationGuide = unified() + .use([[markdown, {}], OsqueryParser]) + .parse(alertData?.['kibana.alert.rule.note']); - const osqueryQueries = filter(parsedAlertInvestigationGuide?.children as object, [ - 'type', - 'osquery', - ]); + const osqueryQueries = filter(parsedAlertInvestigationGuide?.children as object, [ + 'type', + 'osquery', + ]); - const requestQueryExistsInTheInvestigationGuide = some( - osqueryQueries, - (payload: { - configuration: { query: string; ecs_mapping: ECSMappingOrUndefined }; - }) => { - const { result: replacedConfigurationQuery } = replaceParamsQuery( - payload.configuration.query, - alertData - ); + const requestQueryExistsInTheInvestigationGuide = some( + osqueryQueries, + (payload: { + configuration: { query: string; ecs_mapping: ECSMappingOrUndefined }; + }) => { + const { result: replacedConfigurationQuery } = replaceParamsQuery( + payload.configuration.query, + alertData + ); - return ( - replacedConfigurationQuery === request.body.query && - deepEqual(payload.configuration.ecs_mapping, request.body.ecs_mapping) - ); - } - ); + return ( + replacedConfigurationQuery === request.body.query && + deepEqual(payload.configuration.ecs_mapping, request.body.ecs_mapping) + ); + } + ); - if (!requestQueryExistsInTheInvestigationGuide) throw new Error(); + if (!requestQueryExistsInTheInvestigationGuide) throw new Error(); + } + } catch (error) { + return response.forbidden(); } - } catch (error) { + } else { return response.forbidden(); } - } else { - return response.forbidden(); } - } - try { - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - const { response: osqueryAction, fleetActionsCount } = await createActionHandler( - osqueryContext, - request.body, - { - soClient, - metadata: { currentUser }, - alertData, + try { + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; + const { response: osqueryAction, fleetActionsCount } = await createActionHandler( + osqueryContext, + request.body, + { + soClient, + metadata: { currentUser }, + alertData, + } + ); + if (!fleetActionsCount) { + return response.badRequest({ + body: PARAMETER_NOT_FOUND, + }); } - ); - if (!fleetActionsCount) { - return response.badRequest({ - body: PARAMETER_NOT_FOUND, + + return response.ok({ + body: { data: osqueryAction }, }); - } + } catch (error) { + if (error.statusCode === 400) { + return response.badRequest({ body: error }); + } - return response.ok({ - body: { data: osqueryAction }, - }); - } catch (error) { - if (error.statusCode === 400) { - return response.badRequest({ body: error }); + return response.customError({ + statusCode: 500, + body: new Error(`Error occurred while processing ${error}`), + }); } - - return response.customError({ - statusCode: 500, - body: new Error(`Error occurred while processing ${error}`), - }); } - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts b/x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts index 5186de9ce67bee..858b76315c8e01 100644 --- a/x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts @@ -11,6 +11,7 @@ import { omit } from 'lodash'; import type { Observable } from 'rxjs'; import { lastValueFrom } from 'rxjs'; import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { @@ -22,64 +23,73 @@ import { OsqueryQueries } from '../../../common/search_strategy'; import { createFilter, generateTablePaginationOptions } from '../../../common/utils/build_query'; export const findLiveQueryRoute = (router: IRouter) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/live_queries', - validate: { - query: schema.object( - { - filterQuery: schema.maybe(schema.string()), - page: schema.maybe(schema.number()), - pageSize: schema.maybe(schema.number()), - sort: schema.maybe(schema.string()), - sortOrder: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])), + options: { tags: [`access:${PLUGIN_ID}-read`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + query: schema.object( + { + filterQuery: schema.maybe(schema.string()), + page: schema.maybe(schema.number()), + pageSize: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + sortOrder: schema.maybe( + schema.oneOf([schema.literal('asc'), schema.literal('desc')]) + ), + }, + { unknowns: 'allow' } + ), }, - { unknowns: 'allow' } - ), + }, }, - options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const abortSignal = getRequestAbortedSignal(request.events.aborted$); + async (context, request, response) => { + const abortSignal = getRequestAbortedSignal(request.events.aborted$); - try { - const search = await context.search; - const res = await lastValueFrom( - search.search( - { - factoryQueryType: OsqueryQueries.actions, - filterQuery: createFilter(request.query.filterQuery), - pagination: generateTablePaginationOptions( - request.query.page ?? 0, - request.query.pageSize ?? 100 - ), - sort: { - direction: (request.query.sortOrder ?? 'desc') as Direction, - field: request.query.sort ?? 'created_at', + try { + const search = await context.search; + const res = await lastValueFrom( + search.search( + { + factoryQueryType: OsqueryQueries.actions, + filterQuery: createFilter(request.query.filterQuery), + pagination: generateTablePaginationOptions( + request.query.page ?? 0, + request.query.pageSize ?? 100 + ), + sort: { + direction: (request.query.sortOrder ?? 'desc') as Direction, + field: request.query.sort ?? 'created_at', + }, }, - }, - { abortSignal, strategy: 'osquerySearchStrategy' } - ) - ); + { abortSignal, strategy: 'osquerySearchStrategy' } + ) + ); - return response.ok({ - body: { - data: { - ...omit(res, 'edges'), - items: res.edges, + return response.ok({ + body: { + data: { + ...omit(res, 'edges'), + items: res.edges, + }, }, - }, - }); - } catch (e) { - return response.customError({ - statusCode: e.statusCode ?? 500, - body: { - message: e.message, - }, - }); + }); + } catch (e) { + return response.customError({ + statusCode: e.statusCode ?? 500, + body: { + message: e.message, + }, + }); + } } - } - ); + ); }; function getRequestAbortedSignal(aborted$: Observable): AbortSignal { diff --git a/x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts b/x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts index 71da29d04c4164..6bd2bf3a11963d 100644 --- a/x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts +++ b/x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts @@ -11,6 +11,7 @@ import { every, map, mapKeys, pick, reduce } from 'lodash'; import type { Observable } from 'rxjs'; import { lastValueFrom, zip } from 'rxjs'; import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import { getActionResponses } from './utils'; @@ -21,108 +22,115 @@ import type { import { OsqueryQueries } from '../../../common/search_strategy'; export const getLiveQueryDetailsRoute = (router: IRouter) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/live_queries/{id}', - validate: { - params: schema.object( - { - id: schema.string(), + options: { tags: [`access:${PLUGIN_ID}-read`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object( + { + id: schema.string(), + }, + { unknowns: 'allow' } + ), + query: schema.object({}, { unknowns: 'allow' }), }, - { unknowns: 'allow' } - ), - query: schema.object({}, { unknowns: 'allow' }), + }, }, - options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const abortSignal = getRequestAbortedSignal(request.events.aborted$); + async (context, request, response) => { + const abortSignal = getRequestAbortedSignal(request.events.aborted$); - try { - const search = await context.search; - const { actionDetails } = await lastValueFrom( - search.search( - { - actionId: request.params.id, - filterQuery: request.query, - factoryQueryType: OsqueryQueries.actionDetails, - }, - { abortSignal, strategy: 'osquerySearchStrategy' } - ) - ); + try { + const search = await context.search; + const { actionDetails } = await lastValueFrom( + search.search( + { + actionId: request.params.id, + filterQuery: request.query, + factoryQueryType: OsqueryQueries.actionDetails, + }, + { abortSignal, strategy: 'osquerySearchStrategy' } + ) + ); - const queries = actionDetails?._source?.queries; - const expirationDate = actionDetails?.fields?.expiration[0]; + const queries = actionDetails?._source?.queries; + const expirationDate = actionDetails?.fields?.expiration[0]; - const expired = !expirationDate ? true : new Date(expirationDate) < new Date(); + const expired = !expirationDate ? true : new Date(expirationDate) < new Date(); - const responseData = await lastValueFrom( - zip( - ...map(queries, (query) => - getActionResponses(search, query.action_id, query.agents?.length ?? 0) + const responseData = await lastValueFrom( + zip( + ...map(queries, (query) => + getActionResponses(search, query.action_id, query.agents?.length ?? 0) + ) ) - ) - ); + ); - const isCompleted = expired || (responseData && every(responseData, ['pending', 0])); - const agentByActionIdStatusMap = mapKeys(responseData, 'action_id'); + const isCompleted = expired || (responseData && every(responseData, ['pending', 0])); + const agentByActionIdStatusMap = mapKeys(responseData, 'action_id'); - return response.ok({ - body: { - data: { - ...pick( - actionDetails._source, - 'action_id', - 'expiration', - '@timestamp', - 'agent_selection', - 'agents', - 'user_id', - 'pack_id', - 'pack_name', - 'prebuilt_pack' - ), - queries: reduce< - { - action_id: string; - id: string; - query: string; - agents: string[]; - ecs_mapping?: unknown; - version?: string; - platform?: string; - saved_query_id?: string; - }, - Array> - >( - actionDetails._source?.queries, - (acc, query) => { - const agentStatus = agentByActionIdStatusMap[query.action_id]; + return response.ok({ + body: { + data: { + ...pick( + actionDetails._source, + 'action_id', + 'expiration', + '@timestamp', + 'agent_selection', + 'agents', + 'user_id', + 'pack_id', + 'pack_name', + 'prebuilt_pack' + ), + queries: reduce< + { + action_id: string; + id: string; + query: string; + agents: string[]; + ecs_mapping?: unknown; + version?: string; + platform?: string; + saved_query_id?: string; + }, + Array> + >( + actionDetails._source?.queries, + (acc, query) => { + const agentStatus = agentByActionIdStatusMap[query.action_id]; - acc.push({ - ...query, - ...agentStatus, - status: isCompleted || agentStatus?.pending === 0 ? 'completed' : 'running', - }); + acc.push({ + ...query, + ...agentStatus, + status: isCompleted || agentStatus?.pending === 0 ? 'completed' : 'running', + }); - return acc; - }, - [] as Array> - ), - status: isCompleted ? 'completed' : 'running', + return acc; + }, + [] as Array> + ), + status: isCompleted ? 'completed' : 'running', + }, }, - }, - }); - } catch (e) { - return response.customError({ - statusCode: e.statusCode ?? 500, - body: { - message: e.message, - }, - }); + }); + } catch (e) { + return response.customError({ + statusCode: e.statusCode ?? 500, + body: { + message: e.message, + }, + }); + } } - } - ); + ); }; function getRequestAbortedSignal(aborted$: Observable): AbortSignal { diff --git a/x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts b/x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts index c47772bbc70392..c7a86d440e3443 100644 --- a/x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts +++ b/x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts @@ -11,6 +11,7 @@ import { map } from 'lodash'; import type { Observable } from 'rxjs'; import { lastValueFrom, zip } from 'rxjs'; import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import type { ActionDetailsRequestOptions, @@ -21,88 +22,97 @@ import { createFilter, generateTablePaginationOptions } from '../../../common/ut import { getActionResponses } from './utils'; export const getLiveQueryResultsRoute = (router: IRouter) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/live_queries/{id}/results/{actionId}', - validate: { - query: schema.object( - { - filterQuery: schema.maybe(schema.string()), - page: schema.maybe(schema.number()), - pageSize: schema.maybe(schema.number()), - sort: schema.maybe(schema.string()), - sortOrder: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])), - }, - { unknowns: 'allow' } - ), - params: schema.object( - { - id: schema.string(), - actionId: schema.string(), + options: { tags: [`access:${PLUGIN_ID}-read`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + query: schema.object( + { + filterQuery: schema.maybe(schema.string()), + page: schema.maybe(schema.number()), + pageSize: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + sortOrder: schema.maybe( + schema.oneOf([schema.literal('asc'), schema.literal('desc')]) + ), + }, + { unknowns: 'allow' } + ), + params: schema.object( + { + id: schema.string(), + actionId: schema.string(), + }, + { unknowns: 'allow' } + ), }, - { unknowns: 'allow' } - ), + }, }, - options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const abortSignal = getRequestAbortedSignal(request.events.aborted$); + async (context, request, response) => { + const abortSignal = getRequestAbortedSignal(request.events.aborted$); - try { - const search = await context.search; - const { actionDetails } = await lastValueFrom( - search.search( - { - actionId: request.params.id, - filterQuery: createFilter(request.query.filterQuery), - factoryQueryType: OsqueryQueries.actionDetails, - }, - { abortSignal, strategy: 'osquerySearchStrategy' } - ) - ); + try { + const search = await context.search; + const { actionDetails } = await lastValueFrom( + search.search( + { + actionId: request.params.id, + filterQuery: createFilter(request.query.filterQuery), + factoryQueryType: OsqueryQueries.actionDetails, + }, + { abortSignal, strategy: 'osquerySearchStrategy' } + ) + ); - const queries = actionDetails?._source?.queries; + const queries = actionDetails?._source?.queries; - await lastValueFrom( - zip( - ...map(queries, (query) => - getActionResponses(search, query.action_id, query.agents?.length ?? 0) + await lastValueFrom( + zip( + ...map(queries, (query) => + getActionResponses(search, query.action_id, query.agents?.length ?? 0) + ) ) - ) - ); + ); - const res = await lastValueFrom( - search.search<{}>( - { - actionId: request.params.actionId, - factoryQueryType: OsqueryQueries.results, - filterQuery: createFilter(request.query.filterQuery), - pagination: generateTablePaginationOptions( - request.query.page ?? 0, - request.query.pageSize ?? 100 - ), - sort: { - direction: request.query.sortOrder ?? 'desc', - field: request.query.sort ?? '@timestamp', + const res = await lastValueFrom( + search.search<{}>( + { + actionId: request.params.actionId, + factoryQueryType: OsqueryQueries.results, + filterQuery: createFilter(request.query.filterQuery), + pagination: generateTablePaginationOptions( + request.query.page ?? 0, + request.query.pageSize ?? 100 + ), + sort: { + direction: request.query.sortOrder ?? 'desc', + field: request.query.sort ?? '@timestamp', + }, }, - }, - { abortSignal, strategy: 'osquerySearchStrategy' } - ) - ); + { abortSignal, strategy: 'osquerySearchStrategy' } + ) + ); - return response.ok({ - body: { data: res }, - }); - } catch (e) { - return response.customError({ - statusCode: e.statusCode ?? 500, - body: { - message: e.message, - }, - }); + return response.ok({ + body: { data: res }, + }); + } catch (e) { + return response.customError({ + statusCode: e.statusCode ?? 500, + body: { + message: e.message, + }, + }); + } } - } - ); + ); }; function getRequestAbortedSignal(aborted$: Observable): AbortSignal { diff --git a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts index f505d5edd87de9..5d12a41f03c4d2 100644 --- a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts @@ -16,6 +16,7 @@ import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { OSQUERY_INTEGRATION_NAME } from '../../../common'; import { PLUGIN_ID } from '../../../common'; @@ -33,170 +34,177 @@ import type { PackResponseData } from './types'; type PackSavedObjectLimited = Omit; export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.post( - { + router.versioned + .post({ + access: 'public', path: '/api/osquery/packs', - validate: { - body: schema.object( - { - name: schema.string(), - description: schema.maybe(schema.string()), - enabled: schema.maybe(schema.boolean()), - policy_ids: schema.maybe(schema.arrayOf(schema.string())), - shards: schema.recordOf(schema.string(), schema.number()), - queries: schema.recordOf( - schema.string(), - schema.object({ - query: schema.string(), - interval: schema.maybe(schema.number()), - snapshot: schema.maybe(schema.boolean()), - removed: schema.maybe(schema.boolean()), - platform: schema.maybe(schema.string()), - version: schema.maybe(schema.string()), - ecs_mapping: schema.maybe( - schema.recordOf( - schema.string(), - schema.object({ - field: schema.maybe(schema.string()), - value: schema.maybe( - schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) - ), - }) - ) + options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + body: schema.object( + { + name: schema.string(), + description: schema.maybe(schema.string()), + enabled: schema.maybe(schema.boolean()), + policy_ids: schema.maybe(schema.arrayOf(schema.string())), + shards: schema.recordOf(schema.string(), schema.number()), + queries: schema.recordOf( + schema.string(), + schema.object({ + query: schema.string(), + interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), + platform: schema.maybe(schema.string()), + version: schema.maybe(schema.string()), + ecs_mapping: schema.maybe( + schema.recordOf( + schema.string(), + schema.object({ + field: schema.maybe(schema.string()), + value: schema.maybe( + schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) + ), + }) + ) + ), + }) ), - }) + }, + { unknowns: 'allow' } ), }, - { unknowns: 'allow' } - ), - }, - options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const esClient = coreContext.elasticsearch.client.asCurrentUser; - const savedObjectsClient = coreContext.savedObjects.client; - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const agentPolicyService = osqueryContext.service.getAgentPolicyService(); - - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - - // eslint-disable-next-line @typescript-eslint/naming-convention - const { name, description, queries, enabled, policy_ids, shards } = request.body; - const conflictingEntries = await savedObjectsClient.find({ - type: packSavedObjectType, - filter: `${packSavedObjectType}.attributes.name: "${name}"`, - }); - - if ( - conflictingEntries.saved_objects.length && - some(conflictingEntries.saved_objects, ['attributes.name', name]) - ) { - return response.conflict({ body: `Pack with name "${name}" already exists.` }); - } - - const { items: packagePolicies } = (await packagePolicyService?.list( - internalSavedObjectsClient, - { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, - perPage: 1000, - page: 1, - } - )) ?? { items: [] }; - - const policiesList = getInitialPolicies(packagePolicies, policy_ids, shards); - - const agentPolicies = await agentPolicyService?.getByIds( - internalSavedObjectsClient, - policiesList - ); - - const policyShards = findMatchingShards(agentPolicies, shards); - - const agentPoliciesIdMap = mapKeys(agentPolicies, 'id'); - - const references = policiesList.map((id) => ({ - id, - name: agentPoliciesIdMap[id]?.name, - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - })); - - const packSO = await savedObjectsClient.create( - packSavedObjectType, - { - name, - description, - queries: convertPackQueriesToSO(queries), - enabled, - created_at: moment().toISOString(), - created_by: currentUser, - updated_at: moment().toISOString(), - updated_by: currentUser, - shards: convertShardsToArray(shards), }, - { - references, - refresh: 'wait_for', + }, + async (context, request, response) => { + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const agentPolicyService = osqueryContext.service.getAgentPolicyService(); + + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; + + // eslint-disable-next-line @typescript-eslint/naming-convention + const { name, description, queries, enabled, policy_ids, shards } = request.body; + const conflictingEntries = await savedObjectsClient.find({ + type: packSavedObjectType, + filter: `${packSavedObjectType}.attributes.name: "${name}"`, + }); + + if ( + conflictingEntries.saved_objects.length && + some(conflictingEntries.saved_objects, ['attributes.name', name]) + ) { + return response.conflict({ body: `Pack with name "${name}" already exists.` }); } - ); - - if (enabled && policiesList.length) { - await Promise.all( - policiesList.map((agentPolicyId) => { - const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); - if (packagePolicy) { - return packagePolicyService?.update( - internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - if (!has(draft, 'inputs[0].streams')) { - set(draft, 'inputs[0].streams', []); - } - - set(draft, `inputs[0].config.osquery.value.packs.${packSO.attributes.name}`, { - shard: policyShards[packagePolicy.policy_id] - ? policyShards[packagePolicy.policy_id] - : 100, - queries: convertSOQueriesToPackConfig(queries), - }); - - return draft; - }) - ); - } - }) + + const { items: packagePolicies } = (await packagePolicyService?.list( + internalSavedObjectsClient, + { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, + perPage: 1000, + page: 1, + } + )) ?? { items: [] }; + + const policiesList = getInitialPolicies(packagePolicies, policy_ids, shards); + + const agentPolicies = await agentPolicyService?.getByIds( + internalSavedObjectsClient, + policiesList ); - } - set(packSO, 'attributes.queries', queries); - - const { attributes } = packSO; - - const data: PackResponseData = { - name: attributes.name, - description: attributes.description, - queries: attributes.queries, - version: attributes.version, - enabled: attributes.enabled, - created_at: attributes.created_at, - created_by: attributes.created_by, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - policy_ids: attributes.policy_ids, - shards: attributes.shards, - saved_object_id: packSO.id, - }; - - return response.ok({ - body: { - data, - }, - }); - } - ); + const policyShards = findMatchingShards(agentPolicies, shards); + + const agentPoliciesIdMap = mapKeys(agentPolicies, 'id'); + + const references = policiesList.map((id) => ({ + id, + name: agentPoliciesIdMap[id]?.name, + type: AGENT_POLICY_SAVED_OBJECT_TYPE, + })); + + const packSO = await savedObjectsClient.create( + packSavedObjectType, + { + name, + description, + queries: convertPackQueriesToSO(queries), + enabled, + created_at: moment().toISOString(), + created_by: currentUser, + updated_at: moment().toISOString(), + updated_by: currentUser, + shards: convertShardsToArray(shards), + }, + { + references, + refresh: 'wait_for', + } + ); + + if (enabled && policiesList.length) { + await Promise.all( + policiesList.map((agentPolicyId) => { + const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); + if (packagePolicy) { + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + if (!has(draft, 'inputs[0].streams')) { + set(draft, 'inputs[0].streams', []); + } + + set(draft, `inputs[0].config.osquery.value.packs.${packSO.attributes.name}`, { + shard: policyShards[packagePolicy.policy_id] + ? policyShards[packagePolicy.policy_id] + : 100, + queries: convertSOQueriesToPackConfig(queries), + }); + + return draft; + }) + ); + } + }) + ); + } + + set(packSO, 'attributes.queries', queries); + + const { attributes } = packSO; + + const data: PackResponseData = { + name: attributes.name, + description: attributes.description, + queries: attributes.queries, + version: attributes.version, + enabled: attributes.enabled, + created_at: attributes.created_at, + created_by: attributes.created_by, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + policy_ids: attributes.policy_ids, + shards: attributes.shards, + saved_object_id: packSO.id, + }; + + return response.ok({ + body: { + data, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts index cfcab5ad5b2590..33a569653ea1d1 100644 --- a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts @@ -10,6 +10,7 @@ import { produce } from 'immer'; import { schema } from '@kbn/config-schema'; import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { OSQUERY_INTEGRATION_NAME } from '../../../common'; import { PLUGIN_ID } from '../../../common'; @@ -17,62 +18,72 @@ import { packSavedObjectType } from '../../../common/types'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; export const deletePackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.delete( - { + router.versioned + .delete({ + access: 'public', path: '/api/osquery/packs/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - }, options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const esClient = coreContext.elasticsearch.client.asCurrentUser; - const savedObjectsClient = coreContext.savedObjects.client; - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); - const currentPackSO = await savedObjectsClient.get<{ name: string }>( - packSavedObjectType, - request.params.id - ); + const currentPackSO = await savedObjectsClient.get<{ name: string }>( + packSavedObjectType, + request.params.id + ); - await savedObjectsClient.delete(packSavedObjectType, request.params.id, { - refresh: 'wait_for', - }); + await savedObjectsClient.delete(packSavedObjectType, request.params.id, { + refresh: 'wait_for', + }); - const { items: packagePolicies } = (await packagePolicyService?.list(savedObjectsClient, { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, - perPage: 1000, - page: 1, - })) ?? { items: [] }; - const currentPackagePolicies = filter(packagePolicies, (packagePolicy) => - has(packagePolicy, `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}`) - ); + const { items: packagePolicies } = (await packagePolicyService?.list(savedObjectsClient, { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, + perPage: 1000, + page: 1, + })) ?? { items: [] }; + const currentPackagePolicies = filter(packagePolicies, (packagePolicy) => + has( + packagePolicy, + `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + ) + ); - await Promise.all( - currentPackagePolicies.map((packagePolicy) => - packagePolicyService?.update( - savedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - unset( - draft, - `inputs[0].config.osquery.value.packs.${[currentPackSO.attributes.name]}` - ); + await Promise.all( + currentPackagePolicies.map((packagePolicy) => + packagePolicyService?.update( + savedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + unset( + draft, + `inputs[0].config.osquery.value.packs.${[currentPackSO.attributes.name]}` + ); - return draft; - }) + return draft; + }) + ) ) - ) - ); + ); - return response.ok({ - body: {}, - }); - } - ); + return response.ok({ + body: {}, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts index 0d40efc7c748cc..394fc50ff4e29f 100644 --- a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts @@ -10,69 +10,79 @@ import { schema } from '@kbn/config-schema'; import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { packSavedObjectType } from '../../../common/types'; import { PLUGIN_ID } from '../../../common'; import type { PackSavedObject } from '../../common/types'; import type { PackResponseData } from './types'; export const findPackRoute = (router: IRouter) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/packs', - validate: { - query: schema.object( - { - page: schema.maybe(schema.number()), - pageSize: schema.maybe(schema.number()), - sort: schema.maybe(schema.string()), - sortOrder: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])), + options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + query: schema.object( + { + page: schema.maybe(schema.number()), + pageSize: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + sortOrder: schema.maybe( + schema.oneOf([schema.literal('asc'), schema.literal('desc')]) + ), + }, + { unknowns: 'allow' } + ), }, - { unknowns: 'allow' } - ), + }, }, - options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - const soClientResponse = await savedObjectsClient.find({ - type: packSavedObjectType, - page: request.query.page ?? 1, - perPage: request.query.pageSize ?? 20, - sortField: request.query.sort ?? 'updated_at', - sortOrder: request.query.sortOrder ?? 'desc', - }); + const soClientResponse = await savedObjectsClient.find({ + type: packSavedObjectType, + page: request.query.page ?? 1, + perPage: request.query.pageSize ?? 20, + sortField: request.query.sort ?? 'updated_at', + sortOrder: request.query.sortOrder ?? 'desc', + }); - const packSavedObjects: PackResponseData[] = map(soClientResponse.saved_objects, (pack) => { - const policyIds = map( - filter(pack.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), - 'id' - ); + const packSavedObjects: PackResponseData[] = map(soClientResponse.saved_objects, (pack) => { + const policyIds = map( + filter(pack.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), + 'id' + ); - const { attributes } = pack; + const { attributes } = pack; - return { - name: attributes.name, - description: attributes.description, - queries: attributes.queries, - version: attributes.version, - enabled: attributes.enabled, - created_at: attributes.created_at, - created_by: attributes.created_by, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - saved_object_id: pack.id, - policy_ids: policyIds, - }; - }); + return { + name: attributes.name, + description: attributes.description, + queries: attributes.queries, + version: attributes.version, + enabled: attributes.enabled, + created_at: attributes.created_at, + created_by: attributes.created_by, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + saved_object_id: pack.id, + policy_ids: policyIds, + }; + }); - return response.ok({ - body: { - ...omit(soClientResponse, 'saved_objects'), - data: packSavedObjects, - }, - }); - } - ); + return response.ok({ + body: { + ...omit(soClientResponse, 'saved_objects'), + data: packSavedObjects, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts index e0d2001758bd38..0a61b0310def0b 100644 --- a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts @@ -9,6 +9,7 @@ import { filter, map } from 'lodash'; import { schema } from '@kbn/config-schema'; import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import type { PackSavedObject } from '../../common/types'; import { PLUGIN_ID } from '../../../common'; @@ -18,54 +19,59 @@ import { convertShardsToObject } from '../utils'; import type { ReadPackResponseData } from './types'; export const readPackRoute = (router: IRouter) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/packs/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - }, options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - const { attributes, references, id, ...rest } = await savedObjectsClient.get( - packSavedObjectType, - request.params.id - ); + const { attributes, references, id, ...rest } = + await savedObjectsClient.get(packSavedObjectType, request.params.id); - const policyIds = map(filter(references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), 'id'); - const osqueryPackAssetReference = !!filter(references, ['type', 'osquery-pack-asset']); + const policyIds = map(filter(references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), 'id'); + const osqueryPackAssetReference = !!filter(references, ['type', 'osquery-pack-asset']); - const data: ReadPackResponseData = { - type: rest.type, - namespaces: rest.namespaces, - migrationVersion: rest.migrationVersion, - managed: rest.managed, - coreMigrationVersion: rest.coreMigrationVersion, - name: attributes.name, - description: attributes.description, - version: attributes.version, - enabled: attributes.enabled, - created_at: attributes.created_at, - created_by: attributes.created_by, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - saved_object_id: id, - queries: convertSOQueriesToPack(attributes.queries), - shards: convertShardsToObject(attributes.shards), - policy_ids: policyIds, - read_only: attributes.version !== undefined && osqueryPackAssetReference, - }; + const data: ReadPackResponseData = { + type: rest.type, + namespaces: rest.namespaces, + migrationVersion: rest.migrationVersion, + managed: rest.managed, + coreMigrationVersion: rest.coreMigrationVersion, + name: attributes.name, + description: attributes.description, + version: attributes.version, + enabled: attributes.enabled, + created_at: attributes.created_at, + created_by: attributes.created_by, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + saved_object_id: id, + queries: convertSOQueriesToPack(attributes.queries), + shards: convertShardsToObject(attributes.shards), + policy_ids: policyIds, + read_only: attributes.version !== undefined && osqueryPackAssetReference, + }; - return response.ok({ - body: { - data, - }, - }); - } - ); + return response.ok({ + body: { + data, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts index 7f928f3acf40f8..0d05a4d1b30cb6 100644 --- a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts @@ -17,6 +17,7 @@ import { } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { OSQUERY_INTEGRATION_NAME } from '../../../common'; import { packSavedObjectType } from '../../../common/types'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; @@ -34,172 +35,264 @@ import type { PackSavedObject } from '../../common/types'; import type { PackResponseData } from './types'; export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.put( - { + router.versioned + .put({ + access: 'public', path: '/api/osquery/packs/{id}', - validate: { - params: schema.object( - { - id: schema.string(), - }, - { unknowns: 'allow' } - ), - body: schema.object( - { - name: schema.maybe(schema.string()), - description: schema.maybe(schema.string()), - enabled: schema.maybe(schema.boolean()), - policy_ids: schema.maybe(schema.arrayOf(schema.string())), - shards: schema.maybe(schema.recordOf(schema.string(), schema.number())), - queries: schema.maybe( - schema.recordOf( - schema.string(), - schema.object({ - query: schema.string(), - interval: schema.maybe(schema.number()), - snapshot: schema.maybe(schema.boolean()), - removed: schema.maybe(schema.boolean()), - platform: schema.maybe(schema.string()), - version: schema.maybe(schema.string()), - ecs_mapping: schema.maybe( - schema.recordOf( - schema.string(), - schema.object({ - field: schema.maybe(schema.string()), - value: schema.maybe( - schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) - ), - }) - ) - ), - }) - ) + options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object( + { + id: schema.string(), + }, + { unknowns: 'allow' } + ), + body: schema.object( + { + name: schema.maybe(schema.string()), + description: schema.maybe(schema.string()), + enabled: schema.maybe(schema.boolean()), + policy_ids: schema.maybe(schema.arrayOf(schema.string())), + shards: schema.maybe(schema.recordOf(schema.string(), schema.number())), + queries: schema.maybe( + schema.recordOf( + schema.string(), + schema.object({ + query: schema.string(), + interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), + platform: schema.maybe(schema.string()), + version: schema.maybe(schema.string()), + ecs_mapping: schema.maybe( + schema.recordOf( + schema.string(), + schema.object({ + field: schema.maybe(schema.string()), + value: schema.maybe( + schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) + ), + }) + ) + ), + }) + ) + ), + }, + { unknowns: 'allow' } ), }, - { unknowns: 'allow' } - ), + }, }, - options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const esClient = coreContext.elasticsearch.client.asCurrentUser; - const savedObjectsClient = coreContext.savedObjects.client; - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const agentPolicyService = osqueryContext.service.getAgentPolicyService(); - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - - // eslint-disable-next-line @typescript-eslint/naming-convention - const { name, description, queries, enabled, policy_ids, shards = {} } = request.body; - - const currentPackSO = await savedObjectsClient.get<{ name: string; enabled: boolean }>( - packSavedObjectType, - request.params.id - ); - - if (name) { - const conflictingEntries = await savedObjectsClient.find({ - type: packSavedObjectType, - filter: `${packSavedObjectType}.attributes.name: "${name}"`, - }); + async (context, request, response) => { + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const agentPolicyService = osqueryContext.service.getAgentPolicyService(); + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - if ( - some( - filter(conflictingEntries.saved_objects, (packSO) => packSO.id !== currentPackSO.id), - ['attributes.name', name] - ) - ) { - return response.conflict({ body: `Pack with name "${name}" already exists.` }); - } - } + // eslint-disable-next-line @typescript-eslint/naming-convention + const { name, description, queries, enabled, policy_ids, shards = {} } = request.body; - const { items: packagePolicies } = (await packagePolicyService?.list( - internalSavedObjectsClient, - { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, - perPage: 1000, - page: 1, + const currentPackSO = await savedObjectsClient.get<{ name: string; enabled: boolean }>( + packSavedObjectType, + request.params.id + ); + + if (name) { + const conflictingEntries = await savedObjectsClient.find({ + type: packSavedObjectType, + filter: `${packSavedObjectType}.attributes.name: "${name}"`, + }); + + if ( + some( + filter(conflictingEntries.saved_objects, (packSO) => packSO.id !== currentPackSO.id), + ['attributes.name', name] + ) + ) { + return response.conflict({ body: `Pack with name "${name}" already exists.` }); + } } - )) ?? { items: [] }; - const currentPackagePolicies = filter(packagePolicies, (packagePolicy) => - has(packagePolicy, `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}`) - ); - const policiesList = getInitialPolicies(packagePolicies, policy_ids, shards); + const { items: packagePolicies } = (await packagePolicyService?.list( + internalSavedObjectsClient, + { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, + perPage: 1000, + page: 1, + } + )) ?? { items: [] }; + const currentPackagePolicies = filter(packagePolicies, (packagePolicy) => + has( + packagePolicy, + `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + ) + ); + + const policiesList = getInitialPolicies(packagePolicies, policy_ids, shards); - const agentPolicies = await agentPolicyService?.getByIds( - internalSavedObjectsClient, - policiesList - ); + const agentPolicies = await agentPolicyService?.getByIds( + internalSavedObjectsClient, + policiesList + ); - const policyShards = findMatchingShards(agentPolicies, shards); + const policyShards = findMatchingShards(agentPolicies, shards); - const agentPoliciesIdMap = mapKeys(agentPolicies, 'id'); + const agentPoliciesIdMap = mapKeys(agentPolicies, 'id'); - const nonAgentPolicyReferences = filter( - currentPackSO.references, - (reference) => reference.type !== AGENT_POLICY_SAVED_OBJECT_TYPE - ); - const getUpdatedReferences = () => { - if (!policy_ids && isEmpty(shards)) { - return currentPackSO.references; - } + const nonAgentPolicyReferences = filter( + currentPackSO.references, + (reference) => reference.type !== AGENT_POLICY_SAVED_OBJECT_TYPE + ); + const getUpdatedReferences = () => { + if (!policy_ids && isEmpty(shards)) { + return currentPackSO.references; + } + + return [ + ...nonAgentPolicyReferences, + ...policiesList.map((id) => ({ + id, + name: agentPoliciesIdMap[id]?.name, + type: AGENT_POLICY_SAVED_OBJECT_TYPE, + })), + ]; + }; + + const references = getUpdatedReferences(); + + await savedObjectsClient.update( + packSavedObjectType, + request.params.id, + { + enabled, + name, + description: description || '', + queries: queries && convertPackQueriesToSO(queries), + updated_at: moment().toISOString(), + updated_by: currentUser, + shards: convertShardsToArray(shards), + }, + { + refresh: 'wait_for', + references, + } + ); - return [ - ...nonAgentPolicyReferences, - ...policiesList.map((id) => ({ - id, - name: agentPoliciesIdMap[id]?.name, - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - })), - ]; - }; - - const references = getUpdatedReferences(); - - await savedObjectsClient.update( - packSavedObjectType, - request.params.id, - { - enabled, - name, - description: description || '', - queries: queries && convertPackQueriesToSO(queries), - updated_at: moment().toISOString(), - updated_by: currentUser, - shards: convertShardsToArray(shards), - }, - { - refresh: 'wait_for', - references, + const currentAgentPolicyIds = map( + filter(currentPackSO.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), + 'id' + ); + const updatedPackSO = await savedObjectsClient.get( + packSavedObjectType, + request.params.id + ); + + // @ts-expect-error update types + updatedPackSO.attributes.queries = convertSOQueriesToPack(updatedPackSO.attributes.queries); + + if (enabled == null && !currentPackSO.attributes.enabled) { + return response.ok({ body: { data: updatedPackSO } }); } - ); - - const currentAgentPolicyIds = map( - filter(currentPackSO.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), - 'id' - ); - const updatedPackSO = await savedObjectsClient.get( - packSavedObjectType, - request.params.id - ); - - // @ts-expect-error update types - updatedPackSO.attributes.queries = convertSOQueriesToPack(updatedPackSO.attributes.queries); - - if (enabled == null && !currentPackSO.attributes.enabled) { - return response.ok({ body: { data: updatedPackSO } }); - } - if (enabled != null && enabled !== currentPackSO.attributes.enabled) { - if (enabled) { - const policyIds = policy_ids || !isEmpty(shards) ? policiesList : currentAgentPolicyIds; + if (enabled != null && enabled !== currentPackSO.attributes.enabled) { + if (enabled) { + const policyIds = policy_ids || !isEmpty(shards) ? policiesList : currentAgentPolicyIds; + + await Promise.all( + policyIds.map((agentPolicyId) => { + const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); + + if (packagePolicy) { + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + if (!has(draft, 'inputs[0].streams')) { + set(draft, 'inputs[0].streams', []); + } + + set( + draft, + `inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`, + { + queries: updatedPackSO.attributes.queries, + } + ); + + return draft; + }) + ); + } + }) + ); + } else { + await Promise.all( + currentAgentPolicyIds.map((agentPolicyId) => { + const packagePolicy = find(currentPackagePolicies, ['policy_id', agentPolicyId]); + if (!packagePolicy) return; + + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + unset( + draft, + `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + ); + + return draft; + }) + ); + }) + ); + } + } else { + // TODO double check if policiesList shouldnt be changed into policyIds + const agentPolicyIdsToRemove = uniq(difference(currentAgentPolicyIds, policiesList)); + const agentPolicyIdsToUpdate = uniq( + difference(currentAgentPolicyIds, agentPolicyIdsToRemove) + ); + const agentPolicyIdsToAdd = uniq(difference(policiesList, currentAgentPolicyIds)); await Promise.all( - policyIds.map((agentPolicyId) => { + agentPolicyIdsToRemove.map((agentPolicyId) => { + const packagePolicy = find(currentPackagePolicies, ['policy_id', agentPolicyId]); + if (packagePolicy) { + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + unset( + draft, + `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + ); + + return draft; + }) + ); + } + }) + ); + + await Promise.all( + agentPolicyIdsToUpdate.map((agentPolicyId) => { const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); if (packagePolicy) { @@ -209,15 +302,21 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte packagePolicy.id, produce(packagePolicy, (draft) => { unset(draft, 'id'); - if (!has(draft, 'inputs[0].streams')) { - set(draft, 'inputs[0].streams', []); + if (updatedPackSO.attributes.name !== currentPackSO.attributes.name) { + unset( + draft, + `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + ); } set( draft, `inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`, { - queries: updatedPackSO.attributes.queries, + shard: policyShards[packagePolicy.policy_id] + ? policyShards[packagePolicy.policy_id] + : 100, + queries: convertSOQueriesToPackConfig(updatedPackSO.attributes.queries), } ); @@ -227,149 +326,61 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte } }) ); - } else { - await Promise.all( - currentAgentPolicyIds.map((agentPolicyId) => { - const packagePolicy = find(currentPackagePolicies, ['policy_id', agentPolicyId]); - if (!packagePolicy) return; - - return packagePolicyService?.update( - internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - unset( - draft, - `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` - ); - return draft; - }) - ); - }) - ); - } - } else { - // TODO double check if policiesList shouldnt be changed into policyIds - const agentPolicyIdsToRemove = uniq(difference(currentAgentPolicyIds, policiesList)); - const agentPolicyIdsToUpdate = uniq( - difference(currentAgentPolicyIds, agentPolicyIdsToRemove) - ); - const agentPolicyIdsToAdd = uniq(difference(policiesList, currentAgentPolicyIds)); - - await Promise.all( - agentPolicyIdsToRemove.map((agentPolicyId) => { - const packagePolicy = find(currentPackagePolicies, ['policy_id', agentPolicyId]); - if (packagePolicy) { - return packagePolicyService?.update( - internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - unset( - draft, - `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` - ); + await Promise.all( + agentPolicyIdsToAdd.map((agentPolicyId) => { + const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); - return draft; - }) - ); - } - }) - ); + if (packagePolicy) { + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + if (!(draft.inputs.length && draft.inputs[0].streams.length)) { + set(draft, 'inputs[0].streams', []); + } - await Promise.all( - agentPolicyIdsToUpdate.map((agentPolicyId) => { - const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); - - if (packagePolicy) { - return packagePolicyService?.update( - internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - if (updatedPackSO.attributes.name !== currentPackSO.attributes.name) { - unset( + set( draft, - `inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}` + `inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`, + { + shard: policyShards[packagePolicy.policy_id] + ? policyShards[packagePolicy.policy_id] + : 100, + queries: convertSOQueriesToPackConfig(updatedPackSO.attributes.queries), + } ); - } - - set( - draft, - `inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`, - { - shard: policyShards[packagePolicy.policy_id] - ? policyShards[packagePolicy.policy_id] - : 100, - queries: convertSOQueriesToPackConfig(updatedPackSO.attributes.queries), - } - ); - return draft; - }) - ); - } - }) - ); - - await Promise.all( - agentPolicyIdsToAdd.map((agentPolicyId) => { - const packagePolicy = find(packagePolicies, ['policy_id', agentPolicyId]); - - if (packagePolicy) { - return packagePolicyService?.update( - internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - if (!(draft.inputs.length && draft.inputs[0].streams.length)) { - set(draft, 'inputs[0].streams', []); - } - - set( - draft, - `inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`, - { - shard: policyShards[packagePolicy.policy_id] - ? policyShards[packagePolicy.policy_id] - : 100, - queries: convertSOQueriesToPackConfig(updatedPackSO.attributes.queries), - } - ); + return draft; + }) + ); + } + }) + ); + } - return draft; - }) - ); - } - }) - ); + const { attributes } = updatedPackSO; + + const data: PackResponseData = { + name: attributes.name, + description: attributes.description, + queries: attributes.queries, + version: attributes.version, + enabled: attributes.enabled, + created_at: attributes.created_at, + created_by: attributes.created_by, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + policy_ids: attributes.policy_ids, + shards: attributes.shards, + saved_object_id: updatedPackSO.id, + }; + + return response.ok({ + body: { data }, + }); } - - const { attributes } = updatedPackSO; - - const data: PackResponseData = { - name: attributes.name, - description: attributes.description, - queries: attributes.queries, - version: attributes.version, - enabled: attributes.enabled, - created_at: attributes.created_at, - created_by: attributes.created_by, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - policy_ids: attributes.policy_ids, - shards: attributes.shards, - saved_object_id: updatedPackSO.id, - }; - - return response.ok({ - body: { data }, - }); - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts index 07e5e40ac69fdc..b31da0c0e24da0 100644 --- a/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts +++ b/x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts @@ -6,39 +6,45 @@ */ import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { OSQUERY_INTEGRATION_NAME, PLUGIN_ID } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; export const privilegesCheckRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/privileges_check', - validate: {}, options: { tags: [`access:${PLUGIN_ID}-readLiveQueries`], }, - }, - async (context, request, response) => { - if (osqueryContext.security.authz.mode.useRbacForRequest(request)) { - const checkPrivileges = - osqueryContext.security.authz.checkPrivilegesDynamicallyWithRequest(request); - const { hasAllRequested } = await checkPrivileges({ - elasticsearch: { - cluster: [], - index: { - [`logs-${OSQUERY_INTEGRATION_NAME}.result*`]: ['read'], + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: {}, + }, + async (context, request, response) => { + if (osqueryContext.security.authz.mode.useRbacForRequest(request)) { + const checkPrivileges = + osqueryContext.security.authz.checkPrivilegesDynamicallyWithRequest(request); + const { hasAllRequested } = await checkPrivileges({ + elasticsearch: { + cluster: [], + index: { + [`logs-${OSQUERY_INTEGRATION_NAME}.result*`]: ['read'], + }, }, - }, - }); + }); + + return response.ok({ + body: `${hasAllRequested}`, + }); + } return response.ok({ - body: `${hasAllRequested}`, + body: 'true', }); } - - return response.ok({ - body: 'true', - }); - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts index e7c9c2a462ff8f..8f40dbc28924a8 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts @@ -7,6 +7,7 @@ import { isEmpty, pickBy, some, isBoolean } from 'lodash'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import type { SavedQueryResponse } from './types'; import type { SavedQuerySavedObject } from '../../common/types'; import { PLUGIN_ID } from '../../../common'; @@ -18,97 +19,104 @@ import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { convertECSMappingToArray } from '../utils'; export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.post( - { + router.versioned + .post({ + access: 'public', path: '/api/osquery/saved_queries', - validate: { - body: buildRouteValidation< - typeof createSavedQueryRequestSchema, - CreateSavedQueryRequestSchemaDecoded - >(createSavedQueryRequestSchema), - }, options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + body: buildRouteValidation< + typeof createSavedQueryRequestSchema, + CreateSavedQueryRequestSchemaDecoded + >(createSavedQueryRequestSchema), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - const { - id, - description, - platform, - query, - version, - interval, - snapshot, - removed, - // eslint-disable-next-line @typescript-eslint/naming-convention - ecs_mapping, - } = request.body; + const { + id, + description, + platform, + query, + version, + interval, + snapshot, + removed, + // eslint-disable-next-line @typescript-eslint/naming-convention + ecs_mapping, + } = request.body; - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - const conflictingEntries = await savedObjectsClient.find({ - type: savedQuerySavedObjectType, - filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`, - }); + const conflictingEntries = await savedObjectsClient.find({ + type: savedQuerySavedObjectType, + filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`, + }); - if ( - conflictingEntries.saved_objects.length && - some(conflictingEntries.saved_objects, ['attributes.id', id]) - ) { - return response.conflict({ body: `Saved query with id "${id}" already exists.` }); - } + if ( + conflictingEntries.saved_objects.length && + some(conflictingEntries.saved_objects, ['attributes.id', id]) + ) { + return response.conflict({ body: `Saved query with id "${id}" already exists.` }); + } - const savedQuerySO = await savedObjectsClient.create( - savedQuerySavedObjectType, - pickBy( - { - id, - description, - query, - platform, - version, - interval, - snapshot, - removed, - ecs_mapping: convertECSMappingToArray(ecs_mapping), - created_by: currentUser, - created_at: new Date().toISOString(), - updated_by: currentUser, - updated_at: new Date().toISOString(), - }, - (value) => !isEmpty(value) || isBoolean(value) - ) - ); + const savedQuerySO = await savedObjectsClient.create( + savedQuerySavedObjectType, + pickBy( + { + id, + description, + query, + platform, + version, + interval, + snapshot, + removed, + ecs_mapping: convertECSMappingToArray(ecs_mapping), + created_by: currentUser, + created_at: new Date().toISOString(), + updated_by: currentUser, + updated_at: new Date().toISOString(), + }, + (value) => !isEmpty(value) || isBoolean(value) + ) + ); - const { attributes } = savedQuerySO; + const { attributes } = savedQuerySO; - const data: Partial = pickBy( - { - created_at: attributes.created_at, - created_by: attributes.created_by, - description: attributes.description, - id: attributes.id, - removed: attributes.removed, - snapshot: attributes.snapshot, - version: attributes.version, - interval: attributes.interval, - platform: attributes.platform, - query: attributes.query, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - saved_object_id: savedQuerySO.id, - ecs_mapping, - }, - (value) => !isEmpty(value) - ); + const data: Partial = pickBy( + { + created_at: attributes.created_at, + created_by: attributes.created_by, + description: attributes.description, + id: attributes.id, + removed: attributes.removed, + snapshot: attributes.snapshot, + version: attributes.version, + interval: attributes.interval, + platform: attributes.platform, + query: attributes.query, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + saved_object_id: savedQuerySO.id, + ecs_mapping, + }, + (value) => !isEmpty(value) + ); - return response.ok({ - body: { - data, - }, - }); - } - ); + return response.ok({ + body: { + data, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts index ff025ede421f0f..ccecbf7a66dd90 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts @@ -7,41 +7,49 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { PLUGIN_ID } from '../../../common'; import { savedQuerySavedObjectType } from '../../../common/types'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; import { isSavedQueryPrebuilt } from './utils'; export const deleteSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.delete( - { + router.versioned + .delete({ + access: 'public', path: '/api/osquery/saved_queries/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - }, options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - const isPrebuilt = await isSavedQueryPrebuilt( - osqueryContext.service.getPackageService()?.asInternalUser, - request.params.id - ); - if (isPrebuilt) { - return response.conflict({ body: `Elastic prebuilt Saved query cannot be deleted.` }); - } + const isPrebuilt = await isSavedQueryPrebuilt( + osqueryContext.service.getPackageService()?.asInternalUser, + request.params.id + ); + if (isPrebuilt) { + return response.conflict({ body: `Elastic prebuilt Saved query cannot be deleted.` }); + } - await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, { - refresh: 'wait_for', - }); + await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, { + refresh: 'wait_for', + }); - return response.ok({ - body: {}, - }); - } - ); + return response.ok({ + body: {}, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts index 39fd95fb234789..ad4b151554e4df 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; import { omit } from 'lodash'; +import { API_VERSIONS } from '../../../common/constants'; import type { SavedQueryResponse } from './types'; import type { SavedQuerySavedObject } from '../../common/types'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; @@ -18,96 +19,105 @@ import { convertECSMappingToObject } from '../utils'; import { getInstalledSavedQueriesMap } from './utils'; export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/saved_queries', - validate: { - query: schema.object({ - page: schema.number({ defaultValue: 1 }), - pageSize: schema.maybe(schema.number()), - sort: schema.string({ defaultValue: 'id' }), - sortOrder: schema.oneOf([schema.literal('asc'), schema.literal('desc')], { - defaultValue: 'desc', - }), - }), - }, options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + query: schema.object({ + page: schema.number({ defaultValue: 1 }), + pageSize: schema.maybe(schema.number()), + sort: schema.string({ defaultValue: 'id' }), + sortOrder: schema.oneOf([schema.literal('asc'), schema.literal('desc')], { + defaultValue: 'desc', + }), + }), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - try { - const savedQueries = await savedObjectsClient.find({ - type: savedQuerySavedObjectType, - page: request.query.page, - perPage: request.query.pageSize, - sortField: request.query.sort, - sortOrder: request.query.sortOrder, - }); + try { + const savedQueries = await savedObjectsClient.find({ + type: savedQuerySavedObjectType, + page: request.query.page, + perPage: request.query.pageSize, + sortField: request.query.sort, + sortOrder: request.query.sortOrder, + }); - const prebuiltSavedQueriesMap = await getInstalledSavedQueriesMap( - osqueryContext.service.getPackageService()?.asInternalUser - ); - const savedObjects: SavedQueryResponse[] = savedQueries.saved_objects.map((savedObject) => { - // eslint-disable-next-line @typescript-eslint/naming-convention - const ecs_mapping = savedObject.attributes.ecs_mapping; + const prebuiltSavedQueriesMap = await getInstalledSavedQueriesMap( + osqueryContext.service.getPackageService()?.asInternalUser + ); + const savedObjects: SavedQueryResponse[] = savedQueries.saved_objects.map( + (savedObject) => { + // eslint-disable-next-line @typescript-eslint/naming-convention + const ecs_mapping = savedObject.attributes.ecs_mapping; - savedObject.attributes.prebuilt = !!prebuiltSavedQueriesMap[savedObject.id]; + savedObject.attributes.prebuilt = !!prebuiltSavedQueriesMap[savedObject.id]; - if (ecs_mapping) { - // @ts-expect-error update types - savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping); - } + if (ecs_mapping) { + // @ts-expect-error update types + savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping); + } - const { - created_at: createdAt, - created_by: createdBy, - description, - id, - interval, - platform, - query, - removed, - snapshot, - version, - ecs_mapping: ecsMapping, - updated_at: updatedAt, - updated_by: updatedBy, - prebuilt, - } = savedObject.attributes; + const { + created_at: createdAt, + created_by: createdBy, + description, + id, + interval, + platform, + query, + removed, + snapshot, + version, + ecs_mapping: ecsMapping, + updated_at: updatedAt, + updated_by: updatedBy, + prebuilt, + } = savedObject.attributes; - return { - created_at: createdAt, - created_by: createdBy, - description, - id, - removed, - snapshot, - version, - ecs_mapping: ecsMapping, - interval, - platform, - query, - updated_at: updatedAt, - updated_by: updatedBy, - prebuilt, - saved_object_id: savedObject.id, - }; - }); + return { + created_at: createdAt, + created_by: createdBy, + description, + id, + removed, + snapshot, + version, + ecs_mapping: ecsMapping, + interval, + platform, + query, + updated_at: updatedAt, + updated_by: updatedBy, + prebuilt, + saved_object_id: savedObject.id, + }; + } + ); - return response.ok({ - body: { - ...omit(savedQueries, 'saved_objects'), - data: savedObjects, - }, - }); - } catch (e) { - return response.customError({ - statusCode: e.statusCode || e.output?.statusCode || 500, - body: e, - }); + return response.ok({ + body: { + ...omit(savedQueries, 'saved_objects'), + data: savedObjects, + }, + }); + } catch (e) { + return response.customError({ + statusCode: e.statusCode || e.output?.statusCode || 500, + body: e, + }); + } } - } - ); + ); }; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts index ecaec2f2810a29..81d14e160a1a85 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import type { SavedQueryResponse } from './types'; import type { SavedQuerySavedObject } from '../../common/types'; import { isSavedQueryPrebuilt } from './utils'; @@ -16,77 +17,84 @@ import { savedQuerySavedObjectType } from '../../../common/types'; import { convertECSMappingToObject } from '../utils'; export const readSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'public', path: '/api/osquery/saved_queries/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - }, options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; - - const savedQuery = await savedObjectsClient.get( - savedQuerySavedObjectType, - request.params.id - ); + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; - if (savedQuery.attributes.ecs_mapping) { - // @ts-expect-error update types - savedQuery.attributes.ecs_mapping = convertECSMappingToObject( - savedQuery.attributes.ecs_mapping + const savedQuery = await savedObjectsClient.get( + savedQuerySavedObjectType, + request.params.id ); - } - savedQuery.attributes.prebuilt = await isSavedQueryPrebuilt( - osqueryContext.service.getPackageService()?.asInternalUser, - savedQuery.id - ); + if (savedQuery.attributes.ecs_mapping) { + // @ts-expect-error update types + savedQuery.attributes.ecs_mapping = convertECSMappingToObject( + savedQuery.attributes.ecs_mapping + ); + } - const { - created_at: createdAt, - created_by: createdBy, - description, - id, - interval, - platform, - query, - removed, - snapshot, - version, - ecs_mapping: ecsMapping, - updated_at: updatedAt, - updated_by: updatedBy, - prebuilt, - } = savedQuery.attributes; + savedQuery.attributes.prebuilt = await isSavedQueryPrebuilt( + osqueryContext.service.getPackageService()?.asInternalUser, + savedQuery.id + ); - const data: SavedQueryResponse = { - created_at: createdAt, - created_by: createdBy, - description, - id, - removed, - snapshot, - version, - ecs_mapping: ecsMapping, - interval, - platform, - query, - updated_at: updatedAt, - updated_by: updatedBy, - prebuilt, - saved_object_id: savedQuery.id, - }; + const { + created_at: createdAt, + created_by: createdBy, + description, + id, + interval, + platform, + query, + removed, + snapshot, + version, + ecs_mapping: ecsMapping, + updated_at: updatedAt, + updated_by: updatedBy, + prebuilt, + } = savedQuery.attributes; - return response.ok({ - body: { - data, - }, - }); - } - ); + const data: SavedQueryResponse = { + created_at: createdAt, + created_by: createdBy, + description, + id, + removed, + snapshot, + version, + ecs_mapping: ecsMapping, + interval, + platform, + query, + updated_at: updatedAt, + updated_by: updatedBy, + prebuilt, + saved_object_id: savedQuery.id, + }; + + return response.ok({ + body: { + data, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts index 4cfe3e74295df6..758016830b8925 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts @@ -9,6 +9,7 @@ import { filter, some } from 'lodash'; import { schema } from '@kbn/config-schema'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { isSavedQueryPrebuilt } from './utils'; import { PLUGIN_ID } from '../../../common'; import { savedQuerySavedObjectType } from '../../../common/types'; @@ -17,134 +18,144 @@ import { convertECSMappingToArray, convertECSMappingToObject } from '../utils'; import type { UpdateSavedQueryResponse } from './types'; export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.put( - { + router.versioned + .put({ + access: 'public', path: '/api/osquery/saved_queries/{id}', - validate: { - params: schema.object({ - id: schema.string(), - }), - body: schema.object( - { - id: schema.string(), - query: schema.string(), - description: schema.maybe(schema.string()), - interval: schema.maybe(schema.number()), - snapshot: schema.maybe(schema.boolean()), - removed: schema.maybe(schema.boolean()), - platform: schema.maybe(schema.string()), - version: schema.maybe(schema.string()), - ecs_mapping: schema.maybe( - schema.recordOf( - schema.string(), - schema.object({ - field: schema.maybe(schema.string()), - value: schema.maybe( - schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) - ), - }) - ) + options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: schema.object({ + id: schema.string(), + }), + body: schema.object( + { + id: schema.string(), + query: schema.string(), + description: schema.maybe(schema.string()), + interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), + platform: schema.maybe(schema.string()), + version: schema.maybe(schema.string()), + ecs_mapping: schema.maybe( + schema.recordOf( + schema.string(), + schema.object({ + field: schema.maybe(schema.string()), + value: schema.maybe( + schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) + ), + }) + ) + ), + }, + { unknowns: 'allow' } ), }, - { unknowns: 'allow' } - ), + }, }, - options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const savedObjectsClient = coreContext.savedObjects.client; - const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - - const { - id, - description, - platform, - query, - version, - interval, - snapshot, - removed, - // eslint-disable-next-line @typescript-eslint/naming-convention - ecs_mapping, - } = request.body; - - const isPrebuilt = await isSavedQueryPrebuilt( - osqueryContext.service.getPackageService()?.asInternalUser, - request.params.id - ); - - if (isPrebuilt) { - return response.conflict({ body: `Elastic prebuilt Saved query cannot be updated.` }); - } - - const conflictingEntries = await savedObjectsClient.find<{ id: string }>({ - type: savedQuerySavedObjectType, - filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`, - }); - - if ( - some( - filter(conflictingEntries.saved_objects, (soObject) => soObject.id !== request.params.id), - ['attributes.id', id] - ) - ) { - return response.conflict({ body: `Saved query with id "${id}" already exists.` }); - } + async (context, request, response) => { + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; + const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; - const updatedSavedQuerySO = await savedObjectsClient.update( - savedQuerySavedObjectType, - request.params.id, - { + const { id, - description: description || '', + description, platform, query, version, interval, snapshot, removed, - ecs_mapping: convertECSMappingToArray(ecs_mapping), - updated_by: currentUser, - updated_at: new Date().toISOString(), - }, - { - refresh: 'wait_for', + // eslint-disable-next-line @typescript-eslint/naming-convention + ecs_mapping, + } = request.body; + + const isPrebuilt = await isSavedQueryPrebuilt( + osqueryContext.service.getPackageService()?.asInternalUser, + request.params.id + ); + + if (isPrebuilt) { + return response.conflict({ body: `Elastic prebuilt Saved query cannot be updated.` }); } - ); - if (ecs_mapping || updatedSavedQuerySO.attributes.ecs_mapping) { - // @ts-expect-error update types - updatedSavedQuerySO.attributes.ecs_mapping = - ecs_mapping || - (updatedSavedQuerySO.attributes.ecs_mapping && - // @ts-expect-error update types - convertECSMappingToObject(updatedSavedQuerySO.attributes.ecs_mapping)) || - {}; - } + const conflictingEntries = await savedObjectsClient.find<{ id: string }>({ + type: savedQuerySavedObjectType, + filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`, + }); - const { attributes } = updatedSavedQuerySO; + if ( + some( + filter( + conflictingEntries.saved_objects, + (soObject) => soObject.id !== request.params.id + ), + ['attributes.id', id] + ) + ) { + return response.conflict({ body: `Saved query with id "${id}" already exists.` }); + } - const data: Partial = { - description: attributes.description, - id: attributes.id, - removed: attributes.removed, - snapshot: attributes.snapshot, - version: attributes.version, - ecs_mapping: attributes.ecs_mapping, - interval: attributes.interval, - platform: attributes.platform, - query: attributes.query, - updated_at: attributes.updated_at, - updated_by: attributes.updated_by, - saved_object_id: updatedSavedQuerySO.id, - }; + const updatedSavedQuerySO = await savedObjectsClient.update( + savedQuerySavedObjectType, + request.params.id, + { + id, + description: description || '', + platform, + query, + version, + interval, + snapshot, + removed, + ecs_mapping: convertECSMappingToArray(ecs_mapping), + updated_by: currentUser, + updated_at: new Date().toISOString(), + }, + { + refresh: 'wait_for', + } + ); - return response.ok({ - body: { - data, - }, - }); - } - ); + if (ecs_mapping || updatedSavedQuerySO.attributes.ecs_mapping) { + // @ts-expect-error update types + updatedSavedQuerySO.attributes.ecs_mapping = + ecs_mapping || + (updatedSavedQuerySO.attributes.ecs_mapping && + // @ts-expect-error update types + convertECSMappingToObject(updatedSavedQuerySO.attributes.ecs_mapping)) || + {}; + } + + const { attributes } = updatedSavedQuerySO; + + const data: Partial = { + description: attributes.description, + id: attributes.id, + removed: attributes.removed, + snapshot: attributes.snapshot, + version: attributes.version, + ecs_mapping: attributes.ecs_mapping, + interval: attributes.interval, + platform: attributes.platform, + query: attributes.query, + updated_at: attributes.updated_at, + updated_by: attributes.updated_by, + saved_object_id: updatedSavedQuerySO.id, + }; + + return response.ok({ + body: { + data, + }, + }); + } + ); }; diff --git a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts index 785b9540e173ff..2bab8d82bbab8b 100644 --- a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts @@ -15,6 +15,7 @@ import { AGENT_POLICY_SAVED_OBJECT_TYPE, } from '@kbn/fleet-plugin/common'; import type { IRouter } from '@kbn/core/server'; +import { API_VERSIONS } from '../../../common/constants'; import { packSavedObjectType } from '../../../common/types'; import { PLUGIN_ID, OSQUERY_INTEGRATION_NAME } from '../../../common'; import type { OsqueryAppContext } from '../../lib/osquery_app_context_services'; @@ -22,183 +23,188 @@ import { convertPackQueriesToSO } from '../pack/utils'; import { getInternalSavedObjectsClient } from '../utils'; export const createStatusRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => { - router.get( - { + router.versioned + .get({ + access: 'internal', path: '/internal/osquery/status', - validate: false, options: { tags: [`access:${PLUGIN_ID}-read`] }, - }, - async (context, request, response) => { - const coreContext = await context.core; - const esClient = coreContext.elasticsearch.client.asInternalUser; - const internalSavedObjectsClient = await getInternalSavedObjectsClient( - osqueryContext.getStartServices - ); - const packageService = osqueryContext.service.getPackageService()?.asInternalUser; - const packagePolicyService = osqueryContext.service.getPackagePolicyService(); - const agentPolicyService = osqueryContext.service.getAgentPolicyService(); - - const packageInfo = await packageService?.getInstallation(OSQUERY_INTEGRATION_NAME); - - if (packageInfo?.install_version && satisfies(packageInfo?.install_version, '<0.6.0')) { - try { - const policyPackages = await packagePolicyService?.list(internalSavedObjectsClient, { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, - perPage: 10000, - page: 1, - }); - - const migrationObject = reduce( - policyPackages?.items, - (acc, policy) => { - if (acc.agentPolicyToPackage[policy.policy_id]) { - acc.packagePoliciesToDelete.push(policy.id); - } else { - acc.agentPolicyToPackage[policy.policy_id] = policy.id; - } - - const packagePolicyName = policy.name; - const currentOsqueryManagerNamePacksCount = filter( - Object.keys(acc.packs), - (packName) => packName.startsWith(OSQUERY_INTEGRATION_NAME) - ).length; - - const packName = packagePolicyName.startsWith(OSQUERY_INTEGRATION_NAME) - ? `osquery_manager-1_${currentOsqueryManagerNamePacksCount + 1}` - : packagePolicyName; - - if (has(policy, 'inputs[0].streams[0]')) { - if (!acc.packs[packName]) { - acc.packs[packName] = { - policy_ids: [policy.policy_id], - enabled: !packName.startsWith(OSQUERY_INTEGRATION_NAME), - name: packName, - description: policy.description, - queries: reduce>( - policy.inputs[0].streams, - (queries, stream) => { - if (stream.compiled_stream?.id) { - const { id: queryId, ...query } = stream.compiled_stream; - queries[queryId] = query; - } - - return queries; - }, - {} - ), - }; + }) + .addVersion( + { + version: API_VERSIONS.internal.v1, + validate: false, + }, + async (context, request, response) => { + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const internalSavedObjectsClient = await getInternalSavedObjectsClient( + osqueryContext.getStartServices + ); + const packageService = osqueryContext.service.getPackageService()?.asInternalUser; + const packagePolicyService = osqueryContext.service.getPackagePolicyService(); + const agentPolicyService = osqueryContext.service.getAgentPolicyService(); + + const packageInfo = await packageService?.getInstallation(OSQUERY_INTEGRATION_NAME); + + if (packageInfo?.install_version && satisfies(packageInfo?.install_version, '<0.6.0')) { + try { + const policyPackages = await packagePolicyService?.list(internalSavedObjectsClient, { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`, + perPage: 10000, + page: 1, + }); + + const migrationObject = reduce( + policyPackages?.items, + (acc, policy) => { + if (acc.agentPolicyToPackage[policy.policy_id]) { + acc.packagePoliciesToDelete.push(policy.id); } else { - acc.packs[packName].policy_ids.push(policy.policy_id); + acc.agentPolicyToPackage[policy.policy_id] = policy.id; } - } - return acc; - }, - { - packs: {} as Record< - string, - { - policy_ids: string[]; - enabled: boolean; - name: string; - description?: string; - queries: Record; + const packagePolicyName = policy.name; + const currentOsqueryManagerNamePacksCount = filter( + Object.keys(acc.packs), + (packName) => packName.startsWith(OSQUERY_INTEGRATION_NAME) + ).length; + + const packName = packagePolicyName.startsWith(OSQUERY_INTEGRATION_NAME) + ? `osquery_manager-1_${currentOsqueryManagerNamePacksCount + 1}` + : packagePolicyName; + + if (has(policy, 'inputs[0].streams[0]')) { + if (!acc.packs[packName]) { + acc.packs[packName] = { + policy_ids: [policy.policy_id], + enabled: !packName.startsWith(OSQUERY_INTEGRATION_NAME), + name: packName, + description: policy.description, + queries: reduce>( + policy.inputs[0].streams, + (queries, stream) => { + if (stream.compiled_stream?.id) { + const { id: queryId, ...query } = stream.compiled_stream; + queries[queryId] = query; + } + + return queries; + }, + {} + ), + }; + } else { + acc.packs[packName].policy_ids.push(policy.policy_id); + } } - >, - agentPolicyToPackage: {} as Record, - packagePoliciesToDelete: [] as string[], - } - ); - - await packageService?.ensureInstalledPackage({ - pkgName: OSQUERY_INTEGRATION_NAME, - }); - - const agentPolicyIds = uniq(map(policyPackages?.items, 'policy_id')); - const agentPolicies = mapKeys( - await agentPolicyService?.getByIds(internalSavedObjectsClient, agentPolicyIds), - 'id' - ); - - await Promise.all( - map(migrationObject.packs, async (packObject) => { - await internalSavedObjectsClient.create( - packSavedObjectType, - { - name: packObject.name, - description: packObject.description, - queries: convertPackQueriesToSO(packObject.queries), - enabled: packObject.enabled, - created_at: new Date().toISOString(), - created_by: 'system', - updated_at: new Date().toISOString(), - updated_by: 'system', - }, - { - references: packObject.policy_ids.map((policyId: string) => ({ - id: policyId, - name: agentPolicies[policyId].name, - type: AGENT_POLICY_SAVED_OBJECT_TYPE, - })), - refresh: 'wait_for', - } - ); - }) - ); - - // delete unnecessary package policies - await packagePolicyService?.delete( - internalSavedObjectsClient, - esClient, - migrationObject.packagePoliciesToDelete - ); - - // updatePackagePolicies - await Promise.all( - map(migrationObject.agentPolicyToPackage, async (value, key) => { - const agentPacks = filter(migrationObject.packs, (pack) => - pack.policy_ids.includes(key) - ); - await packagePolicyService?.upgrade(internalSavedObjectsClient, esClient, [value]); - const packagePolicy = await packagePolicyService?.get( - internalSavedObjectsClient, - value - ); - - if (packagePolicy) { - return packagePolicyService?.update( + + return acc; + }, + { + packs: {} as Record< + string, + { + policy_ids: string[]; + enabled: boolean; + name: string; + description?: string; + queries: Record; + } + >, + agentPolicyToPackage: {} as Record, + packagePoliciesToDelete: [] as string[], + } + ); + + await packageService?.ensureInstalledPackage({ + pkgName: OSQUERY_INTEGRATION_NAME, + }); + + const agentPolicyIds = uniq(map(policyPackages?.items, 'policy_id')); + const agentPolicies = mapKeys( + await agentPolicyService?.getByIds(internalSavedObjectsClient, agentPolicyIds), + 'id' + ); + + await Promise.all( + map(migrationObject.packs, async (packObject) => { + await internalSavedObjectsClient.create( + packSavedObjectType, + { + name: packObject.name, + description: packObject.description, + queries: convertPackQueriesToSO(packObject.queries), + enabled: packObject.enabled, + created_at: new Date().toISOString(), + created_by: 'system', + updated_at: new Date().toISOString(), + updated_by: 'system', + }, + { + references: packObject.policy_ids.map((policyId: string) => ({ + id: policyId, + name: agentPolicies[policyId].name, + type: AGENT_POLICY_SAVED_OBJECT_TYPE, + })), + refresh: 'wait_for', + } + ); + }) + ); + + // delete unnecessary package policies + await packagePolicyService?.delete( + internalSavedObjectsClient, + esClient, + migrationObject.packagePoliciesToDelete + ); + + // updatePackagePolicies + await Promise.all( + map(migrationObject.agentPolicyToPackage, async (value, key) => { + const agentPacks = filter(migrationObject.packs, (pack) => + pack.policy_ids.includes(key) + ); + await packagePolicyService?.upgrade(internalSavedObjectsClient, esClient, [value]); + const packagePolicy = await packagePolicyService?.get( internalSavedObjectsClient, - esClient, - packagePolicy.id, - produce(packagePolicy, (draft) => { - unset(draft, 'id'); - - set(draft, 'name', 'osquery_manager-1'); - - set(draft, 'inputs[0]', { - enabled: true, - policy_template: OSQUERY_INTEGRATION_NAME, - streams: [], - type: 'osquery', - }); - - each(agentPacks, (agentPack) => { - set(draft, `inputs[0].config.osquery.value.packs.${agentPack.name}`, { - queries: agentPack.queries, + value + ); + + if (packagePolicy) { + return packagePolicyService?.update( + internalSavedObjectsClient, + esClient, + packagePolicy.id, + produce(packagePolicy, (draft) => { + unset(draft, 'id'); + + set(draft, 'name', 'osquery_manager-1'); + + set(draft, 'inputs[0]', { + enabled: true, + policy_template: OSQUERY_INTEGRATION_NAME, + streams: [], + type: 'osquery', }); - }); - return draft; - }) - ); - } - }) - ); - // eslint-disable-next-line no-empty - } catch (e) {} - } + each(agentPacks, (agentPack) => { + set(draft, `inputs[0].config.osquery.value.packs.${agentPack.name}`, { + queries: agentPack.queries, + }); + }); + + return draft; + }) + ); + } + }) + ); + // eslint-disable-next-line no-empty + } catch (e) {} + } - return response.ok({ body: packageInfo }); - } - ); + return response.ok({ body: packageInfo }); + } + ); }; From 6c710308b55a390cdf0dadc4e0bda405bd5ab9ba Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Sun, 2 Jul 2023 01:02:54 -0400 Subject: [PATCH 06/98] [api-docs] 2023-07-02 Daily api_docs build (#161053) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/386 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.devdocs.json | 8 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/ess_security.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...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.devdocs.json | 192 +++++++++--------- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../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 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.devdocs.json | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.devdocs.json | 5 +- api_docs/ml.mdx | 4 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 6 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 546 files changed, 652 insertions(+), 645 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 06c63a8c971e26..7495f6549384dd 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-01 +date: 2023-07-02 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 c6d7d26c63e1cb..dc853d731e9e52 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 6ecac7bcaea236..d6a9026e219a59 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-01 +date: 2023-07-02 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 4af04d872e2394..7ff7553f0d3bb7 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index add26e70b0bfc4..7731ac7692b966 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -782,7 +782,13 @@ "text": "HomeServerPluginStart" }, ">; } | undefined; ml?: { setup: ", - "SharedServices", + { + "pluginId": "ml", + "scope": "server", + "docId": "kibMlPluginApi", + "section": "def-server.MlPluginSetup", + "text": "MlPluginSetup" + }, "; start: () => Promise; } | undefined; security?: { setup: ", { "pluginId": "security", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 37ac435398734e..f54567ba169ce2 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index aa931db319a6c3..f7b7969b78cace 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-01 +date: 2023-07-02 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 0123b23518fff1..88613273787258 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-01 +date: 2023-07-02 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 e174bfa09b8e89..f4602ae4d72da2 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-01 +date: 2023-07-02 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 0ffbd670d9015d..7f1cb5168e4464 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-01 +date: 2023-07-02 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 e6a9241261ae22..5ba704f858c2d9 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-01 +date: 2023-07-02 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 8a92de2f2759e0..91573e22d3ad4e 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-01 +date: 2023-07-02 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 1e7ffe0d05f197..8ff6937987f37d 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index eeec8c7620b042..7b376c5af18b1c 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 97f0420608ec91..9f7cf371be3f19 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 3816605ce1bef0..9564697177789e 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-01 +date: 2023-07-02 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 072abbe09deeb8..6923a13e25de05 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-01 +date: 2023-07-02 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 077e6a1ec85258..569f7f3d96d941 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-01 +date: 2023-07-02 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 42f4bfbf226dd2..07dfbda1579b84 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-01 +date: 2023-07-02 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 9cce614a030661..89dc9449be7638 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-01 +date: 2023-07-02 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 e813c7511e6eb1..134cb7a2edb59f 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 fadd1e1348bb23..e872ae550ddfd5 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-01 +date: 2023-07-02 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 2cbf1b7f35cc98..eb17fa9bf0b331 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-01 +date: 2023-07-02 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 d03dbee720c0f6..f05fb3109c15c0 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-01 +date: 2023-07-02 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 6e92d23d8d236f..0b0dc59e6e9c29 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-01 +date: 2023-07-02 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 37d2cc897faeed..971a36c65f4965 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-01 +date: 2023-07-02 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 91bafcbb7bec41..3f1a06f3db33d1 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-01 +date: 2023-07-02 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 2d05f5867f6e02..b7371765bfb130 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-01 +date: 2023-07-02 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 4631d427203bbc..5a41ce8e07963a 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-01 +date: 2023-07-02 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 0681e67455300d..d53b1d8c56d6a0 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-01 +date: 2023-07-02 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 eea4362f80dc3d..2d93f5964633a0 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 533b3932c76679..8d407f32668263 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-01 +date: 2023-07-02 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 69bf17c8f45824..c08433a98e6e6c 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index f3cc6dbcdc2af3..0c4a7343886654 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index bd42999b8bb391..a0ac678a2b8b3c 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 261808e397ef05..f83a32c85534cd 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 2b430ebfc1bae0..f222a06e7b8b15 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-01 +date: 2023-07-02 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 9784bf7b83c719..ee39db5a8971c7 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-01 +date: 2023-07-02 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 f99a9214582d7c..2854104d7daf49 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-01 +date: 2023-07-02 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 aae1a53406e64a..344517279f5c81 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 237172dcfa41f1..fd5e41f0cd1cc0 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-01 +date: 2023-07-02 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 516bb43480f2a6..5a234662ebaa3c 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-01 +date: 2023-07-02 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 69dd9145dc9a2f..93553d3540bda7 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-01 +date: 2023-07-02 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 bd8f0ede8bd7c6..944b679ce2371d 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-01 +date: 2023-07-02 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 09fa5cc06c6f65..d4692dac007e2a 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 8577b01233fb3e..30c5e5a89292d8 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index bde82301dcc6d0..be30767c1c0c6a 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 2a3df496eafcf5..4f73018b05448c 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-01 +date: 2023-07-02 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 b7b6099efa62b9..4f0d0c7dc92ade 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-01 +date: 2023-07-02 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 8ed4d17443c564..ae2b01da09a6f8 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-01 +date: 2023-07-02 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 7e6a06f626ecaa..7f8b70370f675e 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-01 +date: 2023-07-02 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 34f08c006711b0..1109acc5c97754 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-01 +date: 2023-07-02 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 7f87e4fda94954..f4a06838802112 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-01 +date: 2023-07-02 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 4b526292a9213e..50feb23fdc5910 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-01 +date: 2023-07-02 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 82e89d4c0c092a..6b8406335f1491 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-01 +date: 2023-07-02 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 ba3603fab4fa52..24e85b78eff0e0 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-01 +date: 2023-07-02 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 e5429937e2485d..2245453b68675d 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-01 +date: 2023-07-02 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 d95270262d9545..01083efdef1a5c 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-01 +date: 2023-07-02 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 a019b70928a03a..1e996faee26b68 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-01 +date: 2023-07-02 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 2caec4f4ca51d6..177421eaa404b1 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-01 +date: 2023-07-02 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 ea2bfa46792d98..0cd8228bceac5d 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-01 +date: 2023-07-02 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 5909216b9cfbf1..54a2b593c29634 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-01 +date: 2023-07-02 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 8085fe47d034e4..3f3e98d77c1873 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-01 +date: 2023-07-02 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 6513d046fadcf2..0bf8d6cfd7c3d5 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-01 +date: 2023-07-02 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 d7b0f942c6de20..16f71d15eb8854 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-01 +date: 2023-07-02 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 9389f24e97ccc7..87ccbe8f9a6fcd 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-01 +date: 2023-07-02 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 9a52c4cbdff2f6..aaeabafa5f97f3 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-01 +date: 2023-07-02 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 7e4330582ece45..da21fd6a637126 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 ed61b04e05a384..1fe82ac22cfb07 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-01 +date: 2023-07-02 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 834c8f25531a49..62abbd488152d6 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-01 +date: 2023-07-02 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 27ba62f7037dc1..a337aae1515d05 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-01 +date: 2023-07-02 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 c88c52fa2468cb..5bdfa4b7e16e2b 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-01 +date: 2023-07-02 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 2afbcab16f41a0..014e0c553b7fa2 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-01 +date: 2023-07-02 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 e8eb7427670671..e84965edc7e2db 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 cc1c3805f7f955..6faa6f8362d321 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 35456b77cccdd6..eeb888dffa283c 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 5fc344716d6ea9..90ca11afa59ae7 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-01 +date: 2023-07-02 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 15d235dcae78ee..9cbe6a8d8e44d7 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-01 +date: 2023-07-02 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 965fb6558c4ee8..7a1e28fdc7a279 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 20bce145bd15d1..263fca4c8c0f34 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-01 +date: 2023-07-02 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 cd446b3cc5368a..1a9c1ad7e28181 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 35cdf41d7371b3..7b74dabdaefcae 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 722291a196303a..1dd2128c797ba7 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 84dad5db99bc53..3630e3e0b13a06 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-01 +date: 2023-07-02 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 65dedf5271500d..07ff395d2ff301 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-01 +date: 2023-07-02 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 087b1f64302d6c..8d0147efd20693 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index eb575a7303ea25..75076f9204a1cb 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 55c8403918918d..f7b6a0c9885516 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-01 +date: 2023-07-02 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 e24218328119d8..41a697adbbb901 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-01 +date: 2023-07-02 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 a1820cf184fd16..2b45cb05b8a4bb 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index c098c30d40e6f4..13fba0d801201f 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index a0406b2cb9a631..699477ae4f8e03 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-01 +date: 2023-07-02 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 c93053e2337e6d..ce332d13f697ed 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-01 +date: 2023-07-02 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 dccbd6d70f6ab8..6afe5416b93036 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-01 +date: 2023-07-02 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 061e9d19ea5a48..4fee9bd86e998e 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 9b84e7c15b0ea9..88ab5b753e3fa8 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 74349c25f4c361..a504e2ffc4e864 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-01 +date: 2023-07-02 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 a7639c73f45498..3a901e7406b11c 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-01 +date: 2023-07-02 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 8e04f5febc8ed8..4d3f5f2fb1f385 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-01 +date: 2023-07-02 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 161b4de98ccd3a..660cc266fd0b95 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-01 +date: 2023-07-02 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 9eb6321ce39286..f242020b573640 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-01 +date: 2023-07-02 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 9772ad1fd78f79..0a8c9ce907f61c 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-01 +date: 2023-07-02 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 367a6b85328fa3..f4a9b795196b16 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-01 +date: 2023-07-02 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 bb4ea84bea7c80..00613d712922b3 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-01 +date: 2023-07-02 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 76d7b5bc026e93..084b7e805ac672 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 5e6056b43a6c49..af5b0709407ce2 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 5abd935b63062b..72eaadfacc7540 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-01 +date: 2023-07-02 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 9123b8f8ce7fc4..964e4d2a4bf0e3 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-01 +date: 2023-07-02 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 7efea03d18f2eb..00abbce9ad30f0 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 11d07d7ad553e9..67b98613731e46 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-01 +date: 2023-07-02 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 8c8263f8643ebb..c5eea73b21dcc3 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-01 +date: 2023-07-02 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 dc2fbbd422a9b7..88c05b38619296 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-01 +date: 2023-07-02 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 76001ca2d5509b..076c0e9a7e739d 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 5d86eb8efd1bb0..0a61e52c26a7af 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-01 +date: 2023-07-02 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 bb210a21276c13..f5f79efbb59082 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 34150bc49e1c1f..aa58aa852e4882 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 1c02569c26d927..26e577088c3533 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 4c6c943d247b64..9348f53ef8a12c 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 6584f83892231b..14c069328b0f9d 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-01 +date: 2023-07-02 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 cf1df4a50f6972..ff17a019c49b43 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 ad50dbe580f7d5..452892e9a5c8b3 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 5517f3b95e92da..3580aa3b020e99 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 673b705af68705..1b77905ac2e0f3 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 a4498502822f79..0ae709e997b732 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 48c0f559c575f6..353dcfd6609fd9 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-01 +date: 2023-07-02 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 d6becbd96821a8..fd88bd145cf9d6 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 dd72ba1615c106..3506ea1a6e4b84 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 e0e5f64b773390..3362c17499aeb5 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 285d6e59a0bb2e..3087dcbb48240e 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 02db0a935e8cbd..e8112968229bb4 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-01 +date: 2023-07-02 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 0839bcacd4d101..09e07908991f30 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 7fbee73954fa21..f6cc31585f805a 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 431b353bd4000e..c956f2d1d16a18 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 88fd69febeb623..6be358ab68f9eb 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-01 +date: 2023-07-02 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 2415ecf9db7565..9839c24a3b667f 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-01 +date: 2023-07-02 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 f40fc3e1dc0b8a..4595c6143305bb 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 a54869dad417d4..2308b943b244ca 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 f79f870e9cae62..7ef63aa5edb5da 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 176e96ae00c66a..74b0ba4ca2b25f 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 5c2eedb83c3889..1cee7132a65e95 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 9cc30b7ee6941c..1f940b178f963e 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 0c1c964a700f30..18d6e4820d6446 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 2fa50712a44937..711d9a1bcdb206 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-01 +date: 2023-07-02 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 7f43fe91bc3a04..9a1c58533ee751 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-01 +date: 2023-07-02 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 dc232f748612cd..41c9d7fff9afd8 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 aed66c612e6d2f..444bd7d872801c 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 aa984e1f77cd1a..ec550ca9ed6689 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 1b664b4d9eb7c9..bf2858726e004d 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 ffa08a48efb781..2638bd26282ac6 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 7597d906d36c5f..0fed9318f29e92 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-01 +date: 2023-07-02 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 222e5308a34d6b..06abb4f64a731f 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-01 +date: 2023-07-02 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 538757036af87a..fcd9c6e8284197 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 bdba34782c752a..eef222519f7d86 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 6cd962bcb0c63d..cda1aa9e4ca3cb 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 9c54bbd8da94c7..8fef4e8e6b6c4a 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 93195e54f67650..71a843bb5de9e8 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-01 +date: 2023-07-02 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 70b3f703355bfe..be282aeda65cee 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 ceb6eabdfd911e..0934340e352da2 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 56db9ab357dcf4..3ca3532ead5344 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 3e43aab5895192..38412577f7f2e2 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-01 +date: 2023-07-02 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 9d174e26a16f79..3133db18a475c2 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 957ae12e27c2cd..7fcacafa444ba8 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 9def52d5d31306..9f3095e80037b5 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 640d9382efb011..930d91f5cf67c2 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 e1568c5f0f0fac..8b8a90d770f85a 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 48b7c375bef4fa..dd9a0c2b7bbdfd 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 c4842434dc45bf..83b1a06040d560 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 b031df83beed9c..2c7d7c1baf3d6b 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-01 +date: 2023-07-02 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 13451b79366c2a..35823a54f83648 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-01 +date: 2023-07-02 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 18d85afc81be59..7caac93bcb45ea 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 9caca36c4673b1..2209923ae7eb13 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 4f0c4d626c11a5..e407f301c7bea2 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 f88999fa831513..ed9e3a44565bab 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 f40d2286787084..11b6016f168c81 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 dee354ca07e8b3..fef5570a07f822 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 6e8d24f2423b8b..f7ca46498e0a8a 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 d67c75668cdc93..478185a196e730 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-01 +date: 2023-07-02 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 0c3ebe8b2e3584..fd9ab7ef0d11eb 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 125f06f0fd5446..38c68ace2536b0 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-01 +date: 2023-07-02 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 06ed029830dc8f..c3083945e2313c 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-01 +date: 2023-07-02 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 00b4b2462966c7..9ed5605b743323 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 e796110feb5399..9020bbca83bed2 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 97a25e0d010bd8..2e720b804cacba 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 ec68fbe43e2939..1b570da76ae0ae 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 7a33a89311b4e9..c50ace5947aeff 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -4295,70 +4295,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts" }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/status/create_status_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts" @@ -7057,22 +6993,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts" }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts" @@ -8895,14 +8815,6 @@ "plugin": "lists", "path": "x-pack/plugins/lists/server/routes/update_list_route.ts" }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts" @@ -9983,14 +9895,6 @@ "plugin": "lists", "path": "x-pack/plugins/lists/server/routes/delete_list_route.ts" }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts" - }, - { - "plugin": "osquery", - "path": "x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts" @@ -14138,6 +14042,70 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts" }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/live_query/get_live_query_details_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/live_query/get_live_query_results_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/live_query/find_live_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/status/create_status_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policies.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_policy.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_status_for_agent_policy.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_package_policies.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agents.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/fleet_wrapper/get_agent_details.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/privileges_check/privileges_check_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts" @@ -14538,6 +14506,14 @@ "plugin": "canvas", "path": "x-pack/plugins/canvas/server/routes/workpad/update.ts" }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts" + }, { "plugin": "transform", "path": "x-pack/plugins/transform/server/routes/api/transforms.ts" @@ -15018,6 +14994,22 @@ "plugin": "canvas", "path": "x-pack/plugins/canvas/server/routes/workpad/import.ts" }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/live_query/create_live_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts" + }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts" @@ -15386,6 +15378,14 @@ "plugin": "canvas", "path": "x-pack/plugins/canvas/server/routes/workpad/delete.ts" }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts" + }, { "plugin": "maps", "path": "x-pack/plugins/maps/server/data_indexing/indexing_routes.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 8218462ac370a4..870811d210f5fa 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-01 +date: 2023-07-02 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 5e0a5229c1b1ba..8ef80911634942 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 6042ae34b1ae4e..29142784460bae 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 819bf5b277a4f9..97520c0940b91f 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 a9a71970248929..df298eab3dbc5d 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 50bdbd095679d5..4a4c89dc112913 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-01 +date: 2023-07-02 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 1d5450bdddc08a..28f9543821f46e 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 9f3e591f4ee302..4ed13f90602ec7 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 fbc3e018431917..f3f43c40c64d0b 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 412a9c93621a94..9335424a860bff 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 90c707717e68c2..aaf7f13c5816c5 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 1755befbdafd4b..9b12db241c884a 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 cad40a226bbe07..33022604b1c453 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 25430eb395c9a3..0f9ca0fe8efd8d 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-01 +date: 2023-07-02 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 3d117adba5b8c6..7ba047e926db88 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 7482a36344757d..be1c5f7cf5fc16 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 5ed240b9de7d09..89cde493271506 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 64d1a5c58e5174..f5c7ac871ff1c5 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-01 +date: 2023-07-02 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 e6fa7b12326604..1f5cf853c461be 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 94572b7231d43e..4e979c7494c71e 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 8938c2216ad38a..ddee499cd43bde 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 703c7e2c1331bc..b2deb2a970e01d 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 3f69c05a08085b..936a4ea8cf9776 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-01 +date: 2023-07-02 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 ffc6867a386e1f..fef3ef31fd2934 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 74ecd4d1e91ed1..11e3c75cbbd058 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 f24a224536f8b8..ef818a7f133aa7 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 0f8469d060ceb2..eaab8ffd758c94 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-01 +date: 2023-07-02 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 3ef94f1e951057..c9f9be77f5b0d0 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 cfa981f8e33dfe..2b71cf785ea158 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 405825fe22cb92..3cd835763847b0 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 7857f3a4bf705a..8a69370daab739 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 9a09e07f9f89fe..fc4e9f8058653c 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 1e9517c476f3ca..d9db22f1b4f305 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 3fb3ede439430e..06433f9e611211 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 db2e3278691a22..37ee78c036e47d 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 98cdfca257b602..d260227d197f74 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 11b58536e16a27..c57681a85da19d 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index ca38adb5d0b9e8..c2ae1953fe8172 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-01 +date: 2023-07-02 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 9c97b413193214..a74aed12bfeae2 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 391e24d7133007..205f708d743cb2 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-01 +date: 2023-07-02 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 7219dc56c2f8ea..b29d47d35dc460 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 57d8bc1f80ab56..29ea6ecaef31ec 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 53b89a11bb10a5..26727f813fc84a 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 c118721af4c54d..daa38c765b1f3e 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 efa074188a66f4..8e44c1c81370e0 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 af549e9f5538e8..671c8785a4e4e6 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 460d8bdda3dfa1..00a655c59331fa 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-01 +date: 2023-07-02 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 6490a50ad91e7a..d4ed882b342775 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 57bd092ce6cdd4..b4123aad5eb3d9 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 56f877a8f46870..3d7d2128151c5c 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 cbfbdf2a6ef386..77d530c1af507e 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 ebbd58eb20b854..238012e0457b51 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 0b5debaa947ee1..898dec5f600f14 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 1491e5d3d60e5d..4c0a0e56fd4476 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-01 +date: 2023-07-02 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 100e22633553b6..c45aebe74e483f 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 bf100b41170362..1bb1651f1ad206 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 04170c694d3a71..2c76b360211276 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 36da373f97bb06..86ad14cb7ca41d 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 e22e39d5954d2e..03ac52ad11d173 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-01 +date: 2023-07-02 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 17725c68d14bd9..88e7dca6b2bcac 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 c756087ce49f24..2e265ecb1dd55a 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 732f885b553766..88d1d72f234bc0 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-01 +date: 2023-07-02 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 4fdadc5c7f8d8d..15afa945cb7517 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-01 +date: 2023-07-02 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 816e447f68da3c..3a76d546f27812 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 8cd89a8208a48b..f2bfca2d737f58 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-01 +date: 2023-07-02 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 637236edb4b63d..a86432d832f9e6 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 d08251261cb739..c1e4bdd6e3b72f 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 a718c5bd3f4f89..9d7f6d00d8408c 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-01 +date: 2023-07-02 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 feba5441145fb7..7630cc8ff39451 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 c19c3e7aad6918..1033d2f08e1670 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 10666ef670d7bf..29c8a1b09be30b 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-01 +date: 2023-07-02 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 a714ad7ef5fd6b..db29925453cb13 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 ec3b19a6dc0a1c..e56f4d80e28c38 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 4b01960f63c4ea..4e934f25665249 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 6d36bb8fa411db..f54940cc66db74 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 5f03c7bf614044..11a95a79b67f1a 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 5f9b226846e85d..87b51ebe1268fa 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 5862e5479682bf..8d6e6886629303 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 33624373d7365f..b61afdc9b4cf88 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-01 +date: 2023-07-02 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 193e734bb811a0..64ffb7ed184151 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-01 +date: 2023-07-02 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 3b459a4845f40c..7ad93a87b5dc6f 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 522c3b7de87072..1229a7d07a1b7a 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 8c70bb798947be..b8ecbfa593ddf7 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-01 +date: 2023-07-02 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 9810be226d58b0..8fe7b61733f673 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 c42a120b4099bf..ec74084879928d 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 5ad14647fdb4c2..f72402bdc94d7d 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-01 +date: 2023-07-02 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 375fe8cac8cd60..04c30cf95236e3 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-01 +date: 2023-07-02 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 afabebf91aaf0a..109511c5f7bd9f 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 2a497ed3fdec01..a138e2197be65f 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-01 +date: 2023-07-02 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 3ac6fa9aa045f6..b41f0f433cea92 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 42f1f813b06477..645416b614d9a4 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 355b30ce946685..73ef8ab354bd1f 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 5deea2bf85fbe0..d053d994b9a8cb 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-01 +date: 2023-07-02 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 012f366b275c66..0c9eadc5ed6d09 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-01 +date: 2023-07-02 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 d78e6736c9e105..fe194d1340611e 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-01 +date: 2023-07-02 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 1855190cf31370..6114e255597899 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-01 +date: 2023-07-02 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 a3d2955c852852..685ea75710183c 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-01 +date: 2023-07-02 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 c42259090282b4..a50ab3d723b0e4 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-01 +date: 2023-07-02 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 c739b1a904c7f2..35c0a3e18fdec7 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-01 +date: 2023-07-02 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 a86d3cc28be127..05c83b9f7b00f9 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-01 +date: 2023-07-02 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 4b7b88022a6794..0dcbc454c599c2 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-01 +date: 2023-07-02 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 e19b6a8c891316..7c693fc7f9c537 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-01 +date: 2023-07-02 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.devdocs.json b/api_docs/kbn_default_nav_ml.devdocs.json index 45e7eed7800009..ef16da2dd9b340 100644 --- a/api_docs/kbn_default_nav_ml.devdocs.json +++ b/api_docs/kbn_default_nav_ml.devdocs.json @@ -175,7 +175,7 @@ "label": "children", "description": [], "signature": [ - "[{ title: string; id: \"root\"; children: [{ link: \"ml:overview\"; }, { link: \"ml:notifications\"; }]; }, { title: any; id: \"anomaly_detection\"; children: [{ title: any; link: \"ml:anomalyDetection\"; }, { link: \"ml:anomalyExplorer\"; }, { link: \"ml:singleMetricViewer\"; }, { link: \"ml:settings\"; }]; }, { id: \"data_frame_analytics\"; title: any; children: [{ title: string; link: \"ml:dataFrameAnalytics\"; }, { link: \"ml:resultExplorer\"; }, { link: \"ml:analyticsMap\"; }]; }, { id: \"model_management\"; title: any; children: [{ link: \"ml:nodesOverview\"; }, { link: \"ml:nodes\"; }]; }, { id: \"data_visualizer\"; title: any; children: [{ title: any; link: \"ml:fileUpload\"; }, { title: any; link: \"ml:indexDataVisualizer\"; }]; }, { id: \"aiops_labs\"; title: any; children: [{ title: any; link: \"ml:explainLogRateSpikes\"; }, { link: \"ml:logPatternAnalysis\"; }]; }]" + "[{ title: string; id: \"root\"; children: [{ link: \"ml:overview\"; }, { link: \"ml:notifications\"; }]; }, { title: any; id: \"anomaly_detection\"; children: [{ title: any; link: \"ml:anomalyDetection\"; }, { link: \"ml:anomalyExplorer\"; }, { link: \"ml:singleMetricViewer\"; }, { link: \"ml:settings\"; }]; }, { id: \"data_frame_analytics\"; title: any; children: [{ title: string; link: \"ml:dataFrameAnalytics\"; }, { link: \"ml:resultExplorer\"; }, { link: \"ml:analyticsMap\"; }]; }, { id: \"model_management\"; title: any; children: [{ link: \"ml:nodesOverview\"; }, { link: \"ml:nodes\"; }]; }, { id: \"data_visualizer\"; title: any; children: [{ title: any; link: \"ml:fileUpload\"; }, { title: any; link: \"ml:indexDataVisualizer\"; }]; }, { id: \"aiops_labs\"; title: any; children: [{ link: \"ml:explainLogRateSpikes\"; }, { link: \"ml:logPatternAnalysis\"; }, { link: \"ml:changePointDetections\"; }]; }]" ], "path": "packages/default-nav/ml/default_navigation.ts", "deprecated": false, diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 5d7244de5e2b44..f5f6f5782e42b9 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-01 +date: 2023-07-02 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 54375a41d32a53..ecc2c8d3963b34 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-01 +date: 2023-07-02 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 f378cb6feec663..91a217feb5bd6f 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-01 +date: 2023-07-02 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 73ef71ac81f78f..f0e51e8d7b9ebe 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-01 +date: 2023-07-02 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 231c242f14ac42..482f988de9a90e 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 96d5d3e16bc7f3..69eebd4480917e 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-01 +date: 2023-07-02 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 e69f57d27e6e29..ba7f59fa03b2d6 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 f59e4466d831d9..d3f708077326fd 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-01 +date: 2023-07-02 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 4bfce1e749f9f6..914c205a1cb525 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-01 +date: 2023-07-02 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 759b92e0b971f1..336891fd163819 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-01 +date: 2023-07-02 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 d6d5f3daf17c1a..c4435a1690c8ab 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index bd6ec3e22a5126..d45d8157e02c44 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 497452eb2271b7..6ed694f3be482e 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-01 +date: 2023-07-02 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 85256a910bcb92..0eda635a4aac60 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-01 +date: 2023-07-02 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 8feba3a1d6dfcf..1eb9b0d5e21a45 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-01 +date: 2023-07-02 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 970f436b91b226..c4a17091bb4317 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-01 +date: 2023-07-02 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 37c82a3546288a..775ced7f22bf29 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-01 +date: 2023-07-02 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 8aa3ae23c63d09..3280015d9e55a3 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index ce50720645de46..b28be971abfc17 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-01 +date: 2023-07-02 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 1bb070d1d00b97..02233db1008438 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 6d64c386bbc6f0..2d26c4d04ad7ae 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-01 +date: 2023-07-02 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 2939dcb1027493..7ed6c18db66d56 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 25e30356fc4ea3..0f7308e09368cd 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-01 +date: 2023-07-02 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 c06d70ec88d237..adc951e4ed6e28 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-01 +date: 2023-07-02 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 2351b7f1bf1f78..ee1a5e3dbd11a3 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 1e6b05e205c780..6dba378ca5704f 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 6d4fcb8fe49efb..e93d4ab0ffa0bf 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-01 +date: 2023-07-02 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 5809c8904bb057..d1af1ac4e6b74a 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-01 +date: 2023-07-02 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 a6facf3d48dc64..4cd77461cab950 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 063e560b9d2a07..3a9e544ffb6b89 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-01 +date: 2023-07-02 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 d6f6527f3323b5..037557fcfdcc04 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-01 +date: 2023-07-02 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 8c14d2aac7f3c3..650de501e371d4 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-01 +date: 2023-07-02 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 1ee8d396c85d92..c49962382fca88 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-01 +date: 2023-07-02 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 b06caea81a3bdf..74b5761735b9ce 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-01 +date: 2023-07-02 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 242151c2255311..eb10c7df394e26 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-01 +date: 2023-07-02 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 fe4e513c8a6860..e7ab47cb819d81 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-01 +date: 2023-07-02 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 e8a495b894da0a..5fec521bfd9caf 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-01 +date: 2023-07-02 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 f24fc054813c8d..4e59a5aafc061f 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 47bf87a3bc84c8..4eb31d007adf57 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-01 +date: 2023-07-02 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 b7037e0c3591ca..0db9429190a9c7 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-01 +date: 2023-07-02 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 fa2de724fd1aaf..def764a1044373 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-01 +date: 2023-07-02 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 c0310d96747002..9bf876a5f552a5 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-01 +date: 2023-07-02 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 7c7ffa50236f5e..19431244697941 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index cbb00747d2be5c..6731f017be3764 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-01 +date: 2023-07-02 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 39c6667b632815..d880841674023f 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 9409f726f3d2be..d3f18e375a8ea8 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-01 +date: 2023-07-02 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 06594d6050b4b0..379a1694130361 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index d89fa6752a3730..d608bd5b244fc6 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-01 +date: 2023-07-02 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 95853867cf8496..0a461a140c5541 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-01 +date: 2023-07-02 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 51c648628b5d62..f434027252e173 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 451a434e585db1..61f7daa6777989 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 f09e64cb1023f0..e8caf3b02939e5 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index a937a196c490cc..862475108df398 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 b80759a3c98571..620ba93c3f8210 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-01 +date: 2023-07-02 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 ee88250204b67d..66f14f008a2078 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-01 +date: 2023-07-02 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 d526a8a2f7f6e5..ecc7dbfe445dfa 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 c0319e14cf1411..2e5365e139267b 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 6bed7525b237fb..4cfec5729cedad 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-01 +date: 2023-07-02 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 06683c7591b271..5d2aa52937b1d3 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-01 +date: 2023-07-02 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 a60ffca5d533f6..215c6066be6b0a 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-01 +date: 2023-07-02 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 ee58a072d6bf14..7465e5022a6719 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-01 +date: 2023-07-02 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 7d45dcff22b284..642096c1de6530 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-01 +date: 2023-07-02 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 27f519de3e34bb..9d99f398788d69 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 7af33b1870dad6..727441e8aef930 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 73cad7f7b768f4..605c3bc446d0ab 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 d992a41c07a499..ca301d8a637975 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 0a207eef5155dd..525aa819a3ea57 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 3f1e0790444340..7b3bb06f6e2ece 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-01 +date: 2023-07-02 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 7838e98c20bae4..82cb6a37bcfde0 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 5ebb549cef814e..686c33d18674fd 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 3c80862669f726..ce450198215ecd 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-01 +date: 2023-07-02 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 ac2e442ff24db2..d9ecd5cf2cdba3 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-01 +date: 2023-07-02 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 c9dba8fc7b496e..564d74162358dc 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index b4490a5884e67f..46a9dacb7f870f 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-01 +date: 2023-07-02 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 3fe7bb663be0bf..6afceea407af7b 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-01 +date: 2023-07-02 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 feae10f25c6203..4bb8ec473b25a6 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index e9b165a80fa8a0..22672f2be395f3 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 9dbb61221719c6..496cb382da32f4 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-01 +date: 2023-07-02 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 6e1cb7c047d729..9517d4aa3a69ac 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index c7f1ef72909873..7c64d74a44b6da 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-01 +date: 2023-07-02 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 c6fd8cbe234b31..9a5bf88b936a43 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 2ef81b6c133e69..9d26f86cc71d9f 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-01 +date: 2023-07-02 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 0b560a2fa4a113..0cea41c8c5efe8 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-01 +date: 2023-07-02 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 e30ef23a5ecb1f..6abfa8aa699a91 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-01 +date: 2023-07-02 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 3f0dc805c5587a..403e3ad484b1ce 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-01 +date: 2023-07-02 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 48808594d9f990..a02c55267c44b3 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 2540ca71bb3ce3..6106c9fda73a3c 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 7dcc673d546955..3168bcbdfa181b 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 d0e40282acd9ee..415fa0c8034f13 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index b10e0e04199e68..d544643da44da0 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-01 +date: 2023-07-02 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 d2650651f63337..f1bacfdb3a3353 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-01 +date: 2023-07-02 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 e6a2e11e8b8af2..f05f74000ad403 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-01 +date: 2023-07-02 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 8f2971135ba042..dc2ae0e6d75440 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-01 +date: 2023-07-02 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 2505ad7354ced0..57a15f4ab340a9 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-01 +date: 2023-07-02 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 feb5f9d6112eb0..6ae08dd35f7ad5 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 3fac847ba133ed..6e1a1312d0c60c 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-01 +date: 2023-07-02 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 3814a5c735a236..c8b174a29c6e07 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-01 +date: 2023-07-02 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 e1606e8cedcca6..e59d8787fdc160 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 7e05c3b87b013a..5b6470353bdf21 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-01 +date: 2023-07-02 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 84c0eccfc346e7..2f253d2dc3f848 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-01 +date: 2023-07-02 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 2bdaf3d91dae33..828a04b86b59b4 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-01 +date: 2023-07-02 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 f5aabff2dcc467..dada7a67a56943 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 4bde517249f7d8..8271a04ed50eba 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-01 +date: 2023-07-02 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 18ca9d6b710b31..9154de622d790a 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-01 +date: 2023-07-02 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 0d1cf06cbc5318..eb1cb335df1381 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-01 +date: 2023-07-02 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 34a6cd28b63b28..86ab4ef3d78f20 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 867266875c7bbe..b958c648882eb4 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-01 +date: 2023-07-02 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 0d2d86e2b5f9eb..7ec6ebb027c5db 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-01 +date: 2023-07-02 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 011488503994c6..e6943886fa508f 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-01 +date: 2023-07-02 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 b76b121acf1436..fc807c90dfdd45 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-01 +date: 2023-07-02 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 783a84965b54db..a7c48ca97b4f63 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 1ac8722e820ff4..633deb56bfe722 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 90dcd761088c6c..814188e83a0e04 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-01 +date: 2023-07-02 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 9740834b51668b..a4552a7ea4de81 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-01 +date: 2023-07-02 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 a5dd85a270d533..4886fdbe594758 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index e182a1d1b989ed..2dee3e854401af 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 70b485aabd7dd3..7296a74ffdba82 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 9f61649c0f80aa..fcb02f13ef22c1 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 604e16c3db80d4..d8e2838726f7cb 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-01 +date: 2023-07-02 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 299848ea3f9849..b8337b4c4e1243 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-01 +date: 2023-07-02 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 81fe9003747780..dd1bc2cff7cc28 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 01a8560de63bb2..d82b46f5d38275 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index f0fe276c08959d..444d9d8588295e 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-01 +date: 2023-07-02 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 a04b7451314324..72265dcfd4cb87 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-01 +date: 2023-07-02 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 c445e9dbfc0b3e..7303436ed230e0 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 a9f75168f37592..e4aeaeac2445f3 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 863f1fe7c17320..914b89e0ff249e 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-01 +date: 2023-07-02 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 e508b2ec0be2c7..87fb089853519e 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-01 +date: 2023-07-02 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 1fcb43a3dfb4f8..6b3f92de553600 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-01 +date: 2023-07-02 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 f3df07c76b20d7..c7c9b51f7ca2b5 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-01 +date: 2023-07-02 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 1791452e49f84c..f5ef0dd519b519 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-01 +date: 2023-07-02 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 5eb55a3aee1b17..36a09097e5cd07 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 72a04b84f9a514..24af85c574a07d 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-01 +date: 2023-07-02 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 cd9718f1953b28..db96cf086ab1d8 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 946314be1933c3..1ee0a7a7144442 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-01 +date: 2023-07-02 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 eeb5154639e584..3e52f4e4653cfe 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 6d93616a378dfe..b258ad7c9ba9dd 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-01 +date: 2023-07-02 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 bdb121409874bc..7e6967cbee97b8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 3cb87c2e6d37fb..d4da52368e2bcc 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-01 +date: 2023-07-02 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 97e89e2bcbd070..748499dc537483 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 9998920d49abc7..055a8bd8f5de35 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-01 +date: 2023-07-02 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 1e5dd1cd0d152a..cc5762bf73bbc1 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-01 +date: 2023-07-02 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 32f6e986e4aab1..c3926558f090c3 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 316783b5846c72..e2383f667c00c5 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 e08bd5287ede89..bd732b0ee417e7 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-01 +date: 2023-07-02 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 76dc0f76b08023..709e290b0b01f8 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-01 +date: 2023-07-02 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 3e9a1fd68ca766..c0fb4fb41a95a5 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 91015a2e48c4af..43d349bdd7d38b 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-01 +date: 2023-07-02 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 628de0bcd00173..2701baabd9bc9c 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-01 +date: 2023-07-02 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 b1aba19e1cc999..37044b10298f93 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-01 +date: 2023-07-02 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 cbf005e8a76f4c..ded426f6902dbb 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-01 +date: 2023-07-02 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 500c557b556ec4..5507797d9fbf04 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-01 +date: 2023-07-02 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 939d2b21a60507..578a46fe0d0eb7 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-01 +date: 2023-07-02 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 100186441aa9ea..db4efd0f4620cf 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-01 +date: 2023-07-02 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 2dc3eefef452a4..0cef6235748ae3 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index ec9396d8dd665f..edf8bb06ee42f5 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-01 +date: 2023-07-02 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 76f71d6bccf149..dc4d7fd79a59d9 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-01 +date: 2023-07-02 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 f285c119a1b63e..8792d140843097 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-01 +date: 2023-07-02 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 8f3af791202ce9..678ef6d8277e93 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-01 +date: 2023-07-02 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 59bee27d04908c..1c07e720289b90 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 8412482fb708b3..bc025d75ecef34 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-01 +date: 2023-07-02 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 2aeb616de2d6be..cdd05efb0703b0 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-01 +date: 2023-07-02 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 484dcb76a268eb..f432d2314e3220 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-01 +date: 2023-07-02 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 6a897205db4ff4..a01f84efbac622 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 2420b25760652d..4ac38df6c8b00e 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-01 +date: 2023-07-02 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 bebf5b02024dc4..308dabfbaf97e6 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-01 +date: 2023-07-02 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 4f593db31806b7..d8314d7089912a 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-01 +date: 2023-07-02 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 f538ba872df103..90d7e277abb5f9 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-01 +date: 2023-07-02 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 97f25a83f2bcaf..eabcb60fd23e06 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 8d4707caa8c703..c3cccfbd822c9c 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index af90e441b7df56..ea8e88e5c7c3f4 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 4bcf4dea51cd40..b9dca5a378f984 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-01 +date: 2023-07-02 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 e1497819ed1874..9dfa1d44a98c5b 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-01 +date: 2023-07-02 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 86ea07749dec95..c24e1efef4e8bb 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-01 +date: 2023-07-02 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 3c64564ace6514..e8e008c76c10d3 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 4ffdda08138474..293248469057d7 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index d19633fd370d79..a3de6a755d8e8c 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-01 +date: 2023-07-02 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 8c386f16bf1974..b752cfe59738ad 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-01 +date: 2023-07-02 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 6c6f89609aa5b3..b00b072453eebb 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-01 +date: 2023-07-02 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 23f69c5fa821f9..f63301246f3689 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-01 +date: 2023-07-02 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 269e5c4d593edf..24e3de6556fe70 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-01 +date: 2023-07-02 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 0d9f0753d392f2..cfb73fd65b3bb4 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-01 +date: 2023-07-02 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 9add4e8c52f836..6415ee26c2eff6 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 d238ff43a7a520..433e2310d3c742 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 52c0abbd90c73d..8689f02f61bdf0 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index e4099b8e79753c..24c4becf4f0b37 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-01 +date: 2023-07-02 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 ea69cba58789a4..aa41e122454de1 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-01 +date: 2023-07-02 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 1e48c3b5456f6e..31416c36e90279 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 77287b57334ec1..52fbc37e7e2a31 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -462,7 +462,7 @@ "label": "capabilities", "description": [], "signature": [ - "{ canGetJobs: boolean; canGetDatafeeds: boolean; canGetCalendars: boolean; canFindFileStructure: boolean; canGetDataFrameAnalytics: boolean; canGetAnnotations: boolean; canCreateAnnotation: boolean; canDeleteAnnotation: boolean; canUseMlAlerts: boolean; canGetTrainedModels: boolean; canTestTrainedModels: boolean; canGetFieldInfo: boolean; canGetMlInfo: boolean; canUseAiops: boolean; } & { canCreateJob: boolean; canDeleteJob: boolean; canOpenJob: boolean; canCloseJob: boolean; canResetJob: boolean; canUpdateJob: boolean; canForecastJob: boolean; canCreateDatafeed: boolean; canDeleteDatafeed: boolean; canStartStopDatafeed: boolean; canUpdateDatafeed: boolean; canPreviewDatafeed: boolean; canGetFilters: boolean; canCreateCalendar: boolean; canDeleteCalendar: boolean; canCreateFilter: boolean; canDeleteFilter: boolean; canCreateDataFrameAnalytics: boolean; canDeleteDataFrameAnalytics: boolean; canStartStopDataFrameAnalytics: boolean; canCreateMlAlerts: boolean; canUseMlAlerts: boolean; canViewMlNodes: boolean; canCreateTrainedModels: boolean; canDeleteTrainedModels: boolean; canStartStopTrainedModels: boolean; }" + "{ isADEnabled: boolean; isDFAEnabled: boolean; isNLPEnabled: boolean; } & { canGetJobs: boolean; canGetDatafeeds: boolean; canGetCalendars: boolean; canFindFileStructure: boolean; canGetDataFrameAnalytics: boolean; canGetAnnotations: boolean; canCreateAnnotation: boolean; canDeleteAnnotation: boolean; canUseMlAlerts: boolean; canGetTrainedModels: boolean; canTestTrainedModels: boolean; canGetFieldInfo: boolean; canGetMlInfo: boolean; canUseAiops: boolean; } & { canCreateJob: boolean; canDeleteJob: boolean; canOpenJob: boolean; canCloseJob: boolean; canResetJob: boolean; canUpdateJob: boolean; canForecastJob: boolean; canCreateDatafeed: boolean; canDeleteDatafeed: boolean; canStartStopDatafeed: boolean; canUpdateDatafeed: boolean; canPreviewDatafeed: boolean; canGetFilters: boolean; canCreateCalendar: boolean; canDeleteCalendar: boolean; canCreateFilter: boolean; canDeleteFilter: boolean; canCreateDataFrameAnalytics: boolean; canDeleteDataFrameAnalytics: boolean; canStartStopDataFrameAnalytics: boolean; canCreateMlAlerts: boolean; canUseMlAlerts: boolean; canViewMlNodes: boolean; canCreateTrainedModels: boolean; canDeleteTrainedModels: boolean; canStartStopTrainedModels: boolean; }" ], "path": "x-pack/plugins/ml/common/types/capabilities.ts", "deprecated": false, @@ -1915,7 +1915,8 @@ "): { preview: (args_0: Readonly<{} & { timeRange: string; alertParams: Readonly<{} & { severity: number; jobSelection: Readonly<{} & { groupIds: string[]; jobIds: string[]; }>; resultType: \"bucket\" | \"record\" | \"influencer\"; includeInterim: boolean; lookbackInterval: string | null; topNBuckets: number | null; }>; sampleSize: number; }>) => Promise; execute: (params: Readonly<{} & { severity: number; jobSelection: Readonly<{} & { groupIds: string[]; jobIds: string[]; }>; resultType: \"bucket\" | \"record\" | \"influencer\"; includeInterim: boolean; lookbackInterval: string | null; topNBuckets: number | null; }>) => Promise<{ context: ", "AnomalyDetectionAlertContext", "; name: string; isHealthy: boolean; } | undefined>; }; } & ", - "TrainedModelsProvider" + "TrainedModelsProvider", + " & MlSetup" ], "path": "x-pack/plugins/ml/server/plugin.ts", "deprecated": false, diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index f5e3da113860b6..7cd5c270a7134b 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.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 | |-------------------|-----------|------------------------|-----------------| -| 150 | 3 | 64 | 33 | +| 150 | 3 | 64 | 32 | ## Client diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index d53db399c06431..db969ba0608721 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-01 +date: 2023-07-02 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 420fff32e61b7e..3529ff50d0e0cd 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-01 +date: 2023-07-02 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 fda42a5b2c1617..793b4ce79984eb 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-01 +date: 2023-07-02 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 42bb8d105a4e73..baa4ccb1b946d8 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 7b387f6acd541f..b5fa3e93b2433d 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-01 +date: 2023-07-02 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 3eafde41fea3d9..1b3cac88b6a29c 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index c1703e29d78fd0..8c583c52ba6350 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-01 +date: 2023-07-02 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 f1fc4fe1b7ed3a..418a1d710c7b22 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-01 +date: 2023-07-02 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 25da2b1cd889ad..388485fecd08f5 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 103e70349756f3..00cf378719a8df 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70948 | 544 | 60765 | 1410 | +| 70948 | 544 | 60765 | 1409 | ## Plugin Directory @@ -126,7 +126,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 266 | 0 | 265 | 28 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 33 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 32 | | | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | - | 15 | 3 | 13 | 1 | | | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 34 | 0 | 34 | 2 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index a7f1d296080a3f..4f1d204a682bae 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-01 +date: 2023-07-02 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 8b2228245a5f0f..6e9c106ab943e8 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index dc6e58f5b9210f..2989b9e9beec4b 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-01 +date: 2023-07-02 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 476cb1739d4aa8..2c7e5f970816e5 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index d2588a5cfadc50..5f1d5f492d3307 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 7078e87cd6324a..35e1e83849c180 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-01 +date: 2023-07-02 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 c8ece42510a29d..a2d078a742c4dc 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-01 +date: 2023-07-02 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 8071caeb0c5aec..34b2a84e8c3f7d 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-01 +date: 2023-07-02 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 0808d53f269814..fb0683ffbc92e2 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-01 +date: 2023-07-02 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 b0c13e53e3332a..5866100adbe852 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-01 +date: 2023-07-02 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 a4280a21eeb95b..0cdb66a3c12b69 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-01 +date: 2023-07-02 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 540afdc13298b1..0774c150a95f88 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-01 +date: 2023-07-02 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 a49cede4e7053a..4f9a09475a6a0a 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-01 +date: 2023-07-02 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 fb49a6088d7e41..1802fef00ac0eb 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-01 +date: 2023-07-02 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 1b960866aaa34c..2f4972f0ce5195 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-01 +date: 2023-07-02 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 396f9ac7228f82..685e7c760c0eaa 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-01 +date: 2023-07-02 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 8f01fd49866d7e..05ea5ec3929b26 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-01 +date: 2023-07-02 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 4b9922889c5be4..f7777b78a06ade 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 6f8f4bb513122f..ab63e80837ee13 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-01 +date: 2023-07-02 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 96afad72f333ac..8d15175fe257d7 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-01 +date: 2023-07-02 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 dfe7597f3534fa..b6cbab543b9d1e 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index 9438f77d41e214..ec9c383a6bf33e 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 2404fadea1d4d2..b26a491fb65da1 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-01 +date: 2023-07-02 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 af003c840feebc..26bd21e3de88fd 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-01 +date: 2023-07-02 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 a7248525a6ccac..0a1abe4a728e90 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-01 +date: 2023-07-02 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 efa1263443622b..8fda77f8bfa78b 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-01 +date: 2023-07-02 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 72c5db40b78d0c..a706414ad56f30 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-01 +date: 2023-07-02 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 6bad751d5a1c8f..7593306b4dce93 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-01 +date: 2023-07-02 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 cd91ef931b02cd..341a7e41ed21b3 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-01 +date: 2023-07-02 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 9ac752da2a1b2e..aec532051f98bf 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-01 +date: 2023-07-02 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 40aab05f868541..d80816711d3bb6 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-01 +date: 2023-07-02 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 60ed328aeff72a..0ceda636e947f6 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-01 +date: 2023-07-02 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 6fe5a1b4c223ac..fc2bf3eefa2721 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-01 +date: 2023-07-02 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 616e41b7a88b50..cc74119ee4be8f 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-01 +date: 2023-07-02 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 3c9b796ba2d129..731bbc38959d88 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-01 +date: 2023-07-02 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 c561fc4d9ea48b..7853fa4ee3f9c0 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-01 +date: 2023-07-02 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 5f53242023d280..65e4578d007ddc 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-01 +date: 2023-07-02 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 78edc3f55bcc1a..ca5546b51f81e8 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-01 +date: 2023-07-02 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 43f87bffa9b216..8b28f982c909d2 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-01 +date: 2023-07-02 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 3ef74c95039a62..e3bcc5945648b8 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 21da66d46a878f..76dfbd26239fb7 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-01 +date: 2023-07-02 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 36633709b3c62c..d50428a99432da 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-01 +date: 2023-07-02 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 7f91b88d7955ef..bfe65c2f451ede 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index d04499f05c9fc4..4375269d97c8a2 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-01 +date: 2023-07-02 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 420df299d3954e..7ed0d48923b76a 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-01 +date: 2023-07-02 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 3741f2cc41172a..644c92d3e86741 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-01 +date: 2023-07-02 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 710ce5222aacdc..cc394e5ed6c2cb 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-01 +date: 2023-07-02 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 fad26b275bb063..46a0ea46d935b2 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-01 +date: 2023-07-02 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 08edda8c1d6487..08104c073aba23 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-01 +date: 2023-07-02 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 5d9cb6d19b1cfa..e3d937a0d4e980 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-01 +date: 2023-07-02 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 f3d53a6d0e3510..98d46eec4c6648 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-01 +date: 2023-07-02 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 6a1a9643fe2a53..090f16f98a6af0 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-01 +date: 2023-07-02 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 1b355904b2c7ff..b9a5529c93792b 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-01 +date: 2023-07-02 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 3eb4fc9f00f38a..e002acb767b25f 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-01 +date: 2023-07-02 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 10cdc760633ba2..5a57a88e97d10d 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-01 +date: 2023-07-02 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 bebdbe3246f2e7..0d980931f1036e 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index cd97b619b8a941..07e94e5d4657b6 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index e51e594a608f10..60733ec32a7feb 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-01 +date: 2023-07-02 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From a5d4d9d948cd3d4fa13cb1ceef7710c4e8f0807a Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Sun, 2 Jul 2023 12:53:13 +0300 Subject: [PATCH 07/98] [Cloud Security] update benchmark api (#158800) --- .../common/constants.ts | 5 + .../common/schemas/benchmark.ts | 2 +- .../cloud_security_posture/common/types.ts | 2 +- .../use_csp_benchmark_integrations.ts | 10 +- .../public/pages/rules/use_csp_rules.ts | 3 +- .../server/lib/fleet_util.ts | 4 +- .../routes/benchmarks/benchmarks.test.ts | 16 ++- .../server/routes/benchmarks/benchmarks.ts | 107 ++++++++++-------- .../apis/cloud_security_posture/benchmark.ts | 15 ++- 9 files changed, 97 insertions(+), 67 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 97c718bf4aeb77..8b6ed65bb18533 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -9,10 +9,15 @@ import { PostureTypes, VulnSeverity } from './types'; export const STATUS_ROUTE_PATH = '/internal/cloud_security_posture/status'; export const STATS_ROUTE_PATH = '/internal/cloud_security_posture/stats/{policy_template}'; + export const VULNERABILITIES_DASHBOARD_ROUTE_PATH = '/internal/cloud_security_posture/vulnerabilities_dashboard'; + export const BENCHMARKS_ROUTE_PATH = '/internal/cloud_security_posture/benchmarks'; +export const BENCHMARKS_API_CURRENT_VERSION = '1'; + export const FIND_CSP_RULE_TEMPLATE_ROUTE_PATH = '/internal/cloud_security_posture/rules/_find'; +export const FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION = '1'; export const CLOUD_SECURITY_POSTURE_PACKAGE_NAME = 'cloud_security_posture'; // TODO: REMOVE CSP_LATEST_FINDINGS_DATA_VIEW and replace it with LATEST_FINDINGS_INDEX_PATTERN diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/benchmark.ts b/x-pack/plugins/cloud_security_posture/common/schemas/benchmark.ts index 40f94ec63c57c6..0d30ae992dd113 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/benchmark.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/benchmark.ts @@ -56,7 +56,7 @@ export const benchmarksQueryParamsSchema = schema.object({ /** * Benchmark filter */ - benchmark_name: schema.maybe(schema.string()), + package_policy_name: schema.maybe(schema.string()), }); export type BenchmarksQueryParams = TypeOf; diff --git a/x-pack/plugins/cloud_security_posture/common/types.ts b/x-pack/plugins/cloud_security_posture/common/types.ts index 4f3fd3434617cc..f83fc5ae0fd738 100644 --- a/x-pack/plugins/cloud_security_posture/common/types.ts +++ b/x-pack/plugins/cloud_security_posture/common/types.ts @@ -111,7 +111,7 @@ export type PostureInput = typeof SUPPORTED_CLOUDBEAT_INPUTS[number]; export type CloudSecurityPolicyTemplate = typeof SUPPORTED_POLICY_TEMPLATES[number]; export type PosturePolicyTemplate = Extract; -export interface BenchmarkResponse { +export interface GetBenchmarkResponse { items: Benchmark[]; total: number; page: number; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts index ccdc3650b2596f..95d955c69047e2 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/use_csp_benchmark_integrations.ts @@ -7,7 +7,7 @@ import { useQuery } from '@tanstack/react-query'; import type { ListResult } from '@kbn/fleet-plugin/common'; -import { BENCHMARKS_ROUTE_PATH } from '../../../common/constants'; +import { BENCHMARKS_API_CURRENT_VERSION, BENCHMARKS_ROUTE_PATH } from '../../../common/constants'; import type { BenchmarksQueryParams } from '../../../common/schemas/benchmark'; import { useKibana } from '../../common/hooks/use_kibana'; import type { Benchmark } from '../../../common/types'; @@ -31,7 +31,7 @@ export const useCspBenchmarkIntegrations = ({ }: UseCspBenchmarkIntegrationsProps) => { const { http } = useKibana().services; const query: BenchmarksQueryParams = { - benchmark_name: name, + package_policy_name: name, per_page: perPage, page, sort_field: sortField, @@ -40,7 +40,11 @@ export const useCspBenchmarkIntegrations = ({ return useQuery( [QUERY_KEY, query], - () => http.get>(BENCHMARKS_ROUTE_PATH, { query }), + () => + http.get>(BENCHMARKS_ROUTE_PATH, { + query, + version: BENCHMARKS_API_CURRENT_VERSION, + }), { keepPreviousData: true } ); }; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index b246fa3aa9188a..a5aee47c7c1cc7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -10,6 +10,7 @@ import { useKibana } from '../../common/hooks/use_kibana'; import { CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, + FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION, FIND_CSP_RULE_TEMPLATE_ROUTE_PATH, } from '../../../common/constants'; @@ -27,7 +28,7 @@ export const useFindCspRuleTemplates = ( () => { return http.get(FIND_CSP_RULE_TEMPLATE_ROUTE_PATH, { query: { packagePolicyId, page, perPage }, - version: '1', + version: FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION, }); } ); diff --git a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts index c5ccc19d686637..290e5ecb319697 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts @@ -105,8 +105,8 @@ export const getCspPackagePolicies = async ( ? input.enabled : input.enabled && input.policy_template === postureType ).length > 0 && - (!queryParams.benchmark_name || - pkg.name.toLowerCase().includes(queryParams.benchmark_name.toLowerCase())) + (!queryParams.package_policy_name || + pkg.name.toLowerCase().includes(queryParams.package_policy_name.toLowerCase())) ); const page = queryParams?.page ?? 1; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts index 8e46a5050553df..25fc95e1f8a20d 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts @@ -27,7 +27,7 @@ describe('benchmarks API', () => { defineGetBenchmarksRoute(router); - const [config] = router.get.mock.calls[0]; + const [config] = router.versioned.get.mock.calls[0]; expect(config.path).toEqual('/internal/cloud_security_posture/benchmarks'); }); @@ -37,7 +37,9 @@ describe('benchmarks API', () => { defineGetBenchmarksRoute(router); - const [_, handler] = router.get.mock.calls[0]; + const versionedRouter = router.versioned.get.mock.results[0].value; + + const handler = versionedRouter.addVersion.mock.calls[0][1]; const mockContext = createCspRequestHandlerContextMock(); const mockResponse = httpServerMock.createResponseFactory(); @@ -54,7 +56,9 @@ describe('benchmarks API', () => { defineGetBenchmarksRoute(router); - const [_, handler] = router.get.mock.calls[0]; + const versionedRouter = router.versioned.get.mock.results[0].value; + + const handler = versionedRouter.addVersion.mock.calls[0][1]; const mockContext = createCspRequestHandlerContextMock(); mockContext.fleet.authz.fleet.all = false; @@ -78,15 +82,15 @@ describe('benchmarks API', () => { }); }); - it('expect to find benchmark_name', async () => { + it('expect to find package_policy_name', async () => { const validatedQuery = benchmarksQueryParamsSchema.validate({ - benchmark_name: 'my_cis_benchmark', + package_policy_name: 'my_cis_benchmark', }); expect(validatedQuery).toMatchObject({ page: 1, per_page: DEFAULT_BENCHMARKS_PER_PAGE, - benchmark_name: 'my_cis_benchmark', + package_policy_name: 'my_cis_benchmark', }); }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index 6012583104f359..399e637b234949 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -15,7 +15,7 @@ import { POSTURE_TYPE_ALL, } from '../../../common/constants'; import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark'; -import type { Benchmark } from '../../../common/types'; +import type { Benchmark, GetBenchmarkResponse } from '../../../common/types'; import { getBenchmarkFromPackagePolicy, getBenchmarkTypeFilter, @@ -84,63 +84,74 @@ const createBenchmarks = ( ); }; -export const defineGetBenchmarksRoute = (router: CspRouter): void => - router.get( - { +export const defineGetBenchmarksRoute = (router: CspRouter) => + router.versioned + .get({ + access: 'internal', path: BENCHMARKS_ROUTE_PATH, - validate: { query: benchmarksQueryParamsSchema }, options: { tags: ['access:cloud-security-posture-read'], }, - }, - async (context, request, response) => { - if (!(await context.fleet).authz.fleet.all) { - return response.forbidden(); - } + }) + .addVersion( + { + version: '1', + validate: { + request: { + query: benchmarksQueryParamsSchema, + }, + }, + }, + async (context, request, response) => { + if (!(await context.fleet).authz.fleet.all) { + return response.forbidden(); + } - const cspContext = await context.csp; + const cspContext = await context.csp; - try { - const cspPackagePolicies = await getCspPackagePolicies( - cspContext.soClient, - cspContext.packagePolicyService, - CLOUD_SECURITY_POSTURE_PACKAGE_NAME, - request.query, - POSTURE_TYPE_ALL - ); + try { + const cspPackagePolicies = await getCspPackagePolicies( + cspContext.soClient, + cspContext.packagePolicyService, + CLOUD_SECURITY_POSTURE_PACKAGE_NAME, + request.query, + POSTURE_TYPE_ALL + ); - const agentPolicies = await getCspAgentPolicies( - cspContext.soClient, - cspPackagePolicies.items, - cspContext.agentPolicyService - ); + const agentPolicies = await getCspAgentPolicies( + cspContext.soClient, + cspPackagePolicies.items, + cspContext.agentPolicyService + ); - const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies( - cspContext.agentService, - agentPolicies, - cspContext.logger - ); + const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies( + cspContext.agentService, + agentPolicies, + cspContext.logger + ); - const benchmarks = await createBenchmarks( - cspContext.soClient, - agentPolicies, - agentStatusesByAgentPolicyId, - cspPackagePolicies.items - ); + const benchmarks = await createBenchmarks( + cspContext.soClient, + agentPolicies, + agentStatusesByAgentPolicyId, + cspPackagePolicies.items + ); - return response.ok({ - body: { + const getBenchmarkResponse: GetBenchmarkResponse = { ...cspPackagePolicies, items: benchmarks, - }, - }); - } catch (err) { - const error = transformError(err); - cspContext.logger.error(`Failed to fetch benchmarks ${err}`); - return response.customError({ - body: { message: error.message }, - statusCode: error.statusCode, - }); + }; + + return response.ok({ + body: getBenchmarkResponse, + }); + } catch (err) { + const error = transformError(err); + cspContext.logger.error(`Failed to fetch benchmarks ${err}`); + return response.customError({ + body: { message: error.message }, + statusCode: error.statusCode, + }); + } } - } - ); + ); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/benchmark.ts b/x-pack/test/api_integration/apis/cloud_security_posture/benchmark.ts index 997ff9c636f0ad..0c3382dc8521b2 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/benchmark.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/benchmark.ts @@ -5,8 +5,9 @@ * 2.0. */ import expect from '@kbn/expect'; -import type { BenchmarkResponse } from '@kbn/cloud-security-posture-plugin/common/types'; +import type { GetBenchmarkResponse } from '@kbn/cloud-security-posture-plugin/common/types'; import type { SuperTest, Test } from 'supertest'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -91,8 +92,9 @@ export default function ({ getService }: FtrProviderContext) { }); it(`Should return non-empty array filled with Rules if user has CSP integrations`, async () => { - const { body: res }: { body: BenchmarkResponse } = await supertest + const { body: res }: { body: GetBenchmarkResponse } = await supertest .get(`/internal/cloud_security_posture/benchmarks`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -101,8 +103,9 @@ export default function ({ getService }: FtrProviderContext) { }); it(`Should return array size 2 when we set per page to be only 2 (total element is still 3)`, async () => { - const { body: res }: { body: BenchmarkResponse } = await supertest + const { body: res }: { body: GetBenchmarkResponse } = await supertest .get(`/internal/cloud_security_posture/benchmarks?per_page=2`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -111,8 +114,9 @@ export default function ({ getService }: FtrProviderContext) { }); it(`Should return array size 2 when we set per page to be only 2 (total element is still 3)`, async () => { - const { body: res }: { body: BenchmarkResponse } = await supertest + const { body: res }: { body: GetBenchmarkResponse } = await supertest .get(`/internal/cloud_security_posture/benchmarks?per_page=2&page=2`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -121,8 +125,9 @@ export default function ({ getService }: FtrProviderContext) { }); it(`Should return empty array when we set page to be above the last page number`, async () => { - const { body: res }: { body: BenchmarkResponse } = await supertest + const { body: res }: { body: GetBenchmarkResponse } = await supertest .get(`/internal/cloud_security_posture/benchmarks?per_page=2&page=3`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); From dea3423b2f088af4e0342356f79958fc2532ee71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Sun, 2 Jul 2023 20:29:07 +0100 Subject: [PATCH 08/98] [Cloud] Update support and user profile header menus (#160535) --- .../src/chrome_service.tsx | 23 +++- .../src/constants.ts | 13 -- .../src/nav_controls/nav_controls_service.ts | 16 ++- .../src/ui/header/header.test.tsx | 5 +- .../src/ui/header/header.tsx | 7 + .../src/ui/header/header_help_menu.test.tsx | 17 ++- .../src/ui/header/header_help_menu.tsx | 127 +++++++++++------- .../src/ui/project/header.test.tsx | 4 +- .../src/ui/project/header.tsx | 12 +- .../src/chrome_service.mock.ts | 6 +- .../core/chrome/core-chrome-browser/index.ts | 1 + .../core-chrome-browser/src/contracts.ts | 12 +- .../chrome/core-chrome-browser/src/index.ts | 2 +- .../core-chrome-browser/src/nav_controls.ts | 13 ++ packages/kbn-doc-links/src/get_doc_links.ts | 4 + packages/kbn-doc-links/src/get_doc_meta.ts | 1 + packages/kbn-doc-links/src/types.ts | 4 + packages/kbn-optimizer/limits.yml | 2 +- .../test_suites/core_plugins/rendering.ts | 1 + x-pack/plugins/cloud/public/mocks.tsx | 1 + x-pack/plugins/cloud/public/plugin.tsx | 8 +- x-pack/plugins/cloud/public/types.ts | 4 + x-pack/plugins/cloud/server/config.ts | 2 + .../maybe_add_cloud_links/help_menu_links.ts | 40 ++++++ .../maybe_add_cloud_links.test.ts | 74 ++++++++-- .../maybe_add_cloud_links.ts | 67 +++++---- .../maybe_add_cloud_links/user_menu_links.ts | 22 ++- .../cloud_links/public/plugin.tsx | 2 +- .../cloud_links/tsconfig.json | 2 + .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - x-pack/test/functional_cloud/config.ts | 1 + .../functional_cloud/tests/cloud_links.ts | 21 +-- 34 files changed, 383 insertions(+), 134 deletions(-) delete mode 100644 packages/core/chrome/core-chrome-browser-internal/src/constants.ts create mode 100644 x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx index 151ba56ad4aa0f..65c7df00d39dea 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx @@ -15,7 +15,7 @@ import { EuiLink } from '@elastic/eui'; import useObservable from 'react-use/lib/useObservable'; import type { InternalInjectedMetadataStart } from '@kbn/core-injected-metadata-browser-internal'; import type { AnalyticsServiceSetup } from '@kbn/core-analytics-browser'; -import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import { type DocLinksStart } from '@kbn/core-doc-links-browser'; import type { HttpStart } from '@kbn/core-http-browser'; import { mountReactNode } from '@kbn/core-mount-utils-browser-internal'; import type { NotificationsStart } from '@kbn/core-notifications-browser'; @@ -33,8 +33,11 @@ import type { ChromeSetProjectBreadcrumbsParams, } from '@kbn/core-chrome-browser'; import type { CustomBrandingStart } from '@kbn/core-custom-branding-browser'; -import type { SideNavComponent as ISideNavComponent } from '@kbn/core-chrome-browser'; -import { KIBANA_ASK_ELASTIC_LINK } from './constants'; +import type { + SideNavComponent as ISideNavComponent, + ChromeHelpMenuLink, +} from '@kbn/core-chrome-browser'; + import { DocTitleService } from './doc_title'; import { NavControlsService } from './nav_controls'; import { NavLinksService } from './nav_links'; @@ -135,7 +138,7 @@ export class ChromeService { >(undefined); const badge$ = new BehaviorSubject(undefined); const customNavLink$ = new BehaviorSubject(undefined); - const helpSupportUrl$ = new BehaviorSubject(KIBANA_ASK_ELASTIC_LINK); + const helpSupportUrl$ = new BehaviorSubject(docLinks.links.kibana.askElastic); const isNavDrawerLocked$ = new BehaviorSubject(localStorage.getItem(IS_LOCKED_KEY) === 'true'); const chromeStyle$ = new BehaviorSubject('classic'); @@ -168,6 +171,7 @@ export class ChromeService { const recentlyAccessed = await this.recentlyAccessed.start({ http }); const docTitle = this.docTitle.start(); const { customBranding$ } = customBranding; + const helpMenuLinks$ = navControls.getHelpMenuLinks$(); // erase chrome fields from a previous app while switching to a next app application.currentAppId$.subscribe(() => { @@ -301,12 +305,13 @@ export class ChromeService { breadcrumbs$={currentProjectBreadcrumbs$} helpExtension$={helpExtension$.pipe(takeUntil(this.stop$))} helpSupportUrl$={helpSupportUrl$.pipe(takeUntil(this.stop$))} + helpMenuLinks$={helpMenuLinks$} navControlsLeft$={navControls.getLeft$()} navControlsCenter$={navControls.getCenter$()} navControlsRight$={navControls.getRight$()} loadingCount$={http.getLoadingCount$()} homeHref$={projectNavigation.getProjectHome$()} - kibanaDocLink={docLinks.links.kibana.guide} + docLinks={docLinks} kibanaVersion={injectedMetadata.getKibanaVersion()} prependBasePath={http.basePath.prepend} > @@ -329,10 +334,12 @@ export class ChromeService { breadcrumbsAppendExtension$={breadcrumbsAppendExtension$.pipe(takeUntil(this.stop$))} customNavLink$={customNavLink$.pipe(takeUntil(this.stop$))} kibanaDocLink={docLinks.links.kibana.guide} + docLinks={docLinks} forceAppSwitcherNavigation$={navLinks.getForceAppSwitcherNavigation$()} globalHelpExtensionMenuLinks$={globalHelpExtensionMenuLinks$} helpExtension$={helpExtension$.pipe(takeUntil(this.stop$))} helpSupportUrl$={helpSupportUrl$.pipe(takeUntil(this.stop$))} + helpMenuLinks$={helpMenuLinks$} homeHref={http.basePath.prepend('/app/home')} isVisible$={this.isVisible$} kibanaVersion={injectedMetadata.getKibanaVersion()} @@ -399,6 +406,8 @@ export class ChromeService { setHelpSupportUrl: (url: string) => helpSupportUrl$.next(url), + getHelpSupportUrl$: () => helpSupportUrl$.pipe(takeUntil(this.stop$)), + getIsNavDrawerLocked$: () => getIsNavDrawerLocked$, getCustomNavLink$: () => customNavLink$.pipe(takeUntil(this.stop$)), @@ -407,6 +416,10 @@ export class ChromeService { customNavLink$.next(customNavLink); }, + setHelpMenuLinks: (helpMenuLinks: ChromeHelpMenuLink[]) => { + navControls.setHelpMenuLinks(helpMenuLinks); + }, + setHeaderBanner: (headerBanner?: ChromeUserBanner) => { headerBanner$.next(headerBanner); }, diff --git a/packages/core/chrome/core-chrome-browser-internal/src/constants.ts b/packages/core/chrome/core-chrome-browser-internal/src/constants.ts deleted file mode 100644 index 7c980bec2b2d89..00000000000000 --- a/packages/core/chrome/core-chrome-browser-internal/src/constants.ts +++ /dev/null @@ -1,13 +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. - */ - -export const KIBANA_FEEDBACK_LINK = - 'https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback'; -export const KIBANA_ASK_ELASTIC_LINK = - 'https://www.elastic.co/products/kibana/ask-elastic?blade=kibanaaskelastic'; -export const GITHUB_CREATE_ISSUE_LINK = 'https://github.com/elastic/kibana/issues/new/choose'; diff --git a/packages/core/chrome/core-chrome-browser-internal/src/nav_controls/nav_controls_service.ts b/packages/core/chrome/core-chrome-browser-internal/src/nav_controls/nav_controls_service.ts index 36f448b187e139..1dada1d1324593 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/nav_controls/nav_controls_service.ts +++ b/packages/core/chrome/core-chrome-browser-internal/src/nav_controls/nav_controls_service.ts @@ -9,7 +9,11 @@ import { sortBy } from 'lodash'; import { BehaviorSubject, ReplaySubject } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; -import type { ChromeNavControl, ChromeNavControls } from '@kbn/core-chrome-browser'; +import type { + ChromeNavControl, + ChromeNavControls, + ChromeHelpMenuLink, +} from '@kbn/core-chrome-browser'; /** @internal */ export class NavControlsService { @@ -20,6 +24,7 @@ export class NavControlsService { const navControlsRight$ = new BehaviorSubject>(new Set()); const navControlsCenter$ = new BehaviorSubject>(new Set()); const navControlsExtension$ = new BehaviorSubject>(new Set()); + const helpMenuLinks$ = new BehaviorSubject([]); return { // In the future, registration should be moved to the setup phase. This @@ -36,6 +41,14 @@ export class NavControlsService { registerExtension: (navControl: ChromeNavControl) => navControlsExtension$.next(new Set([...navControlsExtension$.value.values(), navControl])), + setHelpMenuLinks: (links: ChromeHelpMenuLink[]) => { + // This extension point is only intended to be used once by the cloud integration > cloud_links plugin + if (helpMenuLinks$.value.length > 0) { + throw new Error(`Help menu links have already been set`); + } + helpMenuLinks$.next(links); + }, + getLeft$: () => navControlsLeft$.pipe( map((controls) => sortBy([...controls.values()], 'order')), @@ -56,6 +69,7 @@ export class NavControlsService { map((controls) => sortBy([...controls.values()], 'order')), takeUntil(this.stop$) ), + getHelpMenuLinks$: () => helpMenuLinks$.pipe(takeUntil(this.stop$)), }; } diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx index 1e05dafde05cdb..fa578579046170 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx @@ -8,10 +8,11 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, of } from 'rxjs'; import { StubBrowserStorage, mountWithIntl } from '@kbn/test-jest-helpers'; import { httpServiceMock } from '@kbn/core-http-browser-mocks'; import { applicationServiceMock } from '@kbn/core-application-browser-mocks'; +import { docLinksServiceMock } from '@kbn/core-doc-links-browser-mocks'; import type { ChromeBreadcrumbsAppendExtension } from '@kbn/core-chrome-browser'; import { Header } from './header'; @@ -30,6 +31,7 @@ function mockProps() { isVisible$: new BehaviorSubject(true), customBranding$: new BehaviorSubject({}), kibanaDocLink: '/docs', + docLinks: docLinksServiceMock.createStartContract(), navLinks$: new BehaviorSubject([]), customNavLink$: new BehaviorSubject(undefined), recentlyAccessed$: new BehaviorSubject([]), @@ -87,6 +89,7 @@ describe('Header', () => { customNavLink$={customNavLink$} breadcrumbsAppendExtension$={breadcrumbsAppendExtension$} headerBanner$={headerBanner$} + helpMenuLinks$={of([])} /> ); expect(component.find('EuiHeader').exists()).toBeFalsy(); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx index f1867cbea256d9..1a23c0a82f55bd 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx @@ -27,6 +27,7 @@ import type { ChromeBreadcrumb, ChromeNavControl, ChromeNavLink, + ChromeHelpMenuLink, ChromeRecentlyAccessedHistoryItem, ChromeBreadcrumbsAppendExtension, ChromeHelpExtension, @@ -34,6 +35,7 @@ import type { ChromeUserBanner, } from '@kbn/core-chrome-browser'; import { CustomBranding } from '@kbn/core-custom-branding-common'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import { LoadingIndicator } from '../loading_indicator'; import type { OnIsLockedUpdate } from './types'; import { CollapsibleNav } from './collapsible_nav'; @@ -59,12 +61,14 @@ export interface HeaderProps { homeHref: string; isVisible$: Observable; kibanaDocLink: string; + docLinks: DocLinksStart; navLinks$: Observable; recentlyAccessed$: Observable; forceAppSwitcherNavigation$: Observable; globalHelpExtensionMenuLinks$: Observable; helpExtension$: Observable; helpSupportUrl$: Observable; + helpMenuLinks$: Observable; navControlsLeft$: Observable; navControlsCenter$: Observable; navControlsRight$: Observable; @@ -79,6 +83,7 @@ export interface HeaderProps { export function Header({ kibanaVersion, kibanaDocLink, + docLinks, application, basePath, onIsLockedUpdate, @@ -163,7 +168,9 @@ export function Header({ globalHelpExtensionMenuLinks$={globalHelpExtensionMenuLinks$} helpExtension$={observables.helpExtension$} helpSupportUrl$={observables.helpSupportUrl$} + defaultContentLinks$={observables.helpMenuLinks$} kibanaDocLink={kibanaDocLink} + docLinks={docLinks} kibanaVersion={kibanaVersion} navigateToUrl={application.navigateToUrl} />, diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.test.tsx index d66982516d2514..5518667445a57f 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.test.tsx @@ -10,6 +10,8 @@ import React from 'react'; import { BehaviorSubject, of } from 'rxjs'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { applicationServiceMock } from '@kbn/core-application-browser-mocks'; +import { docLinksServiceMock } from '@kbn/core-doc-links-browser-mocks'; + import { HeaderHelpMenu } from './header_help_menu'; describe('HeaderHelpMenu', () => { @@ -26,14 +28,23 @@ describe('HeaderHelpMenu', () => { helpSupportUrl$={helpSupportUrl$} kibanaVersion={'version'} kibanaDocLink={''} + docLinks={docLinksServiceMock.createStartContract()} + defaultContentLinks$={of([])} /> ); expect(component.find('EuiButtonEmpty').length).toBe(1); // only the toggle view on/off button component.find('EuiButtonEmpty').simulate('click'); - // 4 default links + the toggle button - expect(component.find('EuiButtonEmpty').length).toBe(5); + const buttons = component.find('EuiButtonEmpty'); + const buttonTexts = buttons.map((button) => button.text()).filter((text) => text.trim() !== ''); + + expect(buttonTexts).toEqual([ + 'Kibana documentation', + 'Ask Elastic', + 'Give feedback', + 'Open an issue in GitHub', + ]); }); test('it renders the global custom content + the default content', () => { @@ -63,6 +74,8 @@ describe('HeaderHelpMenu', () => { helpSupportUrl$={helpSupportUrl$} kibanaVersion={'version'} kibanaDocLink={''} + docLinks={docLinksServiceMock.createStartContract()} + defaultContentLinks$={of([])} /> ); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx index 1d4813763a2010..e1e43d43ab4016 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx @@ -29,17 +29,56 @@ import type { ChromeHelpExtension, ChromeGlobalHelpExtensionMenuLink, } from '@kbn/core-chrome-browser'; -import { GITHUB_CREATE_ISSUE_LINK, KIBANA_FEEDBACK_LINK } from '../../constants'; +import type { ChromeHelpMenuLink } from '@kbn/core-chrome-browser/src'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; + import { HeaderExtension } from './header_extension'; import { isModifiedOrPrevented } from './nav_link'; +const buildDefaultContentLinks = ({ + kibanaDocLink, + docLinks, + helpSupportUrl, +}: { + kibanaDocLink: string; + docLinks: DocLinksStart; + helpSupportUrl: string; +}): ChromeHelpMenuLink[] => [ + { + title: i18n.translate('core.ui.chrome.headerGlobalNav.helpMenuKibanaDocumentationTitle', { + defaultMessage: 'Kibana documentation', + }), + href: kibanaDocLink, + }, + { + title: i18n.translate('core.ui.chrome.headerGlobalNav.helpMenuAskElasticTitle', { + defaultMessage: 'Ask Elastic', + }), + href: helpSupportUrl, + }, + { + title: i18n.translate('core.ui.chrome.headerGlobalNav.helpMenuGiveFeedbackTitle', { + defaultMessage: 'Give feedback', + }), + href: docLinks.links.kibana.feedback, + }, + { + title: i18n.translate('core.ui.chrome.headerGlobalNav.helpMenuOpenGitHubIssueTitle', { + defaultMessage: 'Open an issue in GitHub', + }), + href: docLinks.links.kibana.createGithubIssue, + }, +]; + interface Props { navigateToUrl: InternalApplicationStart['navigateToUrl']; globalHelpExtensionMenuLinks$: Observable; helpExtension$: Observable; helpSupportUrl$: Observable; + defaultContentLinks$: Observable; kibanaVersion: string; kibanaDocLink: string; + docLinks: DocLinksStart; } interface State { @@ -47,6 +86,7 @@ interface State { helpExtension?: ChromeHelpExtension; helpSupportUrl: string; globalHelpExtensionMenuLinks: ChromeGlobalHelpExtensionMenuLink[]; + defaultContentLinks: ChromeHelpMenuLink[]; } export class HeaderHelpMenu extends Component { @@ -60,6 +100,7 @@ export class HeaderHelpMenu extends Component { helpExtension: undefined, helpSupportUrl: '', globalHelpExtensionMenuLinks: [], + defaultContentLinks: [], }; } @@ -67,14 +108,21 @@ export class HeaderHelpMenu extends Component { this.subscription = combineLatest( this.props.helpExtension$, this.props.helpSupportUrl$, - this.props.globalHelpExtensionMenuLinks$ - ).subscribe(([helpExtension, helpSupportUrl, globalHelpExtensionMenuLinks]) => { - this.setState({ - helpExtension, - helpSupportUrl, - globalHelpExtensionMenuLinks, - }); - }); + this.props.globalHelpExtensionMenuLinks$, + this.props.defaultContentLinks$ + ).subscribe( + ([helpExtension, helpSupportUrl, globalHelpExtensionMenuLinks, defaultContentLinks]) => { + this.setState({ + helpExtension, + helpSupportUrl, + globalHelpExtensionMenuLinks, + defaultContentLinks: + defaultContentLinks.length === 0 + ? buildDefaultContentLinks({ ...this.props, helpSupportUrl }) + : defaultContentLinks, + }); + } + ); } public componentWillUnmount() { @@ -137,58 +185,33 @@ export class HeaderHelpMenu extends Component {
{globalCustomContent} {defaultContent} - {(defaultContent || customContent) && } - {customContent} + {customContent && ( + <> + + {customContent} + + )}
); } private renderDefaultContent() { - const { kibanaDocLink } = this.props; - const { helpSupportUrl } = this.state; + const { defaultContentLinks } = this.state; return ( - - - - - - - - - - - - - - - - - - - - - + {defaultContentLinks.map(({ href, title, iconType }, i) => { + const isLast = i === defaultContentLinks.length - 1; + return ( + + + {title} + + {!isLast && } + + ); + })} ); } diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx index 08ea2bcd5ba582..419e087436de3e 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx @@ -8,6 +8,7 @@ import { EuiHeader } from '@elastic/eui'; import { applicationServiceMock } from '@kbn/core-application-browser-mocks'; +import { docLinksServiceMock } from '@kbn/core-doc-links-browser-mocks'; import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import * as Rx from 'rxjs'; @@ -20,10 +21,11 @@ describe('Header', () => { application: mockApplication, breadcrumbs$: Rx.of([]), actionMenu$: Rx.of(undefined), - kibanaDocLink: 'app/help/doclinks', + docLinks: docLinksServiceMock.createStartContract(), globalHelpExtensionMenuLinks$: Rx.of([]), helpExtension$: Rx.of(undefined), helpSupportUrl$: Rx.of('app/help'), + helpMenuLinks$: Rx.of([]), homeHref$: Rx.of('app/home'), kibanaVersion: '8.9', loadingCount$: Rx.of(0), diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx index 92e40748c3ac26..1da457d289db1e 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx @@ -24,6 +24,7 @@ import { ChromeBreadcrumb, ChromeGlobalHelpExtensionMenuLink, ChromeHelpExtension, + ChromeHelpMenuLink, ChromeNavControl, } from '@kbn/core-chrome-browser/src'; import type { HttpStart } from '@kbn/core-http-browser'; @@ -34,6 +35,8 @@ import { Router } from '@kbn/shared-ux-router'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import useObservable from 'react-use/lib/useObservable'; import { Observable, debounceTime } from 'rxjs'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; + import { HeaderActionMenu, useHeaderActionMenuMounter } from '../header/header_action_menu'; import { HeaderBreadcrumbs } from '../header/header_breadcrumbs'; import { HeaderHelpMenu } from '../header/header_help_menu'; @@ -87,11 +90,12 @@ const headerStrings = { export interface Props { breadcrumbs$: Observable; actionMenu$: Observable; - kibanaDocLink: string; + docLinks: DocLinksStart; children: React.ReactNode; globalHelpExtensionMenuLinks$: Observable; helpExtension$: Observable; helpSupportUrl$: Observable; + helpMenuLinks$: Observable; homeHref$: Observable; kibanaVersion: string; application: InternalApplicationStart; @@ -158,10 +162,10 @@ const Logo = ( export const ProjectHeader = ({ application, - kibanaDocLink, kibanaVersion, children, prependBasePath, + docLinks, ...observables }: Props) => { const [navId] = useState(htmlIdGenerator()()); @@ -239,7 +243,9 @@ export const ProjectHeader = ({ globalHelpExtensionMenuLinks$={observables.globalHelpExtensionMenuLinks$} helpExtension$={observables.helpExtension$} helpSupportUrl$={observables.helpSupportUrl$} - kibanaDocLink={kibanaDocLink} + defaultContentLinks$={observables.helpMenuLinks$} + kibanaDocLink={docLinks.links.elasticStackGetStarted} + docLinks={docLinks} kibanaVersion={kibanaVersion} navigateToUrl={application.navigateToUrl} /> diff --git a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts index 76192aff162c7e..f1ce84f2f9be12 100644 --- a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts +++ b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, of } from 'rxjs'; import type { PublicMethodsOf } from '@kbn/utility-types'; import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ChromeBadge, ChromeBreadcrumb } from '@kbn/core-chrome-browser'; @@ -41,6 +41,8 @@ const createStartContractMock = () => { getCenter$: jest.fn(), getRight$: jest.fn(), getExtension$: jest.fn(), + setHelpMenuLinks: jest.fn(), + getHelpMenuLinks$: jest.fn(), }, setIsVisible: jest.fn(), getIsVisible$: jest.fn(), @@ -54,7 +56,9 @@ const createStartContractMock = () => { registerGlobalHelpExtensionMenuLink: jest.fn(), getHelpExtension$: jest.fn(), setHelpExtension: jest.fn(), + setHelpMenuLinks: jest.fn(), setHelpSupportUrl: jest.fn(), + getHelpSupportUrl$: jest.fn(() => of('https://www.elastic.co/support')), getIsNavDrawerLocked$: jest.fn(), getCustomNavLink$: jest.fn(), setCustomNavLink: jest.fn(), diff --git a/packages/core/chrome/core-chrome-browser/index.ts b/packages/core/chrome/core-chrome-browser/index.ts index c2d7243f34d6fe..d42d859cc6f3b8 100644 --- a/packages/core/chrome/core-chrome-browser/index.ts +++ b/packages/core/chrome/core-chrome-browser/index.ts @@ -14,6 +14,7 @@ export type { ChromeBreadcrumbsAppendExtension, ChromeDocTitle, ChromeGlobalHelpExtensionMenuLink, + ChromeHelpMenuLink, ChromeHelpExtension, ChromeHelpExtensionLinkBase, ChromeHelpExtensionMenuCustomLink, diff --git a/packages/core/chrome/core-chrome-browser/src/contracts.ts b/packages/core/chrome/core-chrome-browser/src/contracts.ts index f64995c877c7f7..c9893ed3863ce7 100644 --- a/packages/core/chrome/core-chrome-browser/src/contracts.ts +++ b/packages/core/chrome/core-chrome-browser/src/contracts.ts @@ -10,7 +10,7 @@ import type { Observable } from 'rxjs'; import type { ChromeNavLink, ChromeNavLinks } from './nav_links'; import type { ChromeRecentlyAccessed } from './recently_accessed'; import type { ChromeDocTitle } from './doc_title'; -import type { ChromeNavControls } from './nav_controls'; +import type { ChromeHelpMenuLink, ChromeNavControls } from './nav_controls'; import type { ChromeHelpExtension } from './help_extension'; import type { ChromeBreadcrumb, ChromeBreadcrumbsAppendExtension } from './breadcrumb'; import type { ChromeBadge, ChromeStyle, ChromeUserBanner } from './types'; @@ -106,6 +106,11 @@ export interface ChromeStart { */ setCustomNavLink(newCustomNavLink?: Partial): void; + /** + * Override the default links shown in the help menu + */ + setHelpMenuLinks(links: ChromeHelpMenuLink[]): void; + /** * Get the list of the registered global help extension menu links */ @@ -134,6 +139,11 @@ export interface ChromeStart { */ setHelpSupportUrl(url: string): void; + /** + * Get the support URL shown in the help menu + */ + getHelpSupportUrl$(): Observable; + /** * Get an observable of the current locked state of the nav drawer. */ diff --git a/packages/core/chrome/core-chrome-browser/src/index.ts b/packages/core/chrome/core-chrome-browser/src/index.ts index 858b1c4e3647a8..7a414fc87164e8 100644 --- a/packages/core/chrome/core-chrome-browser/src/index.ts +++ b/packages/core/chrome/core-chrome-browser/src/index.ts @@ -20,7 +20,7 @@ export type { ChromeHelpExtensionMenuGitHubLink, ChromeGlobalHelpExtensionMenuLink, } from './help_extension'; -export type { ChromeNavControls, ChromeNavControl } from './nav_controls'; +export type { ChromeNavControls, ChromeNavControl, ChromeHelpMenuLink } from './nav_controls'; export type { ChromeNavLinks, ChromeNavLink } from './nav_links'; export type { ChromeRecentlyAccessed, diff --git a/packages/core/chrome/core-chrome-browser/src/nav_controls.ts b/packages/core/chrome/core-chrome-browser/src/nav_controls.ts index 44529b1edf1227..39b5d1b3b59b14 100644 --- a/packages/core/chrome/core-chrome-browser/src/nav_controls.ts +++ b/packages/core/chrome/core-chrome-browser/src/nav_controls.ts @@ -15,6 +15,13 @@ export interface ChromeNavControl { mount: MountPoint; } +/** @public */ +export interface ChromeHelpMenuLink { + title: string; + href: string; + iconType?: string; +} + /** * {@link ChromeNavControls | APIs} for registering new controls to be displayed in the navigation bar. * @@ -44,6 +51,9 @@ export interface ChromeNavControls { /** Register an extension to be presented to the left of the top-right side of the chrome header. */ registerExtension(navControl: ChromeNavControl): void; + /** Set the help menu links */ + setHelpMenuLinks(links: ChromeHelpMenuLink[]): void; + /** @internal */ getLeft$(): Observable; @@ -55,4 +65,7 @@ export interface ChromeNavControls { /** @internal */ getExtension$(): Observable; + + /** @internal */ + getHelpMenuLinks$(): Observable; } diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index 959308de9d5fee..b47b0ab86ac3b5 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -20,6 +20,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { const DOC_LINK_VERSION = meta.version; const ELASTIC_WEBSITE_URL = meta.elasticWebsiteUrl; const DOCS_WEBSITE_URL = meta.docsWebsiteUrl; + const ELASTIC_GITHUB = meta.elasticGithubUrl; const ELASTICSEARCH_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`; const KIBANA_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/`; @@ -305,6 +306,9 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { }, addData: `${KIBANA_DOCS}connect-to-elasticsearch.html`, kibana: { + askElastic: `${ELASTIC_WEBSITE_URL}products/kibana/ask-elastic?blade=kibanaaskelastic`, + createGithubIssue: `${ELASTIC_GITHUB}kibana/issues/new/choose`, + feedback: `${ELASTIC_WEBSITE_URL}products/kibana/feedback?blade=kibanafeedback`, guide: `${KIBANA_DOCS}index.html`, autocompleteSuggestions: `${KIBANA_DOCS}kibana-concepts-analysts.html#autocomplete-suggestions`, secureSavedObject: `${KIBANA_DOCS}xpack-security-secure-saved-objects.html`, diff --git a/packages/kbn-doc-links/src/get_doc_meta.ts b/packages/kbn-doc-links/src/get_doc_meta.ts index e433b2acf1f041..46bd5fb0f06cf3 100644 --- a/packages/kbn-doc-links/src/get_doc_meta.ts +++ b/packages/kbn-doc-links/src/get_doc_meta.ts @@ -16,6 +16,7 @@ export const getDocLinksMeta = ({ kibanaBranch }: GetDocLinksMetaOptions): DocLi return { version: kibanaBranch === 'main' ? 'master' : kibanaBranch, elasticWebsiteUrl: 'https://www.elastic.co/', + elasticGithubUrl: 'https://github.com/elastic/', docsWebsiteUrl: 'https://docs.elastic.co/', }; }; diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index f99515b2d214e6..5f6b92ebd2a44e 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -12,6 +12,7 @@ export interface DocLinksMeta { version: string; elasticWebsiteUrl: string; + elasticGithubUrl: string; docsWebsiteUrl: string; } @@ -284,6 +285,9 @@ export interface DocLinks { }; readonly addData: string; readonly kibana: { + readonly askElastic: string; + readonly createGithubIssue: string; + readonly feedback: string; readonly guide: string; readonly autocompleteSuggestions: string; readonly secureSavedObject: string; diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 0f52afebcdc66b..eb7ca100c56f8b 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -17,7 +17,7 @@ pageLoadAssetSize: cloudExperiments: 59358 cloudFullStory: 18493 cloudGainsight: 18710 - cloudLinks: 17629 + cloudLinks: 55984 cloudSecurityPosture: 19109 console: 46091 contentManagement: 16254 diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index b6b53ce106c8cf..c4f5cf5a695689 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -215,6 +215,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.cloud_integrations.gain_sight.org_id (any)', 'xpack.cloud.id (string)', 'xpack.cloud.organization_url (string)', + 'xpack.cloud.billing_url (string)', 'xpack.cloud.profile_url (string)', 'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)', 'xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled (boolean)', diff --git a/x-pack/plugins/cloud/public/mocks.tsx b/x-pack/plugins/cloud/public/mocks.tsx index 38c63ecb5cfb84..187a8010dc5477 100644 --- a/x-pack/plugins/cloud/public/mocks.tsx +++ b/x-pack/plugins/cloud/public/mocks.tsx @@ -39,6 +39,7 @@ const createStartMock = (): jest.Mocked => ({ cloudId: 'mock-cloud-id', isCloudEnabled: true, deploymentUrl: 'deployment-url', + billingUrl: 'billing-url', profileUrl: 'profile-url', organizationUrl: 'organization-url', }); diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index 02c2c6d51d5caf..78bd6a8a9ef9ac 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -22,6 +22,7 @@ export interface CloudConfigType { base_url?: string; profile_url?: string; deployment_url?: string; + billing_url?: string; organization_url?: string; trial_end_date?: string; is_elastic_staff_owned?: boolean; @@ -30,6 +31,7 @@ export interface CloudConfigType { interface CloudUrls { deploymentUrl?: string; profileUrl?: string; + billingUrl?: string; organizationUrl?: string; snapshotsUrl?: string; } @@ -99,12 +101,13 @@ export class CloudPlugin implements Plugin { ); }; - const { deploymentUrl, profileUrl, organizationUrl } = this.getCloudUrls(); + const { deploymentUrl, profileUrl, billingUrl, organizationUrl } = this.getCloudUrls(); return { CloudContextProvider, isCloudEnabled: this.isCloudEnabled, cloudId: this.config.id, + billingUrl, deploymentUrl, profileUrl, organizationUrl, @@ -116,6 +119,7 @@ export class CloudPlugin implements Plugin { private getCloudUrls(): CloudUrls { const { profile_url: profileUrl, + billing_url: billingUrl, organization_url: organizationUrl, deployment_url: deploymentUrl, base_url: baseUrl, @@ -123,12 +127,14 @@ export class CloudPlugin implements Plugin { const fullCloudDeploymentUrl = getFullCloudUrl(baseUrl, deploymentUrl); const fullCloudProfileUrl = getFullCloudUrl(baseUrl, profileUrl); + const fullCloudBillingUrl = getFullCloudUrl(baseUrl, billingUrl); const fullCloudOrganizationUrl = getFullCloudUrl(baseUrl, organizationUrl); const fullCloudSnapshotsUrl = `${fullCloudDeploymentUrl}/${CLOUD_SNAPSHOTS_PATH}`; return { deploymentUrl: fullCloudDeploymentUrl, profileUrl: fullCloudProfileUrl, + billingUrl: fullCloudBillingUrl, organizationUrl: fullCloudOrganizationUrl, snapshotsUrl: fullCloudSnapshotsUrl, }; diff --git a/x-pack/plugins/cloud/public/types.ts b/x-pack/plugins/cloud/public/types.ts index ae862a981cd551..a482729fb7ac7f 100644 --- a/x-pack/plugins/cloud/public/types.ts +++ b/x-pack/plugins/cloud/public/types.ts @@ -28,6 +28,10 @@ export interface CloudStart { * The full URL to the user profile page on Elastic Cloud. Undefined if not running on Cloud. */ profileUrl?: string; + /** + * The full URL to the billing page on Elastic Cloud. Undefined if not running on Cloud. + */ + billingUrl?: string; /** * The full URL to the organization management page on Elastic Cloud. Undefined if not running on Cloud. */ diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts index 028298c2da3314..7420b2b13b36b9 100644 --- a/x-pack/plugins/cloud/server/config.ts +++ b/x-pack/plugins/cloud/server/config.ts @@ -24,6 +24,7 @@ const configSchema = schema.object({ cname: schema.maybe(schema.string()), deployment_url: schema.maybe(schema.string()), id: schema.maybe(schema.string()), + billing_url: schema.maybe(schema.string()), organization_url: schema.maybe(schema.string()), profile_url: schema.maybe(schema.string()), trial_end_date: schema.maybe(schema.string()), @@ -38,6 +39,7 @@ export const config: PluginConfigDescriptor = { cname: true, deployment_url: true, id: true, + billing_url: true, organization_url: true, profile_url: true, trial_end_date: true, diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts new file mode 100644 index 00000000000000..82b0e86e6569a1 --- /dev/null +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/help_menu_links.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ChromeHelpMenuLink } from '@kbn/core-chrome-browser'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; + +export const createHelpMenuLinks = ({ + docLinks, + helpSupportUrl, +}: { + docLinks: DocLinksStart; + helpSupportUrl: string; +}) => { + const helpMenuLinks: ChromeHelpMenuLink[] = [ + { + title: i18n.translate('xpack.cloudLinks.helpMenuLinks.documentation', { + defaultMessage: 'Documentation', + }), + href: docLinks.links.elasticStackGetStarted, + }, + { + title: i18n.translate('xpack.cloudLinks.helpMenuLinks.support', { + defaultMessage: 'Support', + }), + href: helpSupportUrl, + }, + { + title: i18n.translate('xpack.cloudLinks.helpMenuLinks.giveFeedback', { + defaultMessage: 'Give feedback', + }), + href: docLinks.links.kibana.feedback, + }, + ]; + + return helpMenuLinks; +}; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts index 4bc8edd057b6ea..16d29325502e11 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts @@ -18,6 +18,7 @@ describe('maybeAddCloudLinks', () => { security, chrome: coreMock.createStart().chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: false }, + docLinks: coreMock.createStart().docLinks, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -29,11 +30,12 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: true }) ); - const chrome = coreMock.createStart().chrome; + const { chrome, docLinks } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, + docLinks, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -55,15 +57,41 @@ describe('maybeAddCloudLinks', () => { Object { "href": "profile-url", "iconType": "user", - "label": "Edit profile", + "label": "Profile", "order": 100, "setAsProfile": true, }, + Object { + "href": "billing-url", + "iconType": "visGauge", + "label": "Billing", + "order": 200, + }, Object { "href": "organization-url", "iconType": "gear", - "label": "Account & Billing", - "order": 200, + "label": "Organization", + "order": 300, + }, + ], + ] + `); + + expect(chrome.setHelpMenuLinks).toHaveBeenCalledTimes(1); + expect(chrome.setHelpMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "href": "https://www.elastic.co/guide/en/index.html", + "title": "Documentation", + }, + Object { + "href": "https://www.elastic.co/support", + "title": "Support", + }, + Object { + "href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback", + "title": "Give feedback", }, ], ] @@ -73,11 +101,12 @@ describe('maybeAddCloudLinks', () => { it('when cloud enabled and it fails to fetch the user, it sets the links', async () => { const security = securityMock.createStart(); security.authc.getCurrentUser.mockRejectedValue(new Error('Something went terribly wrong')); - const chrome = coreMock.createStart().chrome; + const { chrome, docLinks } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, + docLinks, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -99,15 +128,40 @@ describe('maybeAddCloudLinks', () => { Object { "href": "profile-url", "iconType": "user", - "label": "Edit profile", + "label": "Profile", "order": 100, "setAsProfile": true, }, + Object { + "href": "billing-url", + "iconType": "visGauge", + "label": "Billing", + "order": 200, + }, Object { "href": "organization-url", "iconType": "gear", - "label": "Account & Billing", - "order": 200, + "label": "Organization", + "order": 300, + }, + ], + ] + `); + expect(chrome.setHelpMenuLinks).toHaveBeenCalledTimes(1); + expect(chrome.setHelpMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "href": "https://www.elastic.co/guide/en/index.html", + "title": "Documentation", + }, + Object { + "href": "https://www.elastic.co/support", + "title": "Support", + }, + Object { + "href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback", + "title": "Give feedback", }, ], ] @@ -119,16 +173,18 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: false }) ); - const chrome = coreMock.createStart().chrome; + const { chrome, docLinks } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, + docLinks, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); expect(security.authc.getCurrentUser).toHaveBeenCalledTimes(1); expect(chrome.setCustomNavLink).not.toHaveBeenCalled(); expect(security.navControlService.addUserMenuLinks).not.toHaveBeenCalled(); + expect(chrome.setHelpMenuLinks).not.toHaveBeenCalledTimes(1); }); }); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts index 383709e1e7e8ce..3d7aa271ed8665 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts @@ -5,44 +5,63 @@ * 2.0. */ -import { catchError, defer, filter, map, of } from 'rxjs'; +import { catchError, defer, filter, map, of, combineLatest } from 'rxjs'; import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; import type { ChromeStart } from '@kbn/core/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import { createUserMenuLinks } from './user_menu_links'; +import { createHelpMenuLinks } from './help_menu_links'; export interface MaybeAddCloudLinksDeps { security: SecurityPluginStart; chrome: ChromeStart; cloud: CloudStart; + docLinks: DocLinksStart; } -export function maybeAddCloudLinks({ security, chrome, cloud }: MaybeAddCloudLinksDeps): void { +export function maybeAddCloudLinks({ + security, + chrome, + cloud, + docLinks, +}: MaybeAddCloudLinksDeps): void { + const userObservable = defer(() => security.authc.getCurrentUser()).pipe( + // Check if user is a cloud user. + map((user) => user.elastic_cloud_user), + // If user is not defined due to an unexpected error, then fail *open*. + catchError(() => of(true)), + filter((isElasticCloudUser) => isElasticCloudUser === true), + map(() => { + if (cloud.deploymentUrl) { + chrome.setCustomNavLink({ + title: i18n.translate('xpack.cloudLinks.deploymentLinkLabel', { + defaultMessage: 'Manage this deployment', + }), + euiIconType: 'logoCloud', + href: cloud.deploymentUrl, + }); + } + const userMenuLinks = createUserMenuLinks(cloud); + security.navControlService.addUserMenuLinks(userMenuLinks); + }) + ); + + const helpObservable = chrome.getHelpSupportUrl$(); + if (cloud.isCloudEnabled) { - defer(() => security.authc.getCurrentUser()) - .pipe( - // Check if user is a cloud user. - map((user) => user.elastic_cloud_user), - // If user is not defined due to an unexpected error, then fail *open*. - catchError(() => of(true)), - filter((isElasticCloudUser) => isElasticCloudUser === true), - map(() => { - if (cloud.deploymentUrl) { - chrome.setCustomNavLink({ - title: i18n.translate('xpack.cloudLinks.deploymentLinkLabel', { - defaultMessage: 'Manage this deployment', - }), - euiIconType: 'logoCloud', - href: cloud.deploymentUrl, - }); - } - const userMenuLinks = createUserMenuLinks(cloud); - security.navControlService.addUserMenuLinks(userMenuLinks); - }) - ) - .subscribe(); + combineLatest({ user: userObservable, helpSupportUrl: helpObservable }).subscribe( + ({ helpSupportUrl }) => { + const helpMenuLinks = createHelpMenuLinks({ + docLinks, + helpSupportUrl, + }); + + chrome.setHelpMenuLinks(helpMenuLinks); + } + ); } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts index 9b0ab8faac5a54..b6996a2f8f5a29 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts @@ -10,13 +10,14 @@ import type { CloudStart } from '@kbn/cloud-plugin/public'; import type { UserMenuLink } from '@kbn/security-plugin/public'; export const createUserMenuLinks = (cloud: CloudStart): UserMenuLink[] => { - const { profileUrl, organizationUrl } = cloud; + const { profileUrl, billingUrl, organizationUrl } = cloud; + const userMenuLinks = [] as UserMenuLink[]; if (profileUrl) { userMenuLinks.push({ label: i18n.translate('xpack.cloudLinks.userMenuLinks.profileLinkText', { - defaultMessage: 'Edit profile', + defaultMessage: 'Profile', }), iconType: 'user', href: profileUrl, @@ -25,14 +26,25 @@ export const createUserMenuLinks = (cloud: CloudStart): UserMenuLink[] => { }); } + if (billingUrl) { + userMenuLinks.push({ + label: i18n.translate('xpack.cloudLinks.userMenuLinks.billingLinkText', { + defaultMessage: 'Billing', + }), + iconType: 'visGauge', + href: billingUrl, + order: 200, + }); + } + if (organizationUrl) { userMenuLinks.push({ - label: i18n.translate('xpack.cloudLinks.userMenuLinks.accountLinkText', { - defaultMessage: 'Account & Billing', + label: i18n.translate('xpack.cloudLinks.userMenuLinks.organizationLinkText', { + defaultMessage: 'Organization', }), iconType: 'gear', href: organizationUrl, - order: 200, + order: 300, }); } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx index a2f8af345ac0a0..1eb490ba0cd3ad 100755 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx @@ -43,7 +43,7 @@ export class CloudLinksPlugin }); } if (security) { - maybeAddCloudLinks({ security, chrome: core.chrome, cloud }); + maybeAddCloudLinks({ security, chrome: core.chrome, cloud, docLinks: core.docLinks }); } } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json index ab4f52a3475910..a57da9edc31996 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json +++ b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json @@ -17,6 +17,8 @@ "@kbn/i18n", "@kbn/i18n-react", "@kbn/guided-onboarding-plugin", + "@kbn/core-chrome-browser", + "@kbn/core-doc-links-browser", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 730b9def5cfba3..d28554d63bbc32 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -39320,7 +39320,6 @@ "xpack.cloudDataMigration.upgrade.text": "Effectuer la mise à niveau vers les versions plus récentes beaucoup plus facilement", "xpack.cloudLinks.deploymentLinkLabel": "Gérer ce déploiement", "xpack.cloudLinks.setupGuide": "Guides de configuration", - "xpack.cloudLinks.userMenuLinks.accountLinkText": "Compte et facturation", "xpack.cloudLinks.userMenuLinks.profileLinkText": "Modifier le profil", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "Choisir le tableau de bord de destination", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "Ouvrir le tableau de bord dans un nouvel onglet", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 3b16e422bdef5f..d8763e4030c788 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -39294,7 +39294,6 @@ "xpack.cloudDataMigration.upgrade.text": "新しいバージョンへのアップグレードがより簡単に", "xpack.cloudLinks.deploymentLinkLabel": "このデプロイの管理", "xpack.cloudLinks.setupGuide": "セットアップガイド", - "xpack.cloudLinks.userMenuLinks.accountLinkText": "会計・請求", "xpack.cloudLinks.userMenuLinks.profileLinkText": "プロフィールを編集", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "対象ダッシュボードを選択", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "新しいタブでダッシュボードを開く", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0443aa6e236cab..59d89ca3145511 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -39288,7 +39288,6 @@ "xpack.cloudDataMigration.upgrade.text": "更轻松地升级到较新版本", "xpack.cloudLinks.deploymentLinkLabel": "管理此部署", "xpack.cloudLinks.setupGuide": "设置指南", - "xpack.cloudLinks.userMenuLinks.accountLinkText": "帐户和帐单", "xpack.cloudLinks.userMenuLinks.profileLinkText": "编辑配置文件", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "选择目标仪表板", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "在新选项卡中打开仪表板", diff --git a/x-pack/test/functional_cloud/config.ts b/x-pack/test/functional_cloud/config.ts index bfcb34d15de437..c3203677631a99 100644 --- a/x-pack/test/functional_cloud/config.ts +++ b/x-pack/test/functional_cloud/config.ts @@ -48,6 +48,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { '--xpack.cloud.base_url=https://cloud.elastic.co', '--xpack.cloud.deployment_url=/deployments/deploymentId', '--xpack.cloud.organization_url=/organization/organizationId', + '--xpack.cloud.billing_url=/billing', '--xpack.cloud.profile_url=/user/userId', '--xpack.security.authc.selector.enabled=false', `--xpack.security.authc.providers=${JSON.stringify({ diff --git a/x-pack/test/functional_cloud/tests/cloud_links.ts b/x-pack/test/functional_cloud/tests/cloud_links.ts index 0d5ab43837b23e..743df23740fb41 100644 --- a/x-pack/test/functional_cloud/tests/cloud_links.ts +++ b/x-pack/test/functional_cloud/tests/cloud_links.ts @@ -55,18 +55,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); describe('Fills up the user menu items', () => { - it('Shows the button Edit profile', async () => { - await PageObjects.common.clickAndValidate('userMenuButton', 'userMenuLink__Edit profile'); - const cloudLink = await find.byLinkText('Edit profile'); + it('Shows the button Profile', async () => { + await PageObjects.common.clickAndValidate('userMenuButton', 'userMenuLink__Profile'); + const cloudLink = await find.byLinkText('Profile'); expect(cloudLink).to.not.be(null); }); - it('Shows the button Account & Billing', async () => { - await PageObjects.common.clickAndValidate( - 'userMenuButton', - 'userMenuLink__Account & Billing' - ); - const cloudLink = await find.byLinkText('Account & Billing'); + it('Shows the button Billing', async () => { + await PageObjects.common.clickAndValidate('userMenuButton', 'userMenuLink__Billing'); + const cloudLink = await find.byLinkText('Billing'); + expect(cloudLink).to.not.be(null); + }); + + it('Shows the button Organization', async () => { + await PageObjects.common.clickAndValidate('userMenuButton', 'userMenuLink__Organization'); + const cloudLink = await find.byLinkText('Organization'); expect(cloudLink).to.not.be(null); }); }); From e31ede27dec84f8fd5b671375e6a5f8b6e09d90d Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Sun, 2 Jul 2023 17:03:45 -0400 Subject: [PATCH 09/98] [RAM] Remove third party RRule library, replace with own timezone-compliant lib (#152873) ## Summary Closes #152630 ~Adds a fix for the weird UTC-but-not-really expected inputs in rrule.js~ This PR removes the third-party `rrule` package and replaces it with `@kbn/rrule`. The third party RRule library's functions produced different results depending on what system timezone you ran it in. It would output local timestamps in UTC, making it impossible to do reliable math on them. It's now replaced with our own library that passes all of our own tests for the limited cross-section of the RRule spec that we need to support. It's possible that it wouldn't stand up to the rigor of more complex RRule queries, but it supports the ones that our Recurrence Scheduler UI supports just fine. ### 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: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + package.json | 2 +- packages/kbn-rrule/README.md | 70 ++ packages/kbn-rrule/index.ts | 11 + packages/kbn-rrule/jest.config.js | 13 + packages/kbn-rrule/kibana.jsonc | 5 + packages/kbn-rrule/package.json | 6 + packages/kbn-rrule/rrule.test.ts | 874 ++++++++++++++++++ packages/kbn-rrule/rrule.ts | 432 +++++++++ packages/kbn-rrule/tsconfig.json | 19 + tsconfig.base.json | 2 + x-pack/plugins/alerting/common/rrule_type.ts | 22 +- .../custom_recurring_schedule.test.tsx | 3 +- .../custom_recurring_schedule.tsx | 7 +- .../recurring_schedule.test.tsx | 3 +- .../recurring_schedule.tsx | 2 +- .../maintenance_windows/components/schema.ts | 7 +- .../pages/maintenance_windows/constants.ts | 12 +- ...rt_from_maintenance_window_to_form.test.ts | 25 +- ...convert_from_maintenance_window_to_form.ts | 7 +- .../helpers/convert_to_rrule.test.ts | 28 +- .../helpers/convert_to_rrule.ts | 10 +- .../helpers/get_presets.ts | 2 +- .../helpers/recurring_summary.test.ts | 2 +- .../helpers/recurring_summary.ts | 14 +- .../pages/maintenance_windows/translations.ts | 2 +- .../public/pages/maintenance_windows/types.ts | 16 +- .../server/lib/is_rule_snoozed.test.ts | 100 +- .../alerting/server/lib/rrule/index.ts | 8 - .../server/lib/rrule/parse_by_weekday.ts | 13 - .../alerting/server/lib/snooze/index.ts | 1 - .../lib/snooze/is_snooze_active.test.ts | 24 +- .../server/lib/snooze/is_snooze_active.ts | 30 +- .../lib/snooze/is_snooze_expired.test.ts | 18 +- .../server/lib/snooze/is_snooze_expired.ts | 9 +- .../server/lib/snooze/timezone_helpers.ts | 32 - .../server/lib/validate_snooze_schedule.ts | 2 +- ...generate_maintenance_window_events.test.ts | 10 +- .../generate_maintenance_window_events.ts | 23 +- .../methods/archive.test.ts | 4 +- .../methods/finish.test.ts | 8 +- .../methods/test_helpers.ts | 4 +- .../methods/update.test.ts | 8 +- .../server/routes/lib/rrule_schema.ts | 6 +- .../update_maintenance_window.test.ts | 4 +- x-pack/plugins/alerting/tsconfig.json | 9 +- yarn.lock | 15 +- 47 files changed, 1640 insertions(+), 285 deletions(-) create mode 100644 packages/kbn-rrule/README.md create mode 100644 packages/kbn-rrule/index.ts create mode 100644 packages/kbn-rrule/jest.config.js create mode 100644 packages/kbn-rrule/kibana.jsonc create mode 100644 packages/kbn-rrule/package.json create mode 100644 packages/kbn-rrule/rrule.test.ts create mode 100644 packages/kbn-rrule/rrule.ts create mode 100644 packages/kbn-rrule/tsconfig.json delete mode 100644 x-pack/plugins/alerting/server/lib/rrule/index.ts delete mode 100644 x-pack/plugins/alerting/server/lib/rrule/parse_by_weekday.ts delete mode 100644 x-pack/plugins/alerting/server/lib/snooze/timezone_helpers.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bfe7bdb251c60b..9f41080bd5a59f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -552,6 +552,7 @@ examples/response_stream @elastic/ml-ui packages/kbn-rison @elastic/kibana-operations x-pack/plugins/rollup @elastic/platform-deployment-management examples/routing_example @elastic/kibana-core +packages/kbn-rrule @elastic/response-ops packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/actionable-observability @elastic/response-ops x-pack/plugins/rule_registry @elastic/response-ops @elastic/actionable-observability x-pack/plugins/runtime_fields @elastic/platform-deployment-management diff --git a/package.json b/package.json index 2fce048b215570..9a3366b65ee29d 100644 --- a/package.json +++ b/package.json @@ -555,6 +555,7 @@ "@kbn/rison": "link:packages/kbn-rison", "@kbn/rollup-plugin": "link:x-pack/plugins/rollup", "@kbn/routing-example-plugin": "link:examples/routing_example", + "@kbn/rrule": "link:packages/kbn-rrule", "@kbn/rule-data-utils": "link:packages/kbn-rule-data-utils", "@kbn/rule-registry-plugin": "link:x-pack/plugins/rule_registry", "@kbn/runtime-fields-plugin": "link:x-pack/plugins/runtime_fields", @@ -965,7 +966,6 @@ "require-in-the-middle": "^6.0.0", "reselect": "^4.1.6", "rison-node": "1.0.2", - "rrule": "2.6.4", "rxjs": "^7.5.5", "safe-squel": "^5.12.5", "seedrandom": "^3.0.5", diff --git a/packages/kbn-rrule/README.md b/packages/kbn-rrule/README.md new file mode 100644 index 00000000000000..fd59b0d019c4cd --- /dev/null +++ b/packages/kbn-rrule/README.md @@ -0,0 +1,70 @@ +# @kbn/rrule + +A rewrite of [rrule.js](https://github.com/jakubroztocil/rrule) using `moment-timezone` for timezone support. Ensures that we always get the same outputs no matter what local timezone the executing system is set to. + +Differences from library on Github: + +- It is **recommended** to generate input Dates from UTC timestamps, but not required. This implementation will perform calculations on inputted Dates accurate to their corresponding Unix timestamps. +- Timezones IDs are required. They're very important for dealing with things like day-of-week changes or DST. +- `inc` argument from `between`, `before`, `after` is removed, and is computed as if it were `true` +- SECONDLY frequency is not implemented. +- This implementation may not accurately support the entire [iCalendar RRULE RFC](https://www.rfc-editor.org/rfc/rfc5545). It is known to work for common scenarios configurable in the Recurrence Scheduler UI, plus some other more complicated ones. See `rrule.test.ts` for known working configurations. + +Known not to work are mostly edge cases: + +- Manually configuring `setpos` with any frequency besides `MONTHLY` +- `wkst` doesn't seem to have an effect on anything (I was also unable to get it to affect anything in the original library though) +- Setting `byyearday` on anything besides `Frequency.YEARLY`, setting `bymonthday` on anything besides `MONTHLY`, and other similar odd situations + +## Constructor + +Create an RRule with the following options: + +```ts +new RRule({ + dtstart: Date; // Recommended to generate this from a UTC timestamp, but this impl + tzid: string; // Takes a Moment.js timezone string. Recommended to use a country and city for DST accuracy, e.g. America/Phoenix and America/Denver are both in Mountain time but Phoenix doesn't observe DST + freq?: Frequency; // Defaults to YEARLY + interval?: number; // Every x freq, e.g. 1 and YEARLY is every 1 year, 2 and WEEKLY is every 2 weeks + until?: Date; // Recur until this date + count?: number; // Number of times this rule should recur until it stops + wkst?: Weekday | number; // Start of week, defaults to Monday + // The following, if not provided, will be automatically derived from the dtstart + byweekday?: Weekday[] | string[]; // Day(s) of the week to recur, OR nth-day-of-month strings, e.g. "+2TU" second Tuesday of month, "-1FR" last Friday of the month, which will get internally converted to a byweekday/bysetpos combination + bysetpos?: number[]; // Positive or negative integer affecting nth day of the month, eg -2 combined with byweekday of FR is 2nd to last Friday of the month. Best not to set this manually and just use byweekday. + byyearday?: number[]; // Day(s) of the year that this rule should recur, e.g. 32 is Feb 1. Respects leap years. + bymonth?: number[]; // Month(s) of the year that this rule should recur + bymonthday?: number[]; // Day(s) of the momth to recur + byhour?: number[]; // Hour(s) of the day to recur + byminute?: number[]; // Minute(s) of the hour to recur + bysecond?: number[]; // Seconds(s) of the day to recur +}); +``` + +## Methods + +### `RRule.prototype.all(limit?: number)` + +returns `Date[] & { hasMore?: boolean}` + +Returns an array all dates matching the rule. By default, limited to 10000 iterations. Pass something to `limit` to change this. + +If it hits the limit, the array will come back with the property `hasMore: true`. + +### `RRule.prototype.before(dt: Date)` + +returns `Date | null` + +Returns the last recurrence before `dt`, or `null` if there is none. + +### RRule.prototype.after(dt: Date)` + +returns `Date | null` + +Returns the last recurrence after `dt`, or `null` if there is none. + +### RRule.prototype.between(start: Date, end: Date)` + +returns `Date[]` + +Returns an array of all dates between `start` and `end`. diff --git a/packages/kbn-rrule/index.ts b/packages/kbn-rrule/index.ts new file mode 100644 index 00000000000000..1ae5fab3a76995 --- /dev/null +++ b/packages/kbn-rrule/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { RRule, Frequency, Weekday } from './rrule'; +export type { Options } from './rrule'; +export declare type WeekdayStr = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU'; diff --git a/packages/kbn-rrule/jest.config.js b/packages/kbn-rrule/jest.config.js new file mode 100644 index 00000000000000..fc3a26dabddd79 --- /dev/null +++ b/packages/kbn-rrule/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../..', + roots: ['/packages/kbn-rrule'], +}; diff --git a/packages/kbn-rrule/kibana.jsonc b/packages/kbn-rrule/kibana.jsonc new file mode 100644 index 00000000000000..08878a6cfb1e9f --- /dev/null +++ b/packages/kbn-rrule/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/rrule", + "owner": "@elastic/response-ops" +} diff --git a/packages/kbn-rrule/package.json b/packages/kbn-rrule/package.json new file mode 100644 index 00000000000000..79f75e59db7373 --- /dev/null +++ b/packages/kbn-rrule/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/rrule", + "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-rrule/rrule.test.ts b/packages/kbn-rrule/rrule.test.ts new file mode 100644 index 00000000000000..468195315621be --- /dev/null +++ b/packages/kbn-rrule/rrule.test.ts @@ -0,0 +1,874 @@ +/* + * Copyright 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 sinon from 'sinon'; +import { RRule, Frequency, Weekday } from './rrule'; + +const DATE_2019 = '2019-01-01T00:00:00.000Z'; +const DATE_2019_DECEMBER_19 = '2019-12-19T00:00:00.000Z'; +const DATE_2019_FEB_28 = '2019-02-28T00:00:00.000Z'; +const DATE_2020 = '2020-01-01T00:00:00.000Z'; +const DATE_2020_MINUS_1_MONTH = '2019-12-01T00:00:00.000Z'; +const DATE_2020_FEB_28 = '2020-02-28T00:00:00.000Z'; +const DATE_2023 = '2023-01-01T00:00:00.000Z'; +const DATE_2023_JAN_6_11PM = '2023-01-06T23:00:00Z'; + +const INVALID_DATE = '2020-01-01-01-01T:00:00:00Z'; + +const NOW = DATE_2020; + +let fakeTimer: sinon.SinonFakeTimers; + +describe('RRule', () => { + beforeAll(() => { + fakeTimer = sinon.useFakeTimers(new Date(NOW)); + }); + + afterAll(() => fakeTimer.restore()); + + describe('frequency', () => { + it('works with yearly', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.YEARLY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule.all(10)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2020-01-01T00:00:00.000Z, + 2021-01-01T00:00:00.000Z, + 2022-01-01T00:00:00.000Z, + 2023-01-01T00:00:00.000Z, + 2024-01-01T00:00:00.000Z, + 2025-01-01T00:00:00.000Z, + 2026-01-01T00:00:00.000Z, + 2027-01-01T00:00:00.000Z, + 2028-01-01T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2020), + freq: Frequency.YEARLY, + interval: 3, + tzid: 'UTC', + }); + + expect(rule2.all(10)).toMatchInlineSnapshot(` + Array [ + 2020-01-01T00:00:00.000Z, + 2023-01-01T00:00:00.000Z, + 2026-01-01T00:00:00.000Z, + 2029-01-01T00:00:00.000Z, + 2032-01-01T00:00:00.000Z, + 2035-01-01T00:00:00.000Z, + 2038-01-01T00:00:00.000Z, + 2041-01-01T00:00:00.000Z, + 2044-01-01T00:00:00.000Z, + 2047-01-01T00:00:00.000Z, + ] + `); + }); + + it('works with monthly', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MONTHLY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule.all(15)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-02-01T00:00:00.000Z, + 2019-03-01T00:00:00.000Z, + 2019-04-01T00:00:00.000Z, + 2019-05-01T00:00:00.000Z, + 2019-06-01T00:00:00.000Z, + 2019-07-01T00:00:00.000Z, + 2019-08-01T00:00:00.000Z, + 2019-09-01T00:00:00.000Z, + 2019-10-01T00:00:00.000Z, + 2019-11-01T00:00:00.000Z, + 2019-12-01T00:00:00.000Z, + 2020-01-01T00:00:00.000Z, + 2020-02-01T00:00:00.000Z, + 2020-03-01T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MONTHLY, + interval: 6, + tzid: 'UTC', + }); + + expect(rule2.all(6)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-07-01T00:00:00.000Z, + 2020-01-01T00:00:00.000Z, + 2020-07-01T00:00:00.000Z, + 2021-01-01T00:00:00.000Z, + 2021-07-01T00:00:00.000Z, + ] + `); + + const rule3 = new RRule({ + dtstart: new Date(DATE_2019), + bymonthday: [10, 20], + freq: Frequency.MONTHLY, + interval: 6, + tzid: 'UTC', + }); + + expect(rule3.all(6)).toMatchInlineSnapshot(` + Array [ + 2019-01-10T00:00:00.000Z, + 2019-01-20T00:00:00.000Z, + 2019-07-10T00:00:00.000Z, + 2019-07-20T00:00:00.000Z, + 2020-01-10T00:00:00.000Z, + 2020-01-20T00:00:00.000Z, + ] + `); + }); + + it('works with weekly', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2019-12-26T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-09T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-23T00:00:00.000Z, + 2020-01-30T00:00:00.000Z, + 2020-02-06T00:00:00.000Z, + 2020-02-13T00:00:00.000Z, + 2020-02-20T00:00:00.000Z, + 2020-02-27T00:00:00.000Z, + 2020-03-05T00:00:00.000Z, + 2020-03-12T00:00:00.000Z, + 2020-03-19T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.WEEKLY, + interval: 2, + tzid: 'UTC', + }); + + expect(rule2.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-30T00:00:00.000Z, + 2020-02-13T00:00:00.000Z, + 2020-02-27T00:00:00.000Z, + 2020-03-12T00:00:00.000Z, + 2020-03-26T00:00:00.000Z, + 2020-04-09T00:00:00.000Z, + 2020-04-23T00:00:00.000Z, + 2020-05-07T00:00:00.000Z, + 2020-05-21T00:00:00.000Z, + 2020-06-04T00:00:00.000Z, + 2020-06-18T00:00:00.000Z, + ] + `); + }); + + it('works with daily', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule.all(30)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2019-12-20T00:00:00.000Z, + 2019-12-21T00:00:00.000Z, + 2019-12-22T00:00:00.000Z, + 2019-12-23T00:00:00.000Z, + 2019-12-24T00:00:00.000Z, + 2019-12-25T00:00:00.000Z, + 2019-12-26T00:00:00.000Z, + 2019-12-27T00:00:00.000Z, + 2019-12-28T00:00:00.000Z, + 2019-12-29T00:00:00.000Z, + 2019-12-30T00:00:00.000Z, + 2019-12-31T00:00:00.000Z, + 2020-01-01T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-03T00:00:00.000Z, + 2020-01-04T00:00:00.000Z, + 2020-01-05T00:00:00.000Z, + 2020-01-06T00:00:00.000Z, + 2020-01-07T00:00:00.000Z, + 2020-01-08T00:00:00.000Z, + 2020-01-09T00:00:00.000Z, + 2020-01-10T00:00:00.000Z, + 2020-01-11T00:00:00.000Z, + 2020-01-12T00:00:00.000Z, + 2020-01-13T00:00:00.000Z, + 2020-01-14T00:00:00.000Z, + 2020-01-15T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-17T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.DAILY, + interval: 48, + tzid: 'UTC', + }); + + expect(rule2.all(12)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2020-02-05T00:00:00.000Z, + 2020-03-24T00:00:00.000Z, + 2020-05-11T00:00:00.000Z, + 2020-06-28T00:00:00.000Z, + 2020-08-15T00:00:00.000Z, + 2020-10-02T00:00:00.000Z, + 2020-11-19T00:00:00.000Z, + 2021-01-06T00:00:00.000Z, + 2021-02-23T00:00:00.000Z, + 2021-04-12T00:00:00.000Z, + 2021-05-30T00:00:00.000Z, + ] + `); + + const rule3 = new RRule({ + dtstart: new Date(DATE_2019_FEB_28), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule3.all(6)).toMatchInlineSnapshot(` + Array [ + 2019-02-28T00:00:00.000Z, + 2019-03-01T00:00:00.000Z, + 2019-03-02T00:00:00.000Z, + 2019-03-03T00:00:00.000Z, + 2019-03-04T00:00:00.000Z, + 2019-03-05T00:00:00.000Z, + ] + `); + + const rule4 = new RRule({ + dtstart: new Date(DATE_2020_FEB_28), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule4.all(6)).toMatchInlineSnapshot(` + Array [ + 2020-02-28T00:00:00.000Z, + 2020-02-29T00:00:00.000Z, + 2020-03-01T00:00:00.000Z, + 2020-03-02T00:00:00.000Z, + 2020-03-03T00:00:00.000Z, + 2020-03-04T00:00:00.000Z, + ] + `); + }); + + it('works with hourly', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.HOURLY, + interval: 1, + tzid: 'UTC', + }); + + expect(rule.all(30)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-01-01T01:00:00.000Z, + 2019-01-01T02:00:00.000Z, + 2019-01-01T03:00:00.000Z, + 2019-01-01T04:00:00.000Z, + 2019-01-01T05:00:00.000Z, + 2019-01-01T06:00:00.000Z, + 2019-01-01T07:00:00.000Z, + 2019-01-01T08:00:00.000Z, + 2019-01-01T09:00:00.000Z, + 2019-01-01T10:00:00.000Z, + 2019-01-01T11:00:00.000Z, + 2019-01-01T12:00:00.000Z, + 2019-01-01T13:00:00.000Z, + 2019-01-01T14:00:00.000Z, + 2019-01-01T15:00:00.000Z, + 2019-01-01T16:00:00.000Z, + 2019-01-01T17:00:00.000Z, + 2019-01-01T18:00:00.000Z, + 2019-01-01T19:00:00.000Z, + 2019-01-01T20:00:00.000Z, + 2019-01-01T21:00:00.000Z, + 2019-01-01T22:00:00.000Z, + 2019-01-01T23:00:00.000Z, + 2019-01-02T00:00:00.000Z, + 2019-01-02T01:00:00.000Z, + 2019-01-02T02:00:00.000Z, + 2019-01-02T03:00:00.000Z, + 2019-01-02T04:00:00.000Z, + 2019-01-02T05:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.HOURLY, + interval: 36, + tzid: 'UTC', + }); + + expect(rule2.all(30)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-01-02T12:00:00.000Z, + 2019-01-04T00:00:00.000Z, + 2019-01-05T12:00:00.000Z, + 2019-01-07T00:00:00.000Z, + 2019-01-08T12:00:00.000Z, + 2019-01-10T00:00:00.000Z, + 2019-01-11T12:00:00.000Z, + 2019-01-13T00:00:00.000Z, + 2019-01-14T12:00:00.000Z, + 2019-01-16T00:00:00.000Z, + 2019-01-17T12:00:00.000Z, + 2019-01-19T00:00:00.000Z, + 2019-01-20T12:00:00.000Z, + 2019-01-22T00:00:00.000Z, + 2019-01-23T12:00:00.000Z, + 2019-01-25T00:00:00.000Z, + 2019-01-26T12:00:00.000Z, + 2019-01-28T00:00:00.000Z, + 2019-01-29T12:00:00.000Z, + 2019-01-31T00:00:00.000Z, + 2019-02-01T12:00:00.000Z, + 2019-02-03T00:00:00.000Z, + 2019-02-04T12:00:00.000Z, + 2019-02-06T00:00:00.000Z, + 2019-02-07T12:00:00.000Z, + 2019-02-09T00:00:00.000Z, + 2019-02-10T12:00:00.000Z, + 2019-02-12T00:00:00.000Z, + 2019-02-13T12:00:00.000Z, + ] + `); + }); + + it('works with minutely', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MINUTELY, + interval: 15, + tzid: 'UTC', + }); + + expect(rule.all(10)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-01-01T00:15:00.000Z, + 2019-01-01T00:30:00.000Z, + 2019-01-01T00:45:00.000Z, + 2019-01-01T01:00:00.000Z, + 2019-01-01T01:15:00.000Z, + 2019-01-01T01:30:00.000Z, + 2019-01-01T01:45:00.000Z, + 2019-01-01T02:00:00.000Z, + 2019-01-01T02:15:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MINUTELY, + interval: 36, + tzid: 'UTC', + }); + + expect(rule2.all(30)).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-01-01T00:36:00.000Z, + 2019-01-01T01:12:00.000Z, + 2019-01-01T01:48:00.000Z, + 2019-01-01T02:24:00.000Z, + 2019-01-01T03:00:00.000Z, + 2019-01-01T03:36:00.000Z, + 2019-01-01T04:12:00.000Z, + 2019-01-01T04:48:00.000Z, + 2019-01-01T05:24:00.000Z, + 2019-01-01T06:00:00.000Z, + 2019-01-01T06:36:00.000Z, + 2019-01-01T07:12:00.000Z, + 2019-01-01T07:48:00.000Z, + 2019-01-01T08:24:00.000Z, + 2019-01-01T09:00:00.000Z, + 2019-01-01T09:36:00.000Z, + 2019-01-01T10:12:00.000Z, + 2019-01-01T10:48:00.000Z, + 2019-01-01T11:24:00.000Z, + 2019-01-01T12:00:00.000Z, + 2019-01-01T12:36:00.000Z, + 2019-01-01T13:12:00.000Z, + 2019-01-01T13:48:00.000Z, + 2019-01-01T14:24:00.000Z, + 2019-01-01T15:00:00.000Z, + 2019-01-01T15:36:00.000Z, + 2019-01-01T16:12:00.000Z, + 2019-01-01T16:48:00.000Z, + 2019-01-01T17:24:00.000Z, + ] + `); + }); + }); + + it('works with until', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MONTHLY, + interval: 1, + tzid: 'UTC', + until: new Date(DATE_2020_MINUS_1_MONTH), + }); + expect(rule.all().length).toBe(12); + }); + + it('works with count', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.MONTHLY, + interval: 1, + tzid: 'UTC', + count: 20, + }); + expect(rule.all()).toMatchInlineSnapshot(` + Array [ + 2019-01-01T00:00:00.000Z, + 2019-02-01T00:00:00.000Z, + 2019-03-01T00:00:00.000Z, + 2019-04-01T00:00:00.000Z, + 2019-05-01T00:00:00.000Z, + 2019-06-01T00:00:00.000Z, + 2019-07-01T00:00:00.000Z, + 2019-08-01T00:00:00.000Z, + 2019-09-01T00:00:00.000Z, + 2019-10-01T00:00:00.000Z, + 2019-11-01T00:00:00.000Z, + 2019-12-01T00:00:00.000Z, + 2020-01-01T00:00:00.000Z, + 2020-02-01T00:00:00.000Z, + 2020-03-01T00:00:00.000Z, + 2020-04-01T00:00:00.000Z, + 2020-05-01T00:00:00.000Z, + 2020-06-01T00:00:00.000Z, + 2020-07-01T00:00:00.000Z, + 2020-08-01T00:00:00.000Z, + ] + `); + }); + + describe('byweekday', () => { + it('works with weekly frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.TH], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2019-12-26T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-09T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-23T00:00:00.000Z, + 2020-01-30T00:00:00.000Z, + 2020-02-06T00:00:00.000Z, + 2020-02-13T00:00:00.000Z, + 2020-02-20T00:00:00.000Z, + 2020-02-27T00:00:00.000Z, + 2020-03-05T00:00:00.000Z, + 2020-03-12T00:00:00.000Z, + 2020-03-19T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.SA, Weekday.SU, Weekday.MO], + }); + + expect(rule2.all(9)).toMatchInlineSnapshot(` + Array [ + 2019-01-05T00:00:00.000Z, + 2019-01-06T00:00:00.000Z, + 2019-01-07T00:00:00.000Z, + 2019-01-12T00:00:00.000Z, + 2019-01-13T00:00:00.000Z, + 2019-01-14T00:00:00.000Z, + 2019-01-19T00:00:00.000Z, + 2019-01-20T00:00:00.000Z, + 2019-01-21T00:00:00.000Z, + ] + `); + }); + + it('works with daily frequency by behaving like weekly frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.TH], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2019-12-26T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-09T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-23T00:00:00.000Z, + 2020-01-30T00:00:00.000Z, + 2020-02-06T00:00:00.000Z, + 2020-02-13T00:00:00.000Z, + 2020-02-20T00:00:00.000Z, + 2020-02-27T00:00:00.000Z, + 2020-03-05T00:00:00.000Z, + 2020-03-12T00:00:00.000Z, + 2020-03-19T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.SA, Weekday.SU, Weekday.MO], + }); + + expect(rule2.all(9)).toMatchInlineSnapshot(` + Array [ + 2019-01-05T00:00:00.000Z, + 2019-01-06T00:00:00.000Z, + 2019-01-07T00:00:00.000Z, + 2019-01-12T00:00:00.000Z, + 2019-01-13T00:00:00.000Z, + 2019-01-14T00:00:00.000Z, + 2019-01-19T00:00:00.000Z, + 2019-01-20T00:00:00.000Z, + 2019-01-21T00:00:00.000Z, + ] + `); + }); + + it('works with monthly frequency with non-setpos syntax by behaving like weekly frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.TH], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:00.000Z, + 2019-12-26T00:00:00.000Z, + 2020-01-02T00:00:00.000Z, + 2020-01-09T00:00:00.000Z, + 2020-01-16T00:00:00.000Z, + 2020-01-23T00:00:00.000Z, + 2020-01-30T00:00:00.000Z, + 2020-02-06T00:00:00.000Z, + 2020-02-13T00:00:00.000Z, + 2020-02-20T00:00:00.000Z, + 2020-02-27T00:00:00.000Z, + 2020-03-05T00:00:00.000Z, + 2020-03-12T00:00:00.000Z, + 2020-03-19T00:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2019), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.SA, Weekday.SU, Weekday.MO], + }); + + expect(rule2.all(9)).toMatchInlineSnapshot(` + Array [ + 2019-01-05T00:00:00.000Z, + 2019-01-06T00:00:00.000Z, + 2019-01-07T00:00:00.000Z, + 2019-01-12T00:00:00.000Z, + 2019-01-13T00:00:00.000Z, + 2019-01-14T00:00:00.000Z, + 2019-01-19T00:00:00.000Z, + 2019-01-20T00:00:00.000Z, + 2019-01-21T00:00:00.000Z, + ] + `); + }); + + it('works with monthly frequency using setpos syntax', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2023), + freq: Frequency.MONTHLY, + interval: 1, + tzid: 'UTC', + byweekday: ['+1TU', '+2TU', '-1FR', '-2FR'], + }); + const result = rule.all(12); + + expect(result).toMatchInlineSnapshot(` + Array [ + 2023-01-03T00:00:00.000Z, + 2023-01-10T00:00:00.000Z, + 2023-01-20T00:00:00.000Z, + 2023-01-27T00:00:00.000Z, + 2023-02-07T00:00:00.000Z, + 2023-02-14T00:00:00.000Z, + 2023-02-17T00:00:00.000Z, + 2023-02-24T00:00:00.000Z, + 2023-03-07T00:00:00.000Z, + 2023-03-14T00:00:00.000Z, + 2023-03-24T00:00:00.000Z, + 2023-03-31T00:00:00.000Z, + ] + `); + }); + + it('works with timezones', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2023_JAN_6_11PM), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'Europe/Madrid', + byweekday: [Weekday.SA], + }); + expect(rule.all(12)).toMatchInlineSnapshot(` + Array [ + 2023-01-06T23:00:00.000Z, + 2023-01-13T23:00:00.000Z, + 2023-01-20T23:00:00.000Z, + 2023-01-27T23:00:00.000Z, + 2023-02-03T23:00:00.000Z, + 2023-02-10T23:00:00.000Z, + 2023-02-17T23:00:00.000Z, + 2023-02-24T23:00:00.000Z, + 2023-03-03T23:00:00.000Z, + 2023-03-10T23:00:00.000Z, + 2023-03-17T23:00:00.000Z, + 2023-03-24T23:00:00.000Z, + ] + `); + + const rule2 = new RRule({ + dtstart: new Date(DATE_2023_JAN_6_11PM), + freq: Frequency.WEEKLY, + interval: 1, + tzid: 'UTC', + byweekday: [Weekday.SA], + }); + + expect(rule2.all(12)).toMatchInlineSnapshot(` + Array [ + 2023-01-07T23:00:00.000Z, + 2023-01-14T23:00:00.000Z, + 2023-01-21T23:00:00.000Z, + 2023-01-28T23:00:00.000Z, + 2023-02-04T23:00:00.000Z, + 2023-02-11T23:00:00.000Z, + 2023-02-18T23:00:00.000Z, + 2023-02-25T23:00:00.000Z, + 2023-03-04T23:00:00.000Z, + 2023-03-11T23:00:00.000Z, + 2023-03-18T23:00:00.000Z, + 2023-03-25T23:00:00.000Z, + ] + `); + }); + }); + + describe('byhour, byminute, bysecond', () => { + it('works with daily frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.DAILY, + interval: 1, + tzid: 'UTC', + byhour: [14], + byminute: [30], + bysecond: [0, 15], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T14:30:00.000Z, + 2019-12-19T14:30:15.000Z, + 2019-12-20T14:30:00.000Z, + 2019-12-20T14:30:15.000Z, + 2019-12-21T14:30:00.000Z, + 2019-12-21T14:30:15.000Z, + 2019-12-22T14:30:00.000Z, + 2019-12-22T14:30:15.000Z, + 2019-12-23T14:30:00.000Z, + 2019-12-23T14:30:15.000Z, + 2019-12-24T14:30:00.000Z, + 2019-12-24T14:30:15.000Z, + 2019-12-25T14:30:00.000Z, + 2019-12-25T14:30:15.000Z, + ] + `); + }); + it('works with hourly frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.HOURLY, + interval: 1, + tzid: 'UTC', + byminute: [15, 30], + bysecond: [30, 0], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:15:30.000Z, + 2019-12-19T00:15:00.000Z, + 2019-12-19T00:30:30.000Z, + 2019-12-19T00:30:00.000Z, + 2019-12-19T01:15:30.000Z, + 2019-12-19T01:15:00.000Z, + 2019-12-19T01:30:30.000Z, + 2019-12-19T01:30:00.000Z, + 2019-12-19T02:15:30.000Z, + 2019-12-19T02:15:00.000Z, + 2019-12-19T02:30:30.000Z, + 2019-12-19T02:30:00.000Z, + 2019-12-19T03:15:30.000Z, + 2019-12-19T03:15:00.000Z, + ] + `); + }); + it('works with minutely frequency', () => { + const rule = new RRule({ + dtstart: new Date(DATE_2019_DECEMBER_19), + freq: Frequency.HOURLY, + interval: 1, + tzid: 'UTC', + bysecond: [10, 30, 58], + }); + expect(rule.all(14)).toMatchInlineSnapshot(` + Array [ + 2019-12-19T00:00:10.000Z, + 2019-12-19T00:00:30.000Z, + 2019-12-19T00:00:58.000Z, + 2019-12-19T00:01:10.000Z, + 2019-12-19T00:01:30.000Z, + 2019-12-19T00:01:58.000Z, + 2019-12-19T00:02:10.000Z, + 2019-12-19T00:02:30.000Z, + 2019-12-19T00:02:58.000Z, + 2019-12-19T00:03:10.000Z, + 2019-12-19T00:03:30.000Z, + 2019-12-19T00:03:58.000Z, + 2019-12-19T00:04:10.000Z, + 2019-12-19T00:04:30.000Z, + ] + `); + }); + }); + + describe('byyearday', () => { + it('respects leap years', () => { + const rule3 = new RRule({ + dtstart: new Date(DATE_2020), + freq: Frequency.YEARLY, + byyearday: [92], + interval: 1, + tzid: 'UTC', + }); + + expect(rule3.all(10)).toMatchInlineSnapshot(` + Array [ + 2020-04-01T00:00:00.000Z, + 2021-04-02T00:00:00.000Z, + 2022-04-02T00:00:00.000Z, + 2023-04-02T00:00:00.000Z, + 2024-04-01T00:00:00.000Z, + 2025-04-02T00:00:00.000Z, + 2026-04-02T00:00:00.000Z, + 2027-04-02T00:00:00.000Z, + 2028-04-01T00:00:00.000Z, + 2029-04-02T00:00:00.000Z, + ] + `); + }); + }); + + describe('error handling', () => { + it('throws an error on an invalid dtstart', () => { + const testFn = () => + new RRule({ + dtstart: new Date(INVALID_DATE), + freq: Frequency.HOURLY, + interval: 1, + tzid: 'UTC', + }); + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Cannot create RRule: dtstart is an invalid date"` + ); + }); + it('throws an error on an invalid until', () => { + const testFn = () => + new RRule({ + dtstart: new Date(DATE_2020), + until: new Date(INVALID_DATE), + freq: Frequency.HOURLY, + interval: 1, + tzid: 'UTC', + }); + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Cannot create RRule: until is an invalid date"` + ); + }); + }); +}); diff --git a/packages/kbn-rrule/rrule.ts b/packages/kbn-rrule/rrule.ts new file mode 100644 index 00000000000000..347a3f986bf12f --- /dev/null +++ b/packages/kbn-rrule/rrule.ts @@ -0,0 +1,432 @@ +/* + * Copyright 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 moment, { Moment } from 'moment-timezone'; + +export enum Frequency { + YEARLY = 0, + MONTHLY = 1, + WEEKLY = 2, + DAILY = 3, + HOURLY = 4, + MINUTELY = 5, +} + +export enum Weekday { + MO = 1, + TU = 2, + WE = 3, + TH = 4, + FR = 5, + SA = 6, + SU = 7, +} + +export type WeekdayStr = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU'; +interface IterOptions { + refDT: Moment; + wkst?: Weekday | number | null; + byyearday?: number[] | null; + bymonth?: number[] | null; + bysetpos?: number[] | null; + bymonthday?: number[] | null; + byweekday?: Weekday[] | null; + byhour?: number[] | null; + byminute?: number[] | null; + bysecond?: number[] | null; +} + +type Options = Omit & { + dtstart: Date; + freq?: Frequency; + interval?: number; + until?: Date | null; + count?: number; + tzid: string; +}; + +type ConstructorOptions = Omit & { + byweekday?: Array | null; + wkst?: Weekday | WeekdayStr | number | null; +}; + +export type { ConstructorOptions as Options }; + +const ISO_WEEKDAYS = [ + Weekday.MO, + Weekday.TU, + Weekday.WE, + Weekday.TH, + Weekday.FR, + Weekday.SA, + Weekday.SU, +]; + +type AllResult = Date[] & { + hasMore?: boolean; +}; + +const ALL_LIMIT = 10000; + +export class RRule { + private options: Options; + constructor(options: ConstructorOptions) { + this.options = options as Options; + if (isNaN(options.dtstart.getTime())) { + throw new Error('Cannot create RRule: dtstart is an invalid date'); + } + if (options.until && isNaN(options.until.getTime())) { + throw new Error('Cannot create RRule: until is an invalid date'); + } + if (typeof options.wkst === 'string') { + this.options.wkst = Weekday[options.wkst]; + } + const weekdayParseResult = parseByWeekdayPos(options.byweekday); + if (weekdayParseResult) { + this.options.byweekday = weekdayParseResult[0]; + this.options.bysetpos = weekdayParseResult[1]; + } + } + + private *dateset(start?: Date, end?: Date): Generator { + const isAfterDtStart = (current: Date) => current.getTime() >= this.options.dtstart.getTime(); + const isInBounds = (current: Date) => { + const afterStart = !start || current.getTime() >= start.getTime(); + const beforeEnd = !end || current.getTime() <= end.getTime(); + + return afterStart && beforeEnd; + }; + + const { dtstart, tzid, count, until } = this.options; + let isFirstIteration = true; + let yieldedRecurrenceCount = 0; + let current: Date = moment(dtstart ?? new Date()) + .tz(tzid) + .toDate(); + + const nextRecurrences: Moment[] = []; + + while ( + (!count && !until) || + (count && yieldedRecurrenceCount < count) || + (until && current.getTime() < new Date(until).getTime()) + ) { + const next = nextRecurrences.shift()?.toDate(); + if (next) { + current = next; + if (!isAfterDtStart(current)) continue; + yieldedRecurrenceCount++; + if (isInBounds(current)) { + yield current; + } else if (start && current.getTime() > start.getTime()) { + return null; + } + } else { + getNextRecurrences({ + refDT: moment(current).tz(tzid), + ...this.options, + interval: isFirstIteration ? 0 : this.options.interval, + wkst: this.options.wkst ? (this.options.wkst as Weekday) : Weekday.MO, + }).forEach((r) => nextRecurrences.push(r)); + isFirstIteration = false; + if (nextRecurrences.length === 0) { + return null; + } + } + } + + return null; + } + + between(start: Date, end: Date) { + const dates = this.dateset(start, end); + return [...dates]; + } + + before(dt: Date) { + const dates = [...this.dateset(this.options.dtstart, dt)]; + return dates[dates.length - 1]; + } + + after(dt: Date) { + const dates = this.dateset(dt); + return dates.next().value; + } + + all(limit: number = ALL_LIMIT): AllResult { + const dateGenerator = this.dateset(); + const dates: AllResult = []; + let next = dateGenerator.next(); + for (let i = 0; i < limit; i++) { + if (!next.done) dates.push(next.value); + else break; + next = dateGenerator.next(); + } + if (next.done) return dates; + else { + dates.hasMore = true; + return dates; + } + } +} + +const parseByWeekdayPos = function (byweekday: ConstructorOptions['byweekday']) { + if (byweekday?.some((d) => typeof d === 'string')) { + const pos: number[] = []; + const newByweekday = byweekday.map((d) => { + if (typeof d !== 'string') return d; + if (Object.keys(Weekday).includes(d)) return Weekday[d as WeekdayStr]; + const [sign, number, ...rest] = d.split(''); + if (sign === '-') pos.push(-Number(number)); + else pos.push(Number(number)); + return Weekday[rest.join('') as WeekdayStr]; + }); + return [newByweekday, pos]; + } else return null; +}; + +export const getNextRecurrences = function ({ + refDT, + wkst = Weekday.MO, + byyearday, + bymonth, + bymonthday, + byweekday, + byhour, + byminute, + bysecond, + bysetpos, + freq = Frequency.YEARLY, + interval = 1, +}: IterOptions & { + freq?: Frequency; + interval?: number; +}) { + const opts = { + wkst, + byyearday, + bymonth, + bymonthday, + byweekday, + byhour, + byminute, + bysecond, + bysetpos, + }; + + // If the frequency is DAILY but there's a byweekday, or if the frequency is MONTHLY with a byweekday with no + // corresponding bysetpos, use the WEEKLY code path to determine recurrences + const derivedFreq = + byweekday && (freq === Frequency.DAILY || (freq === Frequency.MONTHLY && !bysetpos?.length)) + ? Frequency.WEEKLY + : freq; + + switch (derivedFreq) { + case Frequency.YEARLY: { + const nextRef = moment(refDT).add(interval, 'y'); + return getYearOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + case Frequency.MONTHLY: { + const nextRef = moment(refDT).add(interval, 'M'); + return getMonthOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + case Frequency.WEEKLY: { + const nextRef = moment(refDT).add(interval, 'w'); + return getWeekOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + case Frequency.DAILY: { + const nextRef = moment(refDT).add(interval, 'd'); + return getDayOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + case Frequency.HOURLY: { + const nextRef = moment(refDT).add(interval, 'h'); + return getHourOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + case Frequency.MINUTELY: { + const nextRef = moment(refDT).add(interval, 'm'); + return getMinuteOfRecurrences({ + refDT: nextRef, + ...opts, + }); + } + } +}; + +const sortByweekday = function ({ + wkst, + byweekday, +}: { + wkst?: Weekday | null; + byweekday: Weekday[]; +}) { + const weekStart = wkst ?? Weekday.MO; + const weekdays = ISO_WEEKDAYS.slice(weekStart - 1).concat(ISO_WEEKDAYS.slice(0, weekStart - 1)); + return [...byweekday].sort((a, b) => weekdays.indexOf(a) - weekdays.indexOf(b)); +}; + +const getYearOfRecurrences = function ({ + refDT, + wkst, + byyearday, + bymonth, + bymonthday, + byweekday, + byhour, + byminute, + bysecond, + bysetpos, +}: IterOptions) { + const derivedByweekday = byweekday ?? ISO_WEEKDAYS; + + if (bymonth) { + return bymonth.flatMap((month) => { + const currentMonth = moment(refDT).month(month - 1); + return getMonthOfRecurrences({ + refDT: currentMonth, + wkst, + bymonthday, + byweekday, + byhour, + byminute, + bysecond, + bysetpos, + }); + }); + } + + const derivedByyearday = byyearday ?? [refDT.dayOfYear()]; + + return derivedByyearday.flatMap((dayOfYear) => { + const currentDate = moment(refDT).dayOfYear(dayOfYear); + if (!derivedByweekday.includes(currentDate.isoWeekday())) return []; + return getDayOfRecurrences({ refDT: currentDate, byhour, byminute, bysecond }); + }); +}; + +const getMonthOfRecurrences = function ({ + refDT, + wkst, + bymonthday, + bymonth, + byweekday, + byhour, + byminute, + bysecond, + bysetpos, +}: IterOptions) { + const derivedByweekday = byweekday ?? ISO_WEEKDAYS; + const currentMonth = refDT.month(); + if (bymonth && !bymonth.includes(currentMonth)) return []; + + let derivedBymonthday = bymonthday ?? [refDT.date()]; + if (bysetpos) { + const firstOfMonth = moment(refDT).month(currentMonth).date(1); + const dowLookup: Record = { + 1: [], + 2: [], + 3: [], + 4: [], + 5: [], + 6: [], + 7: [], + }; + const trackedDate = firstOfMonth; + while (trackedDate.month() === currentMonth) { + const currentDow = trackedDate.isoWeekday() as Weekday; + dowLookup[currentDow].push(trackedDate.date()); + trackedDate.add(1, 'd'); + } + const sortedByweekday = sortByweekday({ wkst, byweekday: derivedByweekday }); + const bymonthdayFromPos = bysetpos.map((pos, i) => { + const correspondingWeekday = sortedByweekday[i]; + const lookup = dowLookup[correspondingWeekday]; + if (pos > 0) return [lookup[pos - 1], pos]; + return [lookup.slice(pos)[0], pos]; + }); + + const posPositions = [ + // Start with positive numbers in ascending order + ...bymonthdayFromPos + .filter(([, p]) => p > 0) + .sort(([, a], [, b]) => a - b) + .map(([date]) => date), + ]; + const negPositions = [ + // then negative numbers in descending order] + ...bymonthdayFromPos + .filter(([, p]) => p < 0) + .sort(([, a], [, b]) => a - b) + .map(([date]) => date), + ]; + derivedBymonthday = [...posPositions, ...negPositions]; + } + + return derivedBymonthday.flatMap((date) => { + const currentDate = moment(refDT).date(date); + if (!derivedByweekday.includes(currentDate.isoWeekday())) return []; + return getDayOfRecurrences({ refDT: currentDate, byhour, byminute, bysecond }); + }); +}; + +const getWeekOfRecurrences = function ({ + refDT, + wkst = Weekday.MO, + byweekday, + byhour, + byminute, + bysecond, +}: IterOptions) { + const derivedByweekday = byweekday ? sortByweekday({ wkst, byweekday }) : [refDT.isoWeekday()]; + + return derivedByweekday.flatMap((day) => { + const currentDay = moment(refDT).isoWeekday(day); + return getDayOfRecurrences({ refDT: currentDay, byhour, byminute, bysecond }); + }); +}; + +const getDayOfRecurrences = function ({ refDT, byhour, byminute, bysecond }: IterOptions) { + const derivedByhour = + byhour ?? (byminute || bysecond ? Array.from(Array(24), (_, i) => i) : [refDT.hour()]); + + return derivedByhour.flatMap((h) => { + const currentHour = moment(refDT).hour(h); + return getHourOfRecurrences({ refDT: currentHour, byminute, bysecond }); + }); +}; + +const getHourOfRecurrences = function ({ refDT, byminute, bysecond }: IterOptions) { + const derivedByminute = + byminute ?? (bysecond ? Array.from(Array(60), (_, i) => i) : [refDT.minute()]); + + return derivedByminute.flatMap((m) => { + const currentMinute = moment(refDT).minute(m); + return getMinuteOfRecurrences({ refDT: currentMinute, bysecond }); + }); +}; + +const getMinuteOfRecurrences = function ({ refDT, bysecond }: IterOptions) { + const derivedBysecond = bysecond ?? [refDT.second()]; + + return derivedBysecond.map((s) => { + return moment(refDT).second(s); + }); +}; diff --git a/packages/kbn-rrule/tsconfig.json b/packages/kbn-rrule/tsconfig.json new file mode 100644 index 00000000000000..87f865132f4b46 --- /dev/null +++ b/packages/kbn-rrule/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 610d9704b4d90c..6db4864f58f05b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1098,6 +1098,8 @@ "@kbn/rollup-plugin/*": ["x-pack/plugins/rollup/*"], "@kbn/routing-example-plugin": ["examples/routing_example"], "@kbn/routing-example-plugin/*": ["examples/routing_example/*"], + "@kbn/rrule": ["packages/kbn-rrule"], + "@kbn/rrule/*": ["packages/kbn-rrule/*"], "@kbn/rule-data-utils": ["packages/kbn-rule-data-utils"], "@kbn/rule-data-utils/*": ["packages/kbn-rule-data-utils/*"], "@kbn/rule-registry-plugin": ["x-pack/plugins/rule_registry"], diff --git a/x-pack/plugins/alerting/common/rrule_type.ts b/x-pack/plugins/alerting/common/rrule_type.ts index 2405e2b25b7eb4..7d250a0302317d 100644 --- a/x-pack/plugins/alerting/common/rrule_type.ts +++ b/x-pack/plugins/alerting/common/rrule_type.ts @@ -5,26 +5,14 @@ * 2.0. */ -import type { WeekdayStr } from 'rrule'; +import type { WeekdayStr, Options } from '@kbn/rrule'; export type RRuleParams = Partial & Pick; // An iCal RRULE to define a recurrence schedule, see https://github.com/jakubroztocil/rrule for the spec -export interface RRuleRecord { +export type RRuleRecord = Omit & { dtstart: string; - tzid: string; - freq?: 0 | 1 | 2 | 3 | 4 | 5 | 6; - until?: string; - count?: number; - interval?: number; + byweekday?: Array; wkst?: WeekdayStr; - byweekday?: Array; - bymonth?: number[]; - bysetpos?: number[]; - bymonthday: number[]; - byyearday: number[]; - byweekno: number[]; - byhour: number[]; - byminute: number[]; - bysecond: number[]; -} + until?: string; +}; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx index 67f2af2d5df2ce..92e792e4523e4b 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.test.tsx @@ -8,10 +8,11 @@ import React from 'react'; import { fireEvent, waitFor, within } from '@testing-library/react'; import { useForm, Form } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { Frequency } from '@kbn/rrule'; import { AppMockRenderer, createAppMockRenderer } from '../../../../lib/test_utils'; import { FormProps, schema } from '../schema'; import { CustomRecurringSchedule } from './custom_recurring_schedule'; -import { EndsOptions, Frequency } from '../../constants'; +import { EndsOptions } from '../../constants'; const initialValue: FormProps = { title: 'test', diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx index 939896271bbaca..749b5b8b5be301 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx @@ -5,6 +5,7 @@ * 2.0. */ import React, { useMemo } from 'react'; +import { Frequency } from '@kbn/rrule'; import moment from 'moment'; import { css } from '@emotion/react'; import { @@ -17,7 +18,7 @@ import { MultiButtonGroupFieldValue, } from '@kbn/es-ui-shared-plugin/static/forms/components'; import { EuiFlexGroup, EuiFlexItem, EuiFormLabel, EuiSpacer } from '@elastic/eui'; -import { CREATE_FORM_CUSTOM_FREQUENCY, Frequency, WEEKDAY_OPTIONS } from '../../constants'; +import { CREATE_FORM_CUSTOM_FREQUENCY, WEEKDAY_OPTIONS } from '../../constants'; import * as i18n from '../../translations'; import { getInitialByWeekday } from '../../helpers/get_initial_by_weekday'; import { getWeekdayInfo } from '../../helpers/get_weekday_info'; @@ -105,7 +106,7 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { ) : null} - {recurringSchedule?.customFrequency === Frequency.WEEKLY || + {Number(recurringSchedule?.customFrequency) === Frequency.WEEKLY || recurringSchedule?.frequency === Frequency.DAILY ? ( { /> ) : null} - {recurringSchedule?.customFrequency === Frequency.MONTHLY ? ( + {Number(recurringSchedule?.customFrequency) === Frequency.MONTHLY ? ( ; bymonth?: string; } diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts index 36fb85cff6b0f2..22b992e3e63822 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts @@ -5,17 +5,15 @@ * 2.0. */ import { invert, mapValues } from 'lodash'; +import { Frequency } from '@kbn/rrule'; import moment from 'moment'; import * as i18n from './translations'; import { ISO_WEEKDAYS, MaintenanceWindowStatus } from '../../../common'; -// TODO - consolidate enum with backend -export enum Frequency { - YEARLY = '0', - MONTHLY = '1', - WEEKLY = '2', - DAILY = '3', -} +export type MaintenanceWindowFrequency = Extract< + Frequency, + Frequency.YEARLY | Frequency.MONTHLY | Frequency.WEEKLY | Frequency.DAILY +>; export const DEFAULT_FREQUENCY_OPTIONS = [ { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.test.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.test.ts index c892f7db667293..eb187823a685ba 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.test.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.test.ts @@ -7,8 +7,7 @@ import moment from 'moment'; -import { Frequency } from '../constants'; -import { RRuleFrequency } from '../types'; +import { Frequency } from '@kbn/rrule'; import { convertFromMaintenanceWindowToForm } from './convert_from_maintenance_window_to_form'; describe('convertFromMaintenanceWindowToForm', () => { @@ -25,7 +24,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, count: 1, }, }); @@ -46,7 +45,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], }, @@ -76,7 +75,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], until, @@ -106,7 +105,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], count: 3, @@ -136,7 +135,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, byweekday: ['WE'], }, @@ -164,7 +163,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, byweekday: ['+4WE'], }, @@ -192,7 +191,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, interval: 1, bymonth: [3], bymonthday: [22], @@ -220,7 +219,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, }, }); @@ -247,7 +246,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, byweekday: ['WE', 'TH'], }, @@ -276,7 +275,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, bymonthday: [22], }, @@ -305,7 +304,7 @@ describe('convertFromMaintenanceWindowToForm', () => { rRule: { dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, interval: 3, bymonth: [3], bymonthday: [22], diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.ts index 954e6b8bd2658a..f29265c4c7f3a4 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.ts @@ -6,9 +6,10 @@ */ import moment from 'moment'; +import { Frequency } from '@kbn/rrule'; import { has } from 'lodash'; import { MaintenanceWindow } from '../types'; -import { EndsOptions, Frequency } from '../constants'; +import { EndsOptions, MaintenanceWindowFrequency } from '../constants'; import { FormProps, RecurringScheduleFormProps } from '../components/schema'; import { getInitialByWeekday } from './get_initial_by_weekday'; import { RRuleParams } from '../../../../common'; @@ -31,7 +32,7 @@ export const convertFromMaintenanceWindowToForm = ( const rRule = maintenanceWindow.rRule; const isCustomFrequency = isCustom(rRule); - const frequency = rRule.freq?.toString() as Frequency; + const frequency = rRule.freq as MaintenanceWindowFrequency; const ends = rRule.until ? EndsOptions.ON_DATE : rRule.count @@ -74,7 +75,7 @@ export const convertFromMaintenanceWindowToForm = ( }; const isCustom = (rRule: RRuleParams) => { - const freq = rRule.freq?.toString() as Frequency; + const freq = rRule.freq; // interval is greater than 1 if (rRule.interval && rRule.interval > 1) { return true; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.test.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.test.ts index 7eaecba5169b84..bcbcccce06832f 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.test.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.test.ts @@ -6,9 +6,7 @@ */ import moment from 'moment'; - -import { Frequency } from '../constants'; -import { RRuleFrequency } from '../types'; +import { Frequency } from '@kbn/rrule'; import { convertToRRule } from './convert_to_rrule'; describe('convertToRRule', () => { @@ -22,7 +20,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, count: 1, }); }); @@ -37,7 +35,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], }); @@ -55,7 +53,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], until, @@ -73,7 +71,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, byweekday: ['WE'], count: 3, @@ -89,7 +87,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, byweekday: ['WE'], }); @@ -104,7 +102,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, byweekday: ['+4WE'], }); @@ -119,7 +117,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, interval: 1, bymonth: [3], bymonthday: [22], @@ -137,7 +135,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.DAILY, + freq: Frequency.DAILY, interval: 1, }); }); @@ -154,7 +152,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, byweekday: ['WE', 'TH'], }); @@ -172,7 +170,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, bymonthday: [22], }); @@ -190,7 +188,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, byweekday: ['+4WE'], }); @@ -207,7 +205,7 @@ describe('convertToRRule', () => { expect(rRule).toEqual({ dtstart: startDate.toISOString(), tzid: 'UTC', - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, interval: 3, bymonth: [3], bymonthday: [22], diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts index 90706165c717b2..c3861a2a187ea5 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts @@ -6,8 +6,8 @@ */ import { Moment } from 'moment'; -import { RRuleFrequency, RRuleFrequencyMap } from '../types'; -import { Frequency, ISO_WEEKDAYS_TO_RRULE } from '../constants'; +import { Frequency } from '@kbn/rrule'; +import { ISO_WEEKDAYS_TO_RRULE } from '../constants'; import { getNthByWeekday } from './get_nth_by_weekday'; import { RecurringScheduleFormProps } from '../components/schema'; import { getPresets } from './get_presets'; @@ -30,7 +30,7 @@ export const convertToRRule = ( ...rRule, // default to yearly and a count of 1 // if the maintenance window is not recurring - freq: RRuleFrequency.YEARLY, + freq: Frequency.YEARLY, count: 1, }; @@ -39,8 +39,8 @@ export const convertToRRule = ( form = { ...recurringForm, ...presets[recurringForm.frequency] }; } - const frequency = form.customFrequency ? form.customFrequency : (form.frequency as Frequency); - rRule.freq = RRuleFrequencyMap[frequency]; + const frequency = form.customFrequency ?? (form.frequency as Frequency); + rRule.freq = frequency; rRule.interval = form.interval; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/get_presets.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/get_presets.ts index 737376b957c8ae..529922eac5e87d 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/get_presets.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/get_presets.ts @@ -6,7 +6,7 @@ */ import { Moment } from 'moment'; -import { Frequency } from '../constants'; +import { Frequency } from '@kbn/rrule'; import { getInitialByWeekday } from './get_initial_by_weekday'; export const getPresets = (startDate: Moment) => { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.test.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.test.ts index c889172ae9b443..7b6dc794833459 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.test.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.test.ts @@ -7,7 +7,7 @@ import moment from 'moment'; -import { Frequency } from '../constants'; +import { Frequency } from '@kbn/rrule'; import { getPresets } from './get_presets'; import { recurringSummary } from './recurring_summary'; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts index 69a3fc6f0dddaf..5e3be96c041473 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts @@ -6,8 +6,13 @@ */ import moment, { Moment } from 'moment'; +import { Frequency } from '@kbn/rrule'; import * as i18n from '../translations'; -import { Frequency, ISO_WEEKDAYS_TO_RRULE, RRULE_WEEKDAYS_TO_ISO_WEEKDAYS } from '../constants'; +import { + MaintenanceWindowFrequency, + ISO_WEEKDAYS_TO_RRULE, + RRULE_WEEKDAYS_TO_ISO_WEEKDAYS, +} from '../constants'; import { monthDayDate } from './month_day_date'; import { getNthByWeekday } from './get_nth_by_weekday'; import { RecurringScheduleFormProps } from '../components/schema'; @@ -15,7 +20,7 @@ import { RecurringScheduleFormProps } from '../components/schema'; export const recurringSummary = ( startDate: Moment, recurringSchedule: RecurringScheduleFormProps | undefined, - presets: Record> + presets: Record> ) => { if (!recurringSchedule) return ''; @@ -25,9 +30,8 @@ export const recurringSummary = ( schedule = { ...recurringSchedule, ...presets[recurringSchedule.frequency] }; } - const frequency = schedule.customFrequency - ? schedule.customFrequency - : (schedule.frequency as Frequency); + const frequency = + schedule.customFrequency ?? (schedule.frequency as MaintenanceWindowFrequency); const interval = schedule.interval || 1; const frequencySummary = i18n.CREATE_FORM_FREQUENCY_SUMMARY(interval)[frequency]; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/translations.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/translations.ts index 32d234bfe1d362..0490d3faf54cff 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/translations.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/translations.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; import { Moment } from 'moment'; -import { Frequency } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { monthDayDate } from './helpers/month_day_date'; export const MAINTENANCE_WINDOWS = i18n.translate('xpack.alerting.maintenanceWindows', { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/types.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/types.ts index e6be4af6b86755..6551d3808068a0 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/types.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/types.ts @@ -5,23 +5,17 @@ * 2.0. */ +import { Frequency } from '@kbn/rrule'; import { MaintenanceWindow as MaintenanceWindowServerSide, MaintenanceWindowModificationMetadata, } from '../../../common'; -export enum RRuleFrequency { - YEARLY = 0, - MONTHLY = 1, - WEEKLY = 2, - DAILY = 3, -} - export const RRuleFrequencyMap = { - '0': RRuleFrequency.YEARLY, - '1': RRuleFrequency.MONTHLY, - '2': RRuleFrequency.WEEKLY, - '3': RRuleFrequency.DAILY, + '0': Frequency.YEARLY, + '1': Frequency.MONTHLY, + '2': Frequency.WEEKLY, + '3': Frequency.DAILY, }; export type MaintenanceWindow = Pick; diff --git a/x-pack/plugins/alerting/server/lib/is_rule_snoozed.test.ts b/x-pack/plugins/alerting/server/lib/is_rule_snoozed.test.ts index 35ece5bd95c417..74baec92aa4309 100644 --- a/x-pack/plugins/alerting/server/lib/is_rule_snoozed.test.ts +++ b/x-pack/plugins/alerting/server/lib/is_rule_snoozed.test.ts @@ -6,7 +6,8 @@ */ import sinon from 'sinon'; -import { RRule } from 'rrule'; +import moment from 'moment-timezone'; +import { Frequency } from '@kbn/rrule'; import { isRuleSnoozed } from './is_rule_snoozed'; import { RRuleRecord } from '../types'; @@ -14,6 +15,7 @@ const DATE_9999 = '9999-12-31T12:34:56.789Z'; const DATE_1970 = '1970-01-01T00:00:00.000Z'; const DATE_2019 = '2019-01-01T00:00:00.000Z'; const DATE_2019_PLUS_6_HOURS = '2019-01-01T06:00:00.000Z'; +const DATE_2019_IN_ASIA = '2018-12-31T16:00:00.000Z'; const DATE_2020 = '2020-01-01T00:00:00.000Z'; const DATE_2020_MINUS_1_HOUR = '2019-12-31T23:00:00.000Z'; const DATE_2020_MINUS_1_MONTH = '2019-12-01T00:00:00.000Z'; @@ -94,7 +96,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2019, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, }, @@ -106,7 +108,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2019_PLUS_6_HOURS, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, }, @@ -118,7 +120,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2020_MINUS_1_HOUR, tzid: 'UTC', - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, } as RRuleRecord, }, @@ -131,7 +133,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', count: 8761, @@ -145,7 +147,7 @@ describe('isRuleSnoozed', () => { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', count: 25, @@ -159,7 +161,7 @@ describe('isRuleSnoozed', () => { duration: 60 * 1000, rRule: { - freq: RRule.YEARLY, + freq: Frequency.YEARLY, interval: 1, tzid: 'UTC', count: 60, @@ -175,7 +177,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', until: DATE_9999, @@ -188,7 +190,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', until: DATE_2020_MINUS_1_HOUR, @@ -204,7 +206,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, tzid: 'UTC', byweekday: ['MO', 'WE', 'FR'], // Jan 1 2020 was a Wednesday @@ -217,7 +219,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, tzid: 'UTC', byweekday: ['TU', 'TH', 'SA', 'SU'], @@ -230,7 +232,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, tzid: 'UTC', byweekday: ['MO', 'WE', 'FR'], @@ -244,7 +246,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, tzid: 'UTC', byweekday: ['MO', 'WE', 'FR'], @@ -261,7 +263,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, tzid: 'UTC', byweekday: ['+1WE'], // Jan 1 2020 was the first Wednesday of the month @@ -274,7 +276,7 @@ describe('isRuleSnoozed', () => { { duration: 60 * 1000, rRule: { - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, tzid: 'UTC', byweekday: ['+2WE'], @@ -286,35 +288,39 @@ describe('isRuleSnoozed', () => { }); test('using a timezone, returns as expected for a recurring snooze on a day of the week', () => { - const snoozeScheduleA = [ - { - duration: 60 * 1000, - rRule: { - freq: RRule.WEEKLY, - interval: 1, - byweekday: ['WE'], - tzid: 'Asia/Taipei', - dtstart: DATE_2019, - } as RRuleRecord, - }, - ]; + try { + const snoozeScheduleA = [ + { + duration: 60 * 1000, + rRule: { + freq: Frequency.WEEKLY, + interval: 1, + byweekday: ['WE'], + tzid: 'Asia/Taipei', + dtstart: DATE_2019_IN_ASIA, + } as RRuleRecord, + }, + ]; - expect(isRuleSnoozed({ snoozeSchedule: snoozeScheduleA, muteAll: false })).toBe(true); - const snoozeScheduleB = [ - { - duration: 60 * 1000, - rRule: { - freq: RRule.WEEKLY, - interval: 1, - byweekday: ['WE'], - byhour: [0], - byminute: [0], - tzid: 'UTC', - dtstart: DATE_2019, - } as RRuleRecord, - }, - ]; - expect(isRuleSnoozed({ snoozeSchedule: snoozeScheduleB, muteAll: false })).toBe(true); + expect(isRuleSnoozed({ snoozeSchedule: snoozeScheduleA, muteAll: false })).toBe(false); + const snoozeScheduleB = [ + { + duration: 60 * 1000, + rRule: { + freq: Frequency.WEEKLY, + interval: 1, + byweekday: ['WE'], + byhour: [0], + byminute: [0], + tzid: 'UTC', + dtstart: DATE_2019, + } as RRuleRecord, + }, + ]; + expect(isRuleSnoozed({ snoozeSchedule: snoozeScheduleB, muteAll: false })).toBe(true); + } catch (e) { + throw new Error(`In timezone ${process.env.TZ ?? moment.tz.guess()}: ${e}`); + } }); test('returns as expected for a manually skipped recurring snooze', () => { @@ -324,7 +330,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2019, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, skipRecurrences: [DATE_2020], @@ -337,7 +343,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2019, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, skipRecurrences: [DATE_2020_MINUS_1_MONTH], @@ -350,7 +356,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2020, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, skipRecurrences: [DATE_2020], @@ -363,7 +369,7 @@ describe('isRuleSnoozed', () => { rRule: { dtstart: DATE_2020_MINUS_6_HOURS, tzid: 'UTC', - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 5, } as RRuleRecord, skipRecurrences: [DATE_2020_MINUS_1_HOUR], diff --git a/x-pack/plugins/alerting/server/lib/rrule/index.ts b/x-pack/plugins/alerting/server/lib/rrule/index.ts deleted file mode 100644 index 22674b91e6ee42..00000000000000 --- a/x-pack/plugins/alerting/server/lib/rrule/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './parse_by_weekday'; diff --git a/x-pack/plugins/alerting/server/lib/rrule/parse_by_weekday.ts b/x-pack/plugins/alerting/server/lib/rrule/parse_by_weekday.ts deleted file mode 100644 index 9d9cdf3c588486..00000000000000 --- a/x-pack/plugins/alerting/server/lib/rrule/parse_by_weekday.ts +++ /dev/null @@ -1,13 +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 { ByWeekday, rrulestr } from 'rrule'; - -export function parseByWeekday(byweekday: Array): ByWeekday[] { - const rRuleString = `RRULE:BYDAY=${byweekday.join(',')}`; - const parsedRRule = rrulestr(rRuleString); - return parsedRRule.origOptions.byweekday as ByWeekday[]; -} diff --git a/x-pack/plugins/alerting/server/lib/snooze/index.ts b/x-pack/plugins/alerting/server/lib/snooze/index.ts index beb38a3f9650b7..6c04be20ca97c5 100644 --- a/x-pack/plugins/alerting/server/lib/snooze/index.ts +++ b/x-pack/plugins/alerting/server/lib/snooze/index.ts @@ -7,4 +7,3 @@ export { isSnoozeActive } from './is_snooze_active'; export { isSnoozeExpired } from './is_snooze_expired'; -export { utcToLocalUtc, localUtcToUtc } from './timezone_helpers'; diff --git a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.test.ts b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.test.ts index d42824d6e840a8..9fdce331a7da99 100644 --- a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.test.ts +++ b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.test.ts @@ -6,20 +6,20 @@ */ import moment from 'moment'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import sinon from 'sinon'; import { RRuleRecord } from '../../types'; import { isSnoozeActive } from './is_snooze_active'; let fakeTimer: sinon.SinonFakeTimers; -describe('isSnoozeExpired', () => { +describe('isSnoozeActive', () => { afterAll(() => fakeTimer.restore()); test('snooze is NOT active byweekday', () => { // Set the current time as: // - Feb 27 2023 08:15:00 GMT+0000 - Monday - fakeTimer = sinon.useFakeTimers(new Date('2023-02-27T06:15:00.000Z')); + fakeTimer = sinon.useFakeTimers(new Date('2023-02-27T08:15:00.000Z')); // Try to get snooze end time with: // - Start date of: Feb 24 2023 23:00:00 GMT+0000 - Friday @@ -30,7 +30,7 @@ describe('isSnoozeExpired', () => { rRule: { byweekday: ['SA'], tzid: 'Europe/Madrid', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, dtstart: '2023-02-24T23:00:00.000Z', } as RRuleRecord, @@ -54,7 +54,7 @@ describe('isSnoozeExpired', () => { rRule: { byweekday: ['SA'], tzid: 'Europe/Madrid', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, dtstart: '2023-02-24T23:00:00.000Z', } as RRuleRecord, @@ -84,7 +84,7 @@ describe('isSnoozeExpired', () => { rRule: { byweekday: ['SA'], tzid: 'Europe/Madrid', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, dtstart: '2023-02-24T23:00:00.000Z', } as RRuleRecord, @@ -108,7 +108,7 @@ describe('isSnoozeExpired', () => { rRule: { byweekday: ['SA'], tzid: 'Europe/Madrid', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, dtstart: '2023-02-24T23:00:00.000Z', } as RRuleRecord, @@ -117,7 +117,7 @@ describe('isSnoozeExpired', () => { expect(isSnoozeActive(snoozeA)).toMatchInlineSnapshot(` Object { "id": "9141dc1f-ed85-4656-91e4-119173105432", - "lastOccurrence": 2023-03-04T00:00:00.000Z, + "lastOccurrence": 2023-03-03T23:00:00.000Z, "snoozeEndTime": 2023-03-06T06:00:00.000Z, } `); @@ -136,7 +136,7 @@ describe('isSnoozeExpired', () => { const snoozeA = { duration: moment('2023-01', 'YYYY-MM').daysInMonth() * 24 * 60 * 60 * 1000, // 1 month rRule: { - freq: 0, + freq: Frequency.YEARLY, interval: 1, bymonthday: [1], bymonth: [1], @@ -164,7 +164,7 @@ describe('isSnoozeExpired', () => { bymonthday: [1], bymonth: [1], tzid: 'Europe/Madrid', - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, dtstart: '2023-01-01T00:00:00.000Z', } as RRuleRecord, @@ -195,7 +195,7 @@ describe('isSnoozeExpired', () => { bymonthday: [1], bymonth: [1], tzid: 'Europe/Madrid', - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, dtstart: '2023-01-01T00:00:00.000Z', } as RRuleRecord, @@ -221,7 +221,7 @@ describe('isSnoozeExpired', () => { bymonthday: [1], bymonth: [1], tzid: 'Europe/Madrid', - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, dtstart: '2023-01-01T00:00:00.000Z', } as RRuleRecord, diff --git a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.ts b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.ts index 3013cf12ae71f6..0af968c52e2061 100644 --- a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.ts +++ b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_active.ts @@ -5,10 +5,8 @@ * 2.0. */ -import { RRule, Weekday } from 'rrule'; +import { RRule, Weekday } from '@kbn/rrule'; import { RuleSnoozeSchedule } from '../../types'; -import { parseByWeekday } from '../rrule'; -import { utcToLocalUtc, localUtcToUtc } from './timezone_helpers'; const MAX_TIMESTAMP = 8640000000000000; @@ -32,32 +30,24 @@ export function isSnoozeActive(snooze: RuleSnoozeSchedule) { }; // Check to see if now is during a recurrence of the snooze - - const { tzid, ...restRRule } = rRule; - const startDate = utcToLocalUtc(new Date(rRule.dtstart), tzid); - const nowDate = utcToLocalUtc(new Date(now), tzid); - try { const rRuleOptions = { - ...restRRule, - dtstart: startDate, - until: rRule.until ? utcToLocalUtc(new Date(rRule.until), tzid) : null, - wkst: rRule.wkst ? Weekday.fromStr(rRule.wkst) : null, - byweekday: rRule.byweekday ? parseByWeekday(rRule.byweekday) : null, + ...rRule, + dtstart: new Date(rRule.dtstart), + until: rRule.until ? new Date(rRule.until) : null, + byweekday: rRule.byweekday ?? null, + wkst: rRule.wkst ? Weekday[rRule.wkst] : null, }; const recurrenceRule = new RRule(rRuleOptions); - const lastOccurrence = recurrenceRule.before(nowDate, true); + const lastOccurrence = recurrenceRule.before(new Date(now)); + if (!lastOccurrence) return null; // Check if the current recurrence has been skipped manually if (snooze.skipRecurrences?.includes(lastOccurrence.toISOString())) return null; const lastOccurrenceEndTime = lastOccurrence.getTime() + duration; - if (nowDate.getTime() < lastOccurrenceEndTime) - return { - lastOccurrence, - snoozeEndTime: localUtcToUtc(new Date(lastOccurrenceEndTime), tzid), - id, - }; + if (now < lastOccurrenceEndTime) + return { lastOccurrence, snoozeEndTime: new Date(lastOccurrenceEndTime), id }; } catch (e) { throw new Error(`Failed to process RRule ${rRule}: ${e}`); } diff --git a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.test.ts b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.test.ts index 3dfee044cd1c3e..f0a516e855aabf 100644 --- a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.test.ts +++ b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.test.ts @@ -6,7 +6,7 @@ */ import sinon from 'sinon'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { isSnoozeExpired } from './is_snooze_expired'; import { RRuleRecord } from '../../types'; @@ -84,7 +84,7 @@ describe('isSnoozeExpired', () => { rRule: { dtstart: DATE_2019, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, }; @@ -95,7 +95,7 @@ describe('isSnoozeExpired', () => { rRule: { dtstart: DATE_2019_PLUS_6_HOURS, tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, } as RRuleRecord, }; @@ -105,7 +105,7 @@ describe('isSnoozeExpired', () => { rRule: { dtstart: DATE_2020_MINUS_1_HOUR, tzid: 'UTC', - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, } as RRuleRecord, }; @@ -116,7 +116,7 @@ describe('isSnoozeExpired', () => { const snoozeA = { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', count: 8761, @@ -128,7 +128,7 @@ describe('isSnoozeExpired', () => { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', count: 25, @@ -140,7 +140,7 @@ describe('isSnoozeExpired', () => { duration: 60 * 1000, rRule: { - freq: RRule.YEARLY, + freq: Frequency.YEARLY, interval: 1, tzid: 'UTC', count: 30, @@ -155,7 +155,7 @@ describe('isSnoozeExpired', () => { const snoozeA = { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', until: DATE_9999, @@ -166,7 +166,7 @@ describe('isSnoozeExpired', () => { const snoozeB = { duration: 60 * 1000, rRule: { - freq: RRule.HOURLY, + freq: Frequency.HOURLY, interval: 1, tzid: 'UTC', until: DATE_2020_MINUS_1_HOUR, diff --git a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.ts b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.ts index 3c150740910984..f9dd80f9b20247 100644 --- a/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.ts +++ b/x-pack/plugins/alerting/server/lib/snooze/is_snooze_expired.ts @@ -5,10 +5,9 @@ * 2.0. */ -import { RRule, Weekday } from 'rrule'; +import { RRule, Weekday } from '@kbn/rrule'; import { RuleSnoozeSchedule } from '../../types'; import { isSnoozeActive } from './is_snooze_active'; -import { parseByWeekday } from '../rrule'; export function isSnoozeExpired(snooze: RuleSnoozeSchedule) { if (isSnoozeActive(snooze)) { @@ -23,12 +22,12 @@ export function isSnoozeExpired(snooze: RuleSnoozeSchedule) { ...rRule, dtstart: new Date(rRule.dtstart), until: rRule.until ? new Date(rRule.until) : null, - wkst: rRule.wkst ? Weekday.fromStr(rRule.wkst) : null, - byweekday: rRule.byweekday ? parseByWeekday(rRule.byweekday) : null, + byweekday: rRule.byweekday ?? null, + wkst: rRule.wkst ? Weekday[rRule.wkst] : null, }; const recurrenceRule = new RRule(rRuleOptions); - const nextOccurrence = recurrenceRule.after(new Date(now), true); + const nextOccurrence = recurrenceRule.after(new Date(now)); return !nextOccurrence; } catch (e) { throw new Error(`Failed to process RRule ${rRule}: ${e}`); diff --git a/x-pack/plugins/alerting/server/lib/snooze/timezone_helpers.ts b/x-pack/plugins/alerting/server/lib/snooze/timezone_helpers.ts deleted file mode 100644 index e32e8623103bdf..00000000000000 --- a/x-pack/plugins/alerting/server/lib/snooze/timezone_helpers.ts +++ /dev/null @@ -1,32 +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 moment from 'moment-timezone'; - -/** - * Converts the UTC date into the user's local time zone, but still in UTC. - * This must be done because rrule does not care about timezones, so for the result - * to be correct, we must ensure everything is timezone agnostic. - * - * example: 2023-03-29 08:00:00 CET -> 2023-03-29 08:00:00 UTC - */ -export const utcToLocalUtc = (date: Date, tz: string) => { - const localTime = moment(date).tz(tz); - const localTimeInUTC = moment(localTime).tz('UTC', true); - return localTimeInUTC.utc().toDate(); -}; - -/** - * Converts the local date in UTC back into actual UTC. After rrule does its thing, - * we would still like to keep everything in UTC in the business logic, hence why we - * need to convert everything back - * - * Example: 2023-03-29 08:00:00 UTC (from the utcToLocalUtc output) -> 2023-03-29 06:00:00 UTC (Real UTC) - */ -export const localUtcToUtc = (date: Date, tz: string) => { - const localTimeString = moment.utc(date).format('YYYY-MM-DD HH:mm:ss.SSS'); - return moment.tz(localTimeString, tz).utc().toDate(); -}; diff --git a/x-pack/plugins/alerting/server/lib/validate_snooze_schedule.ts b/x-pack/plugins/alerting/server/lib/validate_snooze_schedule.ts index 4004a405792539..a6e9059be9857d 100644 --- a/x-pack/plugins/alerting/server/lib/validate_snooze_schedule.ts +++ b/x-pack/plugins/alerting/server/lib/validate_snooze_schedule.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { Frequency } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import moment from 'moment'; import { RuleSnoozeSchedule } from '../types'; diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts b/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts index 85cfc0f134c4bb..c7e15cf1f974a3 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment-timezone'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { generateMaintenanceWindowEvents } from './generate_maintenance_window_events'; describe('generateMaintenanceWindowEvents', () => { @@ -24,7 +24,7 @@ describe('generateMaintenanceWindowEvents', () => { .toISOString(), rRule: { tzid: 'UTC', - freq: RRule.DAILY, + freq: Frequency.DAILY, interval: 1, dtstart: '2023-02-27T00:00:00.000Z', }, @@ -55,7 +55,7 @@ describe('generateMaintenanceWindowEvents', () => { .toISOString(), rRule: { tzid: 'UTC', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, dtstart: '2023-02-27T00:00:00.000Z', }, @@ -86,7 +86,7 @@ describe('generateMaintenanceWindowEvents', () => { .toISOString(), rRule: { tzid: 'UTC', - freq: RRule.MONTHLY, + freq: Frequency.MONTHLY, interval: 1, dtstart: '2023-02-27T00:00:00.000Z', }, @@ -116,7 +116,7 @@ describe('generateMaintenanceWindowEvents', () => { .toISOString(), rRule: { tzid: 'UTC', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, interval: 1, byweekday: ['TU', 'TH'], dtstart: '2023-02-27T00:00:00.000Z', diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts b/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts index aa09b0069ce499..92ad3ad0fda4de 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/generate_maintenance_window_events.ts @@ -7,10 +7,8 @@ import _ from 'lodash'; import moment from 'moment-timezone'; -import { RRule, Weekday } from 'rrule'; -import { parseByWeekday } from '../lib/rrule'; +import { RRule, Weekday } from '@kbn/rrule'; import { RRuleParams, MaintenanceWindowSOAttributes, DateRange } from '../../common'; -import { utcToLocalUtc, localUtcToUtc } from '../lib/snooze'; export interface GenerateMaintenanceWindowEventsParams { rRule: RRuleParams; @@ -23,28 +21,27 @@ export const generateMaintenanceWindowEvents = ({ expirationDate, duration, }: GenerateMaintenanceWindowEventsParams) => { - const { dtstart, until, wkst, byweekday, tzid, ...rest } = rRule; + const { dtstart, until, wkst, byweekday, ...rest } = rRule; - const startDate = utcToLocalUtc(new Date(dtstart), tzid); - const endDate = utcToLocalUtc(new Date(expirationDate), tzid); + const startDate = new Date(dtstart); + const endDate = new Date(expirationDate); const rRuleOptions = { ...rest, dtstart: startDate, - until: until ? utcToLocalUtc(new Date(until), tzid) : null, - wkst: wkst ? Weekday.fromStr(wkst) : null, - byweekday: byweekday ? parseByWeekday(byweekday) : null, + until: until ? new Date(until) : null, + wkst: wkst ? Weekday[wkst] : null, + byweekday: byweekday ?? null, }; try { const recurrenceRule = new RRule(rRuleOptions); - const occurrenceDates = recurrenceRule.between(startDate, endDate, true); + const occurrenceDates = recurrenceRule.between(startDate, endDate); return occurrenceDates.map((date) => { - const utcDate = localUtcToUtc(date, tzid); return { - gte: utcDate.toISOString(), - lte: moment.utc(utcDate).add(duration, 'ms').toISOString(), + gte: date.toISOString(), + lte: moment(date).add(duration, 'ms').toISOString(), }; }); } catch (e) { diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts index 0bdf0748921f73..c3da9c59482061 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/methods/archive.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment-timezone'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { archive } from './archive'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObjectsUpdateResponse, SavedObject } from '@kbn/core/server'; @@ -153,7 +153,7 @@ describe('MaintenanceWindowClient - archive', () => { rRule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 5, }, events: modifiedEvents, diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts index 8eb4d812426d48..8a37f228892b65 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/methods/finish.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment-timezone'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { finish } from './finish'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObjectsUpdateResponse, SavedObject } from '@kbn/core/server'; @@ -54,7 +54,7 @@ describe('MaintenanceWindowClient - finish', () => { rRule: { tzid: 'UTC', dtstart: moment().utc().toISOString(), - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 2, }, }); @@ -110,7 +110,7 @@ describe('MaintenanceWindowClient - finish', () => { rRule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 5, }, events: modifiedEvents, @@ -158,7 +158,7 @@ describe('MaintenanceWindowClient - finish', () => { rRule: { tzid: 'UTC', dtstart: moment().utc().toISOString(), - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 2, }, }); diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts index c07497135e4c9a..54745c61b73e94 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/methods/test_helpers.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { MaintenanceWindowSOAttributes } from '../../../common'; export const getMockMaintenanceWindow = ( @@ -18,7 +18,7 @@ export const getMockMaintenanceWindow = ( rRule: { tzid: 'UTC', dtstart: '2023-02-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 2, }, events: [ diff --git a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts b/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts index 715d74dd9f9013..ea2cb33341b0db 100644 --- a/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts +++ b/x-pack/plugins/alerting/server/maintenance_window_client/methods/update.test.ts @@ -6,7 +6,7 @@ */ import moment from 'moment-timezone'; -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { update } from './update'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { SavedObject } from '@kbn/core/server'; @@ -28,7 +28,7 @@ const updatedAttributes = { rRule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 2, }, }; @@ -134,7 +134,7 @@ describe('MaintenanceWindowClient - update', () => { rRule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 5, }, events: modifiedEvents, @@ -177,7 +177,7 @@ describe('MaintenanceWindowClient - update', () => { rRule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 2, }, }); diff --git a/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts b/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts index dc518d64df0f48..4f714ef8d9fbeb 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts @@ -13,7 +13,11 @@ export const rRuleSchema = schema.object({ dtstart: schema.string({ validate: validateSnoozeStartDate }), tzid: schema.string(), freq: schema.maybe( - schema.oneOf([schema.literal(0), schema.literal(1), schema.literal(2), schema.literal(3)]) + schema.number({ + validate: (freq: number) => { + if (freq < 0 || freq > 3) return 'rRule freq must be 0, 1, 2, or 3'; + }, + }) ), interval: schema.maybe( schema.number({ diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts index f8f34d1701caa6..a7793c49958908 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/update_maintenance_window.test.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { RRule } from 'rrule'; +import { Frequency } from '@kbn/rrule'; import { httpServiceMock } from '@kbn/core/server/mocks'; import { licenseStateMock } from '../../lib/license_state.mock'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -36,7 +36,7 @@ const updateParams = { r_rule: { tzid: 'CET', dtstart: '2023-03-26T00:00:00.000Z', - freq: RRule.WEEKLY, + freq: Frequency.WEEKLY, count: 10, }, }; diff --git a/x-pack/plugins/alerting/tsconfig.json b/x-pack/plugins/alerting/tsconfig.json index cdba5b7a4d8e6b..9cafbe064360c0 100644 --- a/x-pack/plugins/alerting/tsconfig.json +++ b/x-pack/plugins/alerting/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../../tsconfig.base.json", "compilerOptions": { - "outDir": "target/types", + "outDir": "target/types" }, "include": [ "server/**/*", @@ -42,6 +42,7 @@ "@kbn/alerting-state-types", "@kbn/alerts-as-data-utils", "@kbn/core-elasticsearch-client-server-mocks", + "@kbn/rrule", "@kbn/shared-ux-router", "@kbn/kibana-react-plugin", "@kbn/management-plugin", @@ -52,9 +53,7 @@ "@kbn/doc-links", "@kbn/core-saved-objects-utils-server", "@kbn/core-ui-settings-common", - "@kbn/core-capabilities-common", + "@kbn/core-capabilities-common" ], - "exclude": [ - "target/**/*", - ] + "exclude": ["target/**/*"] } diff --git a/yarn.lock b/yarn.lock index b34388e82f10a9..dec901f6e1b294 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4954,6 +4954,10 @@ version "0.0.0" uid "" +"@kbn/rrule@link:packages/kbn-rrule": + version "0.0.0" + uid "" + "@kbn/rule-data-utils@link:packages/kbn-rule-data-utils": version "0.0.0" uid "" @@ -20703,7 +20707,7 @@ lru-queue@0.1: dependencies: es5-ext "~0.10.2" -luxon@^1.21.3, luxon@^1.25.0: +luxon@^1.25.0: version "1.28.1" resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.1.tgz#528cdf3624a54506d710290a2341aa8e6e6c61b0" integrity sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw== @@ -25674,15 +25678,6 @@ robust-predicates@^3.0.0: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a" integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g== -rrule@2.6.4: - version "2.6.4" - resolved "https://registry.yarnpkg.com/rrule/-/rrule-2.6.4.tgz#7f4f31fda12bc7249bb176c891109a9bc448e035" - integrity sha512-sLdnh4lmjUqq8liFiOUXD5kWp/FcnbDLPwq5YAc/RrN6120XOPb86Ae5zxF7ttBVq8O3LxjjORMEit1baluahA== - dependencies: - tslib "^1.10.0" - optionalDependencies: - luxon "^1.21.3" - rst-selector-parser@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" From 10b35cf4d4fcdc1dfad97c1f1c9d9b40f62cff8b Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 3 Jul 2023 01:01:01 -0400 Subject: [PATCH 10/98] [api-docs] 2023-07-03 Daily api_docs build (#161059) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/387 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 258 ++--------------- api_docs/alerting.mdx | 4 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.devdocs.json | 30 ++ api_docs/cloud.mdx | 4 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/ess_security.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.devdocs.json | 4 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.devdocs.json | 168 +++++++++++ api_docs/kbn_core_chrome_browser.mdx | 4 +- 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 | 32 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../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 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 13 +- api_docs/kbn_doc_links.mdx | 4 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.devdocs.json | 273 ++++++++++++++++++ api_docs/kbn_rrule.mdx | 36 +++ api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 15 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 550 files changed, 1115 insertions(+), 804 deletions(-) create mode 100644 api_docs/kbn_rrule.devdocs.json create mode 100644 api_docs/kbn_rrule.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 7495f6549384dd..6e7c474cacd7aa 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-02 +date: 2023-07-03 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 dc853d731e9e52..fd3ff9831d794b 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index d6a9026e219a59..ef98513eae8af9 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-02 +date: 2023-07-03 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 bff251325f5746..67ed79d64cdc42 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -7144,239 +7144,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord", - "type": "Interface", - "tags": [], - "label": "RRuleRecord", - "description": [], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.dtstart", - "type": "string", - "tags": [], - "label": "dtstart", - "description": [], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.tzid", - "type": "string", - "tags": [], - "label": "tzid", - "description": [], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.freq", - "type": "CompoundType", - "tags": [], - "label": "freq", - "description": [], - "signature": [ - "0 | 2 | 6 | 5 | 4 | 3 | 1 | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.until", - "type": "string", - "tags": [], - "label": "until", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.count", - "type": "number", - "tags": [], - "label": "count", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.interval", - "type": "number", - "tags": [], - "label": "interval", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.wkst", - "type": "CompoundType", - "tags": [], - "label": "wkst", - "description": [], - "signature": [ - "WeekdayStr", - " | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.byweekday", - "type": "Array", - "tags": [], - "label": "byweekday", - "description": [], - "signature": [ - "(string | number)[] | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.bymonth", - "type": "Array", - "tags": [], - "label": "bymonth", - "description": [], - "signature": [ - "number[] | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.bysetpos", - "type": "Array", - "tags": [], - "label": "bysetpos", - "description": [], - "signature": [ - "number[] | undefined" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.bymonthday", - "type": "Array", - "tags": [], - "label": "bymonthday", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.byyearday", - "type": "Array", - "tags": [], - "label": "byyearday", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.byweekno", - "type": "Array", - "tags": [], - "label": "byweekno", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.byhour", - "type": "Array", - "tags": [], - "label": "byhour", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.byminute", - "type": "Array", - "tags": [], - "label": "byminute", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RRuleRecord.bysecond", - "type": "Array", - "tags": [], - "label": "bysecond", - "description": [], - "signature": [ - "number[]" - ], - "path": "x-pack/plugins/alerting/common/rrule_type.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-common.Rule", @@ -10247,6 +10014,31 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RRuleRecord", + "type": "Type", + "tags": [], + "label": "RRuleRecord", + "description": [], + "signature": [ + "Omit<", + "Options", + ", \"wkst\" | \"byweekday\" | \"dtstart\" | \"until\"> & { dtstart: string; byweekday?: (string | number)[] | undefined; wkst?: ", + { + "pluginId": "@kbn/rrule", + "scope": "common", + "docId": "kibKbnRrulePluginApi", + "section": "def-common.WeekdayStr", + "text": "WeekdayStr" + }, + " | undefined; until?: string | undefined; }" + ], + "path": "x-pack/plugins/alerting/common/rrule_type.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleActionAlertsFilterProperty", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 7ff7553f0d3bb7..15a204ae04874b 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-02 +date: 2023-07-03 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 | |-------------------|-----------|------------------------|-----------------| -| 635 | 1 | 611 | 47 | +| 619 | 1 | 595 | 47 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index f54567ba169ce2..c14f27ab3bedc5 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index f7b7969b78cace..e6f19ae5a0655d 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-02 +date: 2023-07-03 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 88613273787258..897a78bb219c36 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-02 +date: 2023-07-03 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 f4602ae4d72da2..44c2cbb782545a 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-02 +date: 2023-07-03 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 7f1cb5168e4464..75b92e187bcf1b 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-02 +date: 2023-07-03 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 5ba704f858c2d9..c6dd67e43d07e9 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-02 +date: 2023-07-03 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 91573e22d3ad4e..479c3cdeca6463 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.devdocs.json b/api_docs/cloud.devdocs.json index 3d9e7dd03898fd..bf2875c387ff7b 100644 --- a/api_docs/cloud.devdocs.json +++ b/api_docs/cloud.devdocs.json @@ -85,6 +85,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "cloud", + "id": "def-public.CloudConfigType.billing_url", + "type": "string", + "tags": [], + "label": "billing_url", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/cloud/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "cloud", "id": "def-public.CloudConfigType.organization_url", @@ -249,6 +263,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "cloud", + "id": "def-public.CloudStart.billingUrl", + "type": "string", + "tags": [], + "label": "billingUrl", + "description": [ + "\nThe full URL to the billing page on Elastic Cloud. Undefined if not running on Cloud." + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/cloud/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "cloud", "id": "def-public.CloudStart.organizationUrl", diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 8ff6937987f37d..554372c5a7ed30 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.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 | |-------------------|-----------|------------------------|-----------------| -| 52 | 0 | 11 | 0 | +| 54 | 0 | 12 | 0 | ## Client diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 7b376c5af18b1c..4de2551a154c69 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 9f7cf371be3f19..d1205180fca8e1 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 9564697177789e..c2dc31f4d57a0a 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-02 +date: 2023-07-03 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 6923a13e25de05..55ba6908278021 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-02 +date: 2023-07-03 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 569f7f3d96d941..d9730ff4cf9e81 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-02 +date: 2023-07-03 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 07dfbda1579b84..19be173117b071 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-02 +date: 2023-07-03 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 89dc9449be7638..176380ce83ac14 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-02 +date: 2023-07-03 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 134cb7a2edb59f..b22e9513e94dbf 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 e872ae550ddfd5..2268e61817c725 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-02 +date: 2023-07-03 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 eb17fa9bf0b331..299103af8c7ece 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-02 +date: 2023-07-03 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 f05fb3109c15c0..16a417cacb7a5f 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-02 +date: 2023-07-03 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 0b0dc59e6e9c29..9ff6f2330f88b0 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-02 +date: 2023-07-03 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 971a36c65f4965..9551b7cebe961d 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-02 +date: 2023-07-03 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 3f1a06f3db33d1..9bb77627bfcaa7 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-02 +date: 2023-07-03 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 b7371765bfb130..0f93446b3f05aa 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-02 +date: 2023-07-03 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 5a41ce8e07963a..3e737d288086ca 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-02 +date: 2023-07-03 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 d53b1d8c56d6a0..1ae9fad417e5d2 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-02 +date: 2023-07-03 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 2d93f5964633a0..37f9b4946d837c 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 8d407f32668263..fa611f10b8e361 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-02 +date: 2023-07-03 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 c08433a98e6e6c..bda216ec621756 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 0c4a7343886654..550f6f68163095 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index a0ac678a2b8b3c..db32045f128177 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index f83a32c85534cd..6c7f4a1b499f3a 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index f222a06e7b8b15..96ffcfe43d38d0 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-02 +date: 2023-07-03 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 ee39db5a8971c7..c1d76eb83346c8 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-02 +date: 2023-07-03 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 2854104d7daf49..2b842e492a9b67 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-02 +date: 2023-07-03 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 344517279f5c81..04d584f7282f90 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index fd5e41f0cd1cc0..9f214e29aca76c 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-02 +date: 2023-07-03 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 5a234662ebaa3c..c657b333104096 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-02 +date: 2023-07-03 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 93553d3540bda7..87bec77293be6d 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-02 +date: 2023-07-03 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 944b679ce2371d..0757a18e10a19e 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-02 +date: 2023-07-03 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 d4692dac007e2a..8dcd203f43d13b 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 30c5e5a89292d8..856ed0b67c624d 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index be30767c1c0c6a..a6ba105b7a6a2a 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 4f73018b05448c..bfd0d8f64ebfee 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-02 +date: 2023-07-03 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 4f0d0c7dc92ade..0e550c333dc305 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-02 +date: 2023-07-03 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 ae2b01da09a6f8..62c5aed54bee29 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-02 +date: 2023-07-03 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 7f8b70370f675e..25ca29169fd792 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-02 +date: 2023-07-03 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 1109acc5c97754..aa3ecef0635b6b 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-02 +date: 2023-07-03 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 f4a06838802112..cb9cf1e79b81e1 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-02 +date: 2023-07-03 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 50feb23fdc5910..bd845b069beefe 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-02 +date: 2023-07-03 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 6b8406335f1491..4790a1440a31ca 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-02 +date: 2023-07-03 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 24e85b78eff0e0..a5fda431f88e6d 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-02 +date: 2023-07-03 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 2245453b68675d..6dc2d107f845cd 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-02 +date: 2023-07-03 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 01083efdef1a5c..c4b99bdb1cd89a 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-02 +date: 2023-07-03 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 1e996faee26b68..b4e92499d5a597 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-02 +date: 2023-07-03 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 177421eaa404b1..a8212bf8743583 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-02 +date: 2023-07-03 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 0cd8228bceac5d..05d7b916e4d527 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-02 +date: 2023-07-03 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 54a2b593c29634..2f41edf8ec7287 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-02 +date: 2023-07-03 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 3f3e98d77c1873..4f29157f0d332b 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-02 +date: 2023-07-03 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 0bf8d6cfd7c3d5..f6d4c24f36bb96 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-02 +date: 2023-07-03 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 16f71d15eb8854..2838e587f6f9fc 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-02 +date: 2023-07-03 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 87ccbe8f9a6fcd..dba63ce83efd06 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-02 +date: 2023-07-03 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 aaeabafa5f97f3..6db8d183a55ce4 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-02 +date: 2023-07-03 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 da21fd6a637126..cc9fa3ccf98951 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 1fe82ac22cfb07..e3561ff67f72fb 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-02 +date: 2023-07-03 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 62abbd488152d6..7fecdc4a0cf484 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-02 +date: 2023-07-03 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 a337aae1515d05..693fb5e1bc6a2f 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-02 +date: 2023-07-03 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 5bdfa4b7e16e2b..066cbf18f7bfec 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-02 +date: 2023-07-03 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 014e0c553b7fa2..292d0a0ee2565e 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-02 +date: 2023-07-03 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 e84965edc7e2db..489440e7892eed 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 6faa6f8362d321..13174c35a62988 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 eeb888dffa283c..520d1eb1b99cfd 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 90ca11afa59ae7..c669489aceb7b2 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-02 +date: 2023-07-03 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 9cbe6a8d8e44d7..ace377408281a5 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-02 +date: 2023-07-03 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 7a1e28fdc7a279..3510ccb3026ed0 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 263fca4c8c0f34..d8b747beb9973c 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-02 +date: 2023-07-03 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 1a9c1ad7e28181..073c7ad634370d 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 7b74dabdaefcae..3b07e03c7e8f7a 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 1dd2128c797ba7..a89fadba6b9052 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 3630e3e0b13a06..f8116af96a29c8 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-02 +date: 2023-07-03 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 07ff395d2ff301..6549daceac9df8 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-02 +date: 2023-07-03 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 8d0147efd20693..487971dc0824d5 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 75076f9204a1cb..b84ca2a9ae3d61 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 f7b6a0c9885516..d835ce46020aaa 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-02 +date: 2023-07-03 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 41a697adbbb901..d8ef06e92a2d4c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-02 +date: 2023-07-03 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 2b45cb05b8a4bb..34aae13e5f9090 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 13fba0d801201f..5903db6c22eb47 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 699477ae4f8e03..ff477d2694ad9f 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-02 +date: 2023-07-03 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 ce332d13f697ed..d7c82e20ac2043 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-02 +date: 2023-07-03 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 6afe5416b93036..ddecff7dcdc3a0 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-02 +date: 2023-07-03 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 4fee9bd86e998e..dfe6f14649adf7 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 88ab5b753e3fa8..7cf209d3a67e8f 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index a504e2ffc4e864..929302a536fb96 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.devdocs.json b/api_docs/kbn_cell_actions.devdocs.json index dcc406e62c1d00..bb7d9ec6611ffa 100644 --- a/api_docs/kbn_cell_actions.devdocs.json +++ b/api_docs/kbn_cell_actions.devdocs.json @@ -1277,7 +1277,7 @@ "label": "CellActionFieldValue", "description": [], "signature": [ - "string[] | undefined[] | boolean[] | number[] | ", + "string[] | undefined[] | boolean[] | ", { "pluginId": "@kbn/utility-types", "scope": "common", @@ -1285,7 +1285,7 @@ "section": "def-common.Serializable", "text": "Serializable" }, - " | null[]" + " | number[] | null[]" ], "path": "packages/kbn-cell-actions/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 3a901e7406b11c..5d822ead90c1bb 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-02 +date: 2023-07-03 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 4d3f5f2fb1f385..2634b8ff3bd297 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-02 +date: 2023-07-03 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 660cc266fd0b95..8ede10441d779e 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-02 +date: 2023-07-03 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 f242020b573640..52f8c815893b1a 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-02 +date: 2023-07-03 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 0a8c9ce907f61c..b4c0a5bc34885a 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-02 +date: 2023-07-03 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 f4a9b795196b16..086ac5b45494a0 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-02 +date: 2023-07-03 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 00613d712922b3..414873ca5e0c22 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-02 +date: 2023-07-03 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 084b7e805ac672..ed494fbbffdbea 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index af5b0709407ce2..a8fcbb433416be 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 72eaadfacc7540..8a8436cfca4f55 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-02 +date: 2023-07-03 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 964e4d2a4bf0e3..fb82faf4a7a276 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-02 +date: 2023-07-03 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 00abbce9ad30f0..3455e1e02089c8 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 67b98613731e46..c62ef76a639b59 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-02 +date: 2023-07-03 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 c5eea73b21dcc3..e31d1f88a6d910 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-02 +date: 2023-07-03 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 88c05b38619296..22d2d4f11a7036 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-02 +date: 2023-07-03 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 076c0e9a7e739d..385c8b7b370620 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 0a61e52c26a7af..feded3fb5194ac 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-02 +date: 2023-07-03 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 f5f79efbb59082..db392a7e558a2d 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 aa58aa852e4882..f04fb919cc799c 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 26e577088c3533..9b4fc1de7b3580 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 9348f53ef8a12c..9b46410b4c5d5d 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 14c069328b0f9d..f6024026e107b0 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-02 +date: 2023-07-03 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 ff17a019c49b43..ea4cd542ba79fc 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 452892e9a5c8b3..7b7474182acccb 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 3580aa3b020e99..45eafb44bfc209 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 1b77905ac2e0f3..2ef325b1161b0e 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 0ae709e997b732..dc7c24e327b29e 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 353dcfd6609fd9..8a4c00d3d5b3d3 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-02 +date: 2023-07-03 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 fd88bd145cf9d6..db198460df5562 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 3506ea1a6e4b84..d3179020d8a577 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 3362c17499aeb5..c57aa5a6b905f4 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 3087dcbb48240e..5a5bafaad26479 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 e8112968229bb4..f35498753f0dcc 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-02 +date: 2023-07-03 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 09e07908991f30..20ba41af78b051 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 f6cc31585f805a..72e523cd3bfccc 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 c956f2d1d16a18..8bc58dcf9a0b16 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 6be358ab68f9eb..49770b82a23170 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-02 +date: 2023-07-03 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 9839c24a3b667f..80a41f737d7a8b 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-02 +date: 2023-07-03 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 4595c6143305bb..43feccb9120762 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.devdocs.json b/api_docs/kbn_core_chrome_browser.devdocs.json index 32156759fca8b9..5d48630ad5476d 100644 --- a/api_docs/kbn_core_chrome_browser.devdocs.json +++ b/api_docs/kbn_core_chrome_browser.devdocs.json @@ -671,6 +671,56 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeHelpMenuLink", + "type": "Interface", + "tags": [], + "label": "ChromeHelpMenuLink", + "description": [], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeHelpMenuLink.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeHelpMenuLink.href", + "type": "string", + "tags": [], + "label": "href", + "description": [], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeHelpMenuLink.iconType", + "type": "string", + "tags": [], + "label": "iconType", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/core-chrome-browser", "id": "def-common.ChromeNavControl", @@ -941,6 +991,55 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeNavControls.setHelpMenuLinks", + "type": "Function", + "tags": [], + "label": "setHelpMenuLinks", + "description": [ + "Set the help menu links" + ], + "signature": [ + "(links: ", + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeHelpMenuLink", + "text": "ChromeHelpMenuLink" + }, + "[]) => void" + ], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeNavControls.setHelpMenuLinks.$1", + "type": "Array", + "tags": [], + "label": "links", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeHelpMenuLink", + "text": "ChromeHelpMenuLink" + }, + "[]" + ], + "path": "packages/core/chrome/core-chrome-browser/src/nav_controls.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -2227,6 +2326,55 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.setHelpMenuLinks", + "type": "Function", + "tags": [], + "label": "setHelpMenuLinks", + "description": [ + "\nOverride the default links shown in the help menu" + ], + "signature": [ + "(links: ", + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeHelpMenuLink", + "text": "ChromeHelpMenuLink" + }, + "[]) => void" + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.setHelpMenuLinks.$1", + "type": "Array", + "tags": [], + "label": "links", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeHelpMenuLink", + "text": "ChromeHelpMenuLink" + }, + "[]" + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "@kbn/core-chrome-browser", "id": "def-common.ChromeStart.getGlobalHelpExtensionMenuLinks$", @@ -2416,6 +2564,26 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.getHelpSupportUrl$", + "type": "Function", + "tags": [], + "label": "getHelpSupportUrl$", + "description": [ + "\nGet the support URL shown in the help menu" + ], + "signature": [ + "() => ", + "Observable", + "" + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@kbn/core-chrome-browser", "id": "def-common.ChromeStart.getIsNavDrawerLocked$", diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 2308b943b244ca..d18ed9db795ccc 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.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 | |-------------------|-----------|------------------------|-----------------| -| 157 | 0 | 61 | 0 | +| 166 | 0 | 67 | 0 | ## Common diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 7ef63aa5edb5da..3f904a46cf2156 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 74b0ba4ca2b25f..36f2c3f8d4211c 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 1cee7132a65e95..b13cbd06d06ae6 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 1f940b178f963e..07255a61ef8eea 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 18d6e4820d6446..d43b547f61936c 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 711d9a1bcdb206..574213ae5c3c51 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-02 +date: 2023-07-03 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 9a1c58533ee751..d3f84a72783724 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-02 +date: 2023-07-03 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 41c9d7fff9afd8..ea12c1ad4746a6 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 444bd7d872801c..a40642519f3735 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 ec550ca9ed6689..f4e6020861c2c3 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 bf2858726e004d..4aad2c2eb3045e 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 2638bd26282ac6..d6ea7c1ad09985 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 0fed9318f29e92..c9f3ffa34e4202 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-02 +date: 2023-07-03 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 06abb4f64a731f..a1746de33122b8 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-02 +date: 2023-07-03 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 fcd9c6e8284197..79c322f80b0d5b 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 eef222519f7d86..a816923aade617 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 cda1aa9e4ca3cb..1672f37050fded 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 8fef4e8e6b6c4a..9b4d14ae1b7cd7 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 71a843bb5de9e8..0565c0ab62ed24 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-02 +date: 2023-07-03 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 be282aeda65cee..8389ce52496569 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 0934340e352da2..dd0d1aaad67dd9 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 3ca3532ead5344..0f5abe010369c1 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 38412577f7f2e2..5bfec1ca6c4b36 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-02 +date: 2023-07-03 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 3133db18a475c2..e7feab4db21181 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 7fcacafa444ba8..b78a3adba13971 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 9f3095e80037b5..84154ebfde0891 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 930d91f5cf67c2..e47082f7c1934d 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 8b8a90d770f85a..36e70d152ebfbc 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 dd9a0c2b7bbdfd..80282eb1ff5fc4 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 83b1a06040d560..60d57dd5e3e387 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 2c7d7c1baf3d6b..3f958fd4c0e4a1 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-02 +date: 2023-07-03 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 35823a54f83648..5f493fcce34cd6 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-02 +date: 2023-07-03 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 7caac93bcb45ea..d6aad01e676eb2 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 2209923ae7eb13..cd4b201905a621 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 e407f301c7bea2..4eefbbc1a62122 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 ed9e3a44565bab..7202e3113edc7b 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 11b6016f168c81..35333e04959760 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 fef5570a07f822..53697d0e06fa51 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 f7ca46498e0a8a..99d48d422df00b 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 478185a196e730..fffc5966c181f1 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-02 +date: 2023-07-03 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 fd9ab7ef0d11eb..6b1abf77a61ad0 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 38c68ace2536b0..e2d870af2bd905 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-02 +date: 2023-07-03 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 c3083945e2313c..558e64209ae587 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-02 +date: 2023-07-03 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 9ed5605b743323..9302f4d7edfb9a 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 9020bbca83bed2..b49b267aa07d35 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 2e720b804cacba..ff78a784afc473 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 1b570da76ae0ae..44e99bcd360f1a 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 c50ace5947aeff..cdc4974ac790f3 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -3739,10 +3739,6 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/vulnerabilities_dashboard.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts" - }, { "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/status/status.ts" @@ -5415,18 +5411,6 @@ "plugin": "cloudChat", "path": "x-pack/plugins/cloud_integrations/cloud_chat/server/routes/chat.test.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" - }, { "plugin": "fleet", "path": "x-pack/plugins/fleet/server/routes/uninstall_token/handlers.test.ts" @@ -14038,6 +14022,10 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts" }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts" + }, { "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts" @@ -14338,6 +14326,18 @@ "plugin": "cloudDefend", "path": "x-pack/plugins/cloud_defend/server/routes/status/status.test.ts" }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts" + }, { "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.test.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 870811d210f5fa..9c8f8292e92038 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-02 +date: 2023-07-03 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 8ef80911634942..fc90a923127ec2 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 29142784460bae..fca10b2470a7bc 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 97520c0940b91f..da45a2b7a3937f 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 df298eab3dbc5d..b16574938c4967 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 4a4c89dc112913..e3e029d65d6d66 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-02 +date: 2023-07-03 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 28f9543821f46e..6d281f60d24b68 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 4ed13f90602ec7..df1e020523f62b 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 f3f43c40c64d0b..0ad4d0f2ec0ed9 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 9335424a860bff..9a81492fe19754 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 aaf7f13c5816c5..3ec3daae38115c 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 9b12db241c884a..212298f954c989 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 33022604b1c453..626ce47187eac6 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 0f9ca0fe8efd8d..e2830ae5cf0168 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-02 +date: 2023-07-03 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 7ba047e926db88..64e32ba8edc671 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 be1c5f7cf5fc16..e461b3fb20f9ab 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 89cde493271506..34b1a1178c5d74 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 f5c7ac871ff1c5..f3236e8121fdd3 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-02 +date: 2023-07-03 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 1f5cf853c461be..73adce21cdcf7c 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 4e979c7494c71e..d28da30ecdd5d0 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 ddee499cd43bde..96963764a6763d 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 b2deb2a970e01d..8c75dde632791c 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 936a4ea8cf9776..52153d6ff57daf 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-02 +date: 2023-07-03 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 fef3ef31fd2934..00a6e9c8ad6d01 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 11e3c75cbbd058..a4c20122cb118b 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 ef818a7f133aa7..7f21472bb92e0b 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 eaab8ffd758c94..909233cc5ab6f8 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-02 +date: 2023-07-03 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 c9f9be77f5b0d0..bef05ac9357c3e 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 2b71cf785ea158..8d3df740e56ffe 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 3cd835763847b0..bb98f55ea0c41d 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 8a69370daab739..8e6d151c4d659f 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 fc4e9f8058653c..313654df45a85b 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 d9db22f1b4f305..772ceeee94c362 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 06433f9e611211..50f5127ccc679d 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 37ee78c036e47d..efe823a173a128 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 d260227d197f74..d9e879a748dc37 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 c57681a85da19d..602278778c3e6e 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index c2ae1953fe8172..15fadabe771b35 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-02 +date: 2023-07-03 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 a74aed12bfeae2..ecd45f7308de09 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 205f708d743cb2..8ce163e2665096 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-02 +date: 2023-07-03 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 b29d47d35dc460..054389789e925b 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 29ea6ecaef31ec..18d62db4cc7869 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 26727f813fc84a..f2bff07a801801 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 daa38c765b1f3e..f55cdab569d6bb 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 8e44c1c81370e0..7bcc25af5e6807 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 671c8785a4e4e6..dc2c8b47d9168a 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 00a655c59331fa..678967576150b1 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-02 +date: 2023-07-03 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 d4ed882b342775..fa67962a4b5693 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 b4123aad5eb3d9..9dffcf9fef3f81 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 3d7d2128151c5c..6b9dbfe06b4c3d 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 77d530c1af507e..ee12e8cc98ddbe 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 238012e0457b51..f6fdabf1d65679 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 898dec5f600f14..3e05cafa5ddd4c 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 4c0a0e56fd4476..149fbedfff6a9a 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-02 +date: 2023-07-03 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 c45aebe74e483f..ea4258f65d0d38 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 1bb1651f1ad206..a037d82b405490 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 2c76b360211276..f50bbb8616046a 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 86ad14cb7ca41d..a478edb3197517 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 03ac52ad11d173..35596d4d833c9c 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-02 +date: 2023-07-03 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 88e7dca6b2bcac..b0b5255227a364 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 2e265ecb1dd55a..7a0b0f68d5d320 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 88d1d72f234bc0..8d295836a6cf86 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-02 +date: 2023-07-03 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 15afa945cb7517..768599b5053bb9 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-02 +date: 2023-07-03 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 3a76d546f27812..511a84babbe8fc 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 f2bfca2d737f58..2fc2797f45d100 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-02 +date: 2023-07-03 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 a86432d832f9e6..37cc2281c42be8 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 c1e4bdd6e3b72f..baf2f79e049531 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 9d7f6d00d8408c..92205214d635ca 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-02 +date: 2023-07-03 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 7630cc8ff39451..beb474f595f4f3 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 1033d2f08e1670..b6e914193798eb 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 29c8a1b09be30b..7dbe9a90426e31 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-02 +date: 2023-07-03 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 db29925453cb13..0d6ecf679c5b01 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 e56f4d80e28c38..0e6f51e1c3309a 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 4e934f25665249..142f6035898c26 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index f54940cc66db74..f7d9767b813e17 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 11a95a79b67f1a..e39273566fa65d 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 87b51ebe1268fa..5057dd29a20de6 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 8d6e6886629303..ee79b6d1f903ba 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 b61afdc9b4cf88..f9b62b1dc92ce0 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-02 +date: 2023-07-03 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 64ffb7ed184151..bec01eeeb70339 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-02 +date: 2023-07-03 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 7ad93a87b5dc6f..cffe5df4a856ad 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 1229a7d07a1b7a..9bb9dc64916f28 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 b8ecbfa593ddf7..b5e3493f82751e 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-02 +date: 2023-07-03 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 8fe7b61733f673..0ca51dd533610d 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 ec74084879928d..d8aee8bf1a7f9a 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 f72402bdc94d7d..39a86e004ef48c 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-02 +date: 2023-07-03 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 04c30cf95236e3..f851a352f922dc 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-02 +date: 2023-07-03 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 109511c5f7bd9f..81e97a47315f89 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 a138e2197be65f..83d77c684910f5 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-02 +date: 2023-07-03 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 b41f0f433cea92..e39edeea0c06cf 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 645416b614d9a4..5bb1ef01346fe8 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 73ef8ab354bd1f..7d2b146ae217be 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index d053d994b9a8cb..e39f50ec0a1771 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-02 +date: 2023-07-03 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 0c9eadc5ed6d09..8e46553951fd4b 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-02 +date: 2023-07-03 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 fe194d1340611e..b12bd067253025 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-02 +date: 2023-07-03 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 6114e255597899..d8de57ea9eb71c 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-02 +date: 2023-07-03 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 685ea75710183c..3970bdf914e056 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-02 +date: 2023-07-03 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 a50ab3d723b0e4..24d30e69b89e7f 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-02 +date: 2023-07-03 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 35c0a3e18fdec7..5ee03ee5870e73 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-02 +date: 2023-07-03 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 05c83b9f7b00f9..d5b977c5cdee8b 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-02 +date: 2023-07-03 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 0dcbc454c599c2..b9c31f0d9e983b 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-02 +date: 2023-07-03 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 7c693fc7f9c537..7a6ec8b0b24184 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-02 +date: 2023-07-03 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 f5f6f5782e42b9..2a63690175ac15 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-02 +date: 2023-07-03 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 ecc2c8d3963b34..0c5e55f1530a3d 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-02 +date: 2023-07-03 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 91a217feb5bd6f..bc8cfc1ec87ad1 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-02 +date: 2023-07-03 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 f0e51e8d7b9ebe..2ccea747389a6e 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-02 +date: 2023-07-03 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 482f988de9a90e..c57740608bdd12 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 38e1fa294e145b..85fbfcea2892d5 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -479,7 +479,7 @@ "label": "kibana", "description": [], "signature": [ - "{ readonly guide: string; readonly autocompleteSuggestions: string; readonly secureSavedObject: string; readonly xpackSecurity: string; }" + "{ readonly askElastic: string; readonly createGithubIssue: string; readonly feedback: string; readonly guide: string; readonly autocompleteSuggestions: string; readonly secureSavedObject: string; readonly xpackSecurity: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, @@ -1008,6 +1008,17 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/doc-links", + "id": "def-common.DocLinksMeta.elasticGithubUrl", + "type": "string", + "tags": [], + "label": "elasticGithubUrl", + "description": [], + "path": "packages/kbn-doc-links/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/doc-links", "id": "def-common.DocLinksMeta.docsWebsiteUrl", diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 69eebd4480917e..b5e4d8524be67c 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/docs](https://github.com/orgs/elastic/teams/docs) for question | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 71 | 0 | 71 | 2 | +| 72 | 0 | 72 | 2 | ## Common diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index ba7f59fa03b2d6..73419b45a76af3 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 d3f708077326fd..4b6d0775c4b0e0 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-02 +date: 2023-07-03 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 914c205a1cb525..2eb3f2d9143d3b 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-02 +date: 2023-07-03 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 336891fd163819..c7a18913894110 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-02 +date: 2023-07-03 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 c4435a1690c8ab..6a512056beced2 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index d45d8157e02c44..2f2101d15abd1c 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 6ed694f3be482e..1239f4f1c5e005 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-02 +date: 2023-07-03 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 0eda635a4aac60..37873c856d57f9 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-02 +date: 2023-07-03 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 1eb9b0d5e21a45..78131a2926647a 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-02 +date: 2023-07-03 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 c4a17091bb4317..6c30bc36e3c11a 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-02 +date: 2023-07-03 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 775ced7f22bf29..596300c1b5913a 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-02 +date: 2023-07-03 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 3280015d9e55a3..570b75b9240641 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index b28be971abfc17..6cbe0e1c4e47cc 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-02 +date: 2023-07-03 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 02233db1008438..dca9f7d611e9c7 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 2d26c4d04ad7ae..762218ef04c432 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-02 +date: 2023-07-03 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 7ed6c18db66d56..ee52ceb039d68a 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 0f7308e09368cd..614a3fc288bb29 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-02 +date: 2023-07-03 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 adc951e4ed6e28..f5948cfc5773dd 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-02 +date: 2023-07-03 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 ee1a5e3dbd11a3..67f03a9e45bc87 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 6dba378ca5704f..797b415e2da5f1 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index e93d4ab0ffa0bf..0d95afc4efd7f9 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-02 +date: 2023-07-03 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 d1af1ac4e6b74a..60231ea44d3060 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-02 +date: 2023-07-03 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 4cd77461cab950..71a44612532b07 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 3a9e544ffb6b89..a19ad26316f301 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-02 +date: 2023-07-03 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 037557fcfdcc04..a569f10bf7bd99 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-02 +date: 2023-07-03 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 650de501e371d4..6daa232d8b9b0e 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-02 +date: 2023-07-03 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 c49962382fca88..347792b5678fab 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-02 +date: 2023-07-03 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 74b5761735b9ce..bb21d9c01981e8 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-02 +date: 2023-07-03 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 eb10c7df394e26..65ff9f51736291 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-02 +date: 2023-07-03 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 e7ab47cb819d81..a7c683a49990d3 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-02 +date: 2023-07-03 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 5fec521bfd9caf..77cd989c028427 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-02 +date: 2023-07-03 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 4e59a5aafc061f..d2fa70c64ec432 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 4eb31d007adf57..38fdd3c2e61d64 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-02 +date: 2023-07-03 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 0db9429190a9c7..d687e871dc6980 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-02 +date: 2023-07-03 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 def764a1044373..e2c176c38744ef 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-02 +date: 2023-07-03 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 9bf876a5f552a5..b8bd537cdf4b16 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-02 +date: 2023-07-03 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 19431244697941..eef98288dea02f 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 6731f017be3764..150f581c087441 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-02 +date: 2023-07-03 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 d880841674023f..f9231eb985b6cd 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index d3f18e375a8ea8..f035ae091252d0 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-02 +date: 2023-07-03 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 379a1694130361..1031ad4ffaa31b 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index d608bd5b244fc6..6be3e936cde506 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-02 +date: 2023-07-03 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 0a461a140c5541..7c38ff1a3d33bd 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-02 +date: 2023-07-03 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 f434027252e173..4441d8cfe1704f 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 61f7daa6777989..257ba4e7fc4e54 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 e8caf3b02939e5..bd1e1501481cd1 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 862475108df398..67992c1e250739 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 620ba93c3f8210..9639238308b58f 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-02 +date: 2023-07-03 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 66f14f008a2078..8ae9d959e5c41f 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-02 +date: 2023-07-03 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 ecc7dbfe445dfa..d6a6621ffa99ce 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 2e5365e139267b..f73cb8fb9678ff 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 4cfec5729cedad..4a3a0ec674c29a 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-02 +date: 2023-07-03 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 5d2aa52937b1d3..6a39f28206866e 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-02 +date: 2023-07-03 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 215c6066be6b0a..e074cff2362f11 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-02 +date: 2023-07-03 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 7465e5022a6719..c612dde0333f7c 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-02 +date: 2023-07-03 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 642096c1de6530..0588bf88fca635 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-02 +date: 2023-07-03 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 9d99f398788d69..6efe0f92bf6696 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 727441e8aef930..4c9d14a51e53ad 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 605c3bc446d0ab..1b34b0a238b16b 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 ca301d8a637975..42d7a07ebc6d50 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 525aa819a3ea57..a16555eb88815d 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 7b3bb06f6e2ece..22e457a4ebcf25 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-02 +date: 2023-07-03 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 82cb6a37bcfde0..2ec62c0170c423 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 686c33d18674fd..85b4f63b897b43 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index ce450198215ecd..f302e95a34e306 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-02 +date: 2023-07-03 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 d9ecd5cf2cdba3..1d18012d3d06e7 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-02 +date: 2023-07-03 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 564d74162358dc..ab0be9166607a5 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 46a9dacb7f870f..dcfab0f732e8d5 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-02 +date: 2023-07-03 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 6afceea407af7b..8de49e90a12190 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-02 +date: 2023-07-03 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 4bb8ec473b25a6..e96708f0d7deeb 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 22672f2be395f3..a698699823a0b8 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 496cb382da32f4..6d31f2d49b3990 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-02 +date: 2023-07-03 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 9517d4aa3a69ac..8f18fcc306e781 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 7c64d74a44b6da..cb2c76074f3d9f 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-02 +date: 2023-07-03 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 9a5bf88b936a43..fbc5385de83c67 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 9d26f86cc71d9f..b10707fad90a5a 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-02 +date: 2023-07-03 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 0cea41c8c5efe8..1a5fba09feb55b 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-02 +date: 2023-07-03 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 6abfa8aa699a91..a9e4810644cab9 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-02 +date: 2023-07-03 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 403e3ad484b1ce..1a20fb5676183e 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-02 +date: 2023-07-03 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 a02c55267c44b3..d9b27d4ae9f9c4 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 6106c9fda73a3c..f4386f74487ed7 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.devdocs.json b/api_docs/kbn_rrule.devdocs.json new file mode 100644 index 00000000000000..849f4cc2f8ff78 --- /dev/null +++ b/api_docs/kbn_rrule.devdocs.json @@ -0,0 +1,273 @@ +{ + "id": "@kbn/rrule", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule", + "type": "Class", + "tags": [], + "label": "RRule", + "description": [], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.Unnamed.$1", + "type": "CompoundType", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "Options" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.between", + "type": "Function", + "tags": [], + "label": "between", + "description": [], + "signature": [ + "(start: Date, end: Date) => Date[]" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.between.$1", + "type": "Object", + "tags": [], + "label": "start", + "description": [], + "signature": [ + "Date" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.between.$2", + "type": "Object", + "tags": [], + "label": "end", + "description": [], + "signature": [ + "Date" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.before", + "type": "Function", + "tags": [], + "label": "before", + "description": [], + "signature": [ + "(dt: Date) => Date" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.before.$1", + "type": "Object", + "tags": [], + "label": "dt", + "description": [], + "signature": [ + "Date" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.after", + "type": "Function", + "tags": [], + "label": "after", + "description": [], + "signature": [ + "(dt: Date) => Date | null" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.after.$1", + "type": "Object", + "tags": [], + "label": "dt", + "description": [], + "signature": [ + "Date" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.all", + "type": "Function", + "tags": [], + "label": "all", + "description": [], + "signature": [ + "(limit?: number) => AllResult" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.RRule.all.$1", + "type": "number", + "tags": [], + "label": "limit", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [], + "interfaces": [], + "enums": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.Frequency", + "type": "Enum", + "tags": [], + "label": "Frequency", + "description": [], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.Weekday", + "type": "Enum", + "tags": [], + "label": "Weekday", + "description": [], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.ConstructorOptions", + "type": "Type", + "tags": [], + "label": "ConstructorOptions", + "description": [], + "signature": [ + "Omit & { byweekday?: (string | number)[] | null | undefined; wkst?: number | \"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\" | null | undefined; }" + ], + "path": "packages/kbn-rrule/rrule.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/rrule", + "id": "def-common.WeekdayStr", + "type": "Type", + "tags": [], + "label": "WeekdayStr", + "description": [], + "signature": [ + "\"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\"" + ], + "path": "packages/kbn-rrule/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx new file mode 100644 index 00000000000000..7fe59eb4f55533 --- /dev/null +++ b/api_docs/kbn_rrule.mdx @@ -0,0 +1,36 @@ +--- +#### +#### 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: kibKbnRrulePluginApi +slug: /kibana-dev-docs/api/kbn-rrule +title: "@kbn/rrule" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/rrule plugin +date: 2023-07-03 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] +--- +import kbnRruleObj from './kbn_rrule.devdocs.json'; + + + +Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 16 | 0 | 16 | 1 | + +## Common + +### Classes + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 3168bcbdfa181b..6e4d33e4c9fd96 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 415fa0c8034f13..b259e39c97e001 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index d544643da44da0..3c3c34c2c8d237 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-02 +date: 2023-07-03 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 f1bacfdb3a3353..ae75ed838a5fb4 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-02 +date: 2023-07-03 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 f05f74000ad403..c469670905c4ef 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-02 +date: 2023-07-03 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 dc2ae0e6d75440..239a7da01e2ba8 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-02 +date: 2023-07-03 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 57a15f4ab340a9..bdcac24385621d 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-02 +date: 2023-07-03 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 6ae08dd35f7ad5..286bafc4be8ae5 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 6e1a1312d0c60c..ced451bf44cf89 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-02 +date: 2023-07-03 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 c8b174a29c6e07..134ded89594125 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-02 +date: 2023-07-03 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 e59d8787fdc160..0f5e65cdca82d7 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 5b6470353bdf21..243de472d8d169 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-02 +date: 2023-07-03 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 2f253d2dc3f848..20c322ba723417 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-02 +date: 2023-07-03 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 828a04b86b59b4..86f58857a5b887 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-02 +date: 2023-07-03 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 dada7a67a56943..fe7aafdde510ae 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 8271a04ed50eba..9351ba6a822743 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-02 +date: 2023-07-03 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 9154de622d790a..bed2d7ceb892a0 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-02 +date: 2023-07-03 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 eb1cb335df1381..8864c0556d09c3 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-02 +date: 2023-07-03 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 86ab4ef3d78f20..b771b4233129c8 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 b958c648882eb4..48dd017d21cd81 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-02 +date: 2023-07-03 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 7ec6ebb027c5db..e017156293a510 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-02 +date: 2023-07-03 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 e6943886fa508f..ccd098e0cce091 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-02 +date: 2023-07-03 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 fc807c90dfdd45..b4937bf6ce69ec 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-02 +date: 2023-07-03 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 a7c48ca97b4f63..60bf1fc183a501 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 633deb56bfe722..eb5254b30807c0 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 814188e83a0e04..3050200b77926f 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-02 +date: 2023-07-03 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 a4552a7ea4de81..43a79bb804df9d 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-02 +date: 2023-07-03 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 4886fdbe594758..365d3827958518 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 2dee3e854401af..e3f3bc58ab2e3e 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 7296a74ffdba82..bbf239c1a54f55 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index fcb02f13ef22c1..c2ffcbecd4cbfb 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index d8e2838726f7cb..0adfb9feb12003 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-02 +date: 2023-07-03 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 b8337b4c4e1243..4318ee625009d0 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-02 +date: 2023-07-03 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 dd1bc2cff7cc28..81ce0412163142 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 d82b46f5d38275..c4513f09502731 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 444d9d8588295e..8822612effecf1 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-02 +date: 2023-07-03 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 72265dcfd4cb87..b8e314847b7d20 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-02 +date: 2023-07-03 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 7303436ed230e0..54002fd5e231aa 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 e4aeaeac2445f3..4833a17b136461 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 914b89e0ff249e..69bf1ba9714c0e 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-02 +date: 2023-07-03 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 87fb089853519e..603f55f21452cf 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-02 +date: 2023-07-03 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 6b3f92de553600..9d35e93e55d588 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-02 +date: 2023-07-03 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 c7c9b51f7ca2b5..aea6d9ca9c9441 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-02 +date: 2023-07-03 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 f5ef0dd519b519..73a24de7c582ed 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-02 +date: 2023-07-03 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 36a09097e5cd07..8d4e9f253a7404 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 24af85c574a07d..3259792fa8a3e8 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-02 +date: 2023-07-03 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 db96cf086ab1d8..47995a01be9407 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 1ee0a7a7144442..94ce217ad52512 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-02 +date: 2023-07-03 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 3e52f4e4653cfe..b4208bdb934ebf 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 b258ad7c9ba9dd..a60e61262df8ac 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-02 +date: 2023-07-03 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 7e6967cbee97b8..c34c48ba5a2c40 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 d4da52368e2bcc..5625062922f682 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-02 +date: 2023-07-03 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 748499dc537483..ae72e8f25ece2d 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 055a8bd8f5de35..cd7f501ef59bdd 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-02 +date: 2023-07-03 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 cc5762bf73bbc1..fb7deaf5ef3df6 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-02 +date: 2023-07-03 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 c3926558f090c3..bf6a8f93ab49e7 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 e2383f667c00c5..43cfd25a4b3a9e 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 bd732b0ee417e7..176160b9a96137 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-02 +date: 2023-07-03 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 709e290b0b01f8..7ec40f853f6234 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-02 +date: 2023-07-03 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 c0fb4fb41a95a5..7606162f3db6b4 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 43d349bdd7d38b..926fcbffc93e8e 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-02 +date: 2023-07-03 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 2701baabd9bc9c..e0e6eb404306db 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-02 +date: 2023-07-03 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 37044b10298f93..8ab5f358d30b96 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-02 +date: 2023-07-03 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 ded426f6902dbb..c40f63fd15ba6f 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-02 +date: 2023-07-03 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 5507797d9fbf04..9c12c13d09d0e7 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-02 +date: 2023-07-03 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 578a46fe0d0eb7..b6b5e86ea67e02 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-02 +date: 2023-07-03 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 db4efd0f4620cf..5bde2ad8365f7e 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-02 +date: 2023-07-03 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 0cef6235748ae3..66f26519d1ab6a 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index edf8bb06ee42f5..815a97c1dfffe1 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-02 +date: 2023-07-03 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 dc4d7fd79a59d9..9507e46669d509 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-02 +date: 2023-07-03 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 8792d140843097..96b4e7cb42636f 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-02 +date: 2023-07-03 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 678ef6d8277e93..e10964750f681c 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-02 +date: 2023-07-03 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 1c07e720289b90..16e559f3cd948a 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index bc025d75ecef34..5386812542a2d4 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-02 +date: 2023-07-03 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 cdd05efb0703b0..d8c75ae07419a8 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-02 +date: 2023-07-03 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 f432d2314e3220..f37190ddc1e0f0 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-02 +date: 2023-07-03 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 a01f84efbac622..101042ea6c065d 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 4ac38df6c8b00e..b4fcaea9aecd0f 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-02 +date: 2023-07-03 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 308dabfbaf97e6..0bf8cb2d6e0393 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-02 +date: 2023-07-03 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 d8314d7089912a..23560795684df9 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-02 +date: 2023-07-03 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 90d7e277abb5f9..07cd8dbb085fff 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-02 +date: 2023-07-03 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 eabcb60fd23e06..c445dd46160a88 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index c3cccfbd822c9c..5fbabd339666d3 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index ea8e88e5c7c3f4..e8551189096d53 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index b9dca5a378f984..fde8c7f3edeb7f 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-02 +date: 2023-07-03 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 9dfa1d44a98c5b..d911e61e165d33 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-02 +date: 2023-07-03 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 c24e1efef4e8bb..d322837209b81b 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-02 +date: 2023-07-03 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 e8e008c76c10d3..d48c3e8f348b15 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 293248469057d7..d9e75497bad3f0 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index a3de6a755d8e8c..ee7ba8f9abebf4 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-02 +date: 2023-07-03 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 b752cfe59738ad..c5ff29da175eaf 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-02 +date: 2023-07-03 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 b00b072453eebb..28a0faf0b7a932 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-02 +date: 2023-07-03 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 f63301246f3689..ac0766b2756c19 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-02 +date: 2023-07-03 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 24e3de6556fe70..0a1c3bae111042 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-02 +date: 2023-07-03 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 cfb73fd65b3bb4..9225b262dbe9f2 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-02 +date: 2023-07-03 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 6415ee26c2eff6..8de872753892ac 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 433e2310d3c742..047070d494b974 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 8689f02f61bdf0..bbaaad6c45db51 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 24c4becf4f0b37..6f730945cc4ad1 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-02 +date: 2023-07-03 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 aa41e122454de1..7dce59669f358a 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-02 +date: 2023-07-03 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 31416c36e90279..254967debb785b 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 7cd5c270a7134b..a7c468d0acbdfd 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index db969ba0608721..ca697dc1cc9ec2 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-02 +date: 2023-07-03 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 3529ff50d0e0cd..f7df9e858e7687 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-02 +date: 2023-07-03 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 793b4ce79984eb..40c69346b94456 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-02 +date: 2023-07-03 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 baa4ccb1b946d8..a381c4195c2d95 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index b5fa3e93b2433d..72fe7e558062f4 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-02 +date: 2023-07-03 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 1b3cac88b6a29c..19b04cca8047c6 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 8c583c52ba6350..7cccdcb4a8c98d 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-02 +date: 2023-07-03 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 418a1d710c7b22..45d01be1c6443f 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-02 +date: 2023-07-03 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 388485fecd08f5..0c3e65f60d78ae 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 00cf378719a8df..713bd0c62c1e21 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 644 | 535 | 38 | +| 645 | 536 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70948 | 544 | 60765 | 1409 | +| 70960 | 544 | 60773 | 1410 | ## Plugin Directory @@ -30,7 +30,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 270 | 10 | 265 | 27 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 1 | 32 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 45 | 0 | 27 | 1 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 635 | 1 | 611 | 47 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 619 | 1 | 595 | 47 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 48 | 0 | 48 | 113 | | | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | Asset manager plugin for entity assets (inventory, topology, etc) | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 9 | 0 | @@ -38,7 +38,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 80 | 0 | 65 | 26 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 268 | 16 | 253 | 10 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 52 | 0 | 11 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 54 | 0 | 12 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 3 | 0 | 2 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | This plugin exists as a workaround for using `cloudChat` plugin in plugins which can't have a direct dependency on security plugin. | 5 | 0 | 5 | 0 | | | [@elastic/platform-onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | Static migration page where self-managed users can see text/copy about migrating to Elastic Cloud | 8 | 1 | 8 | 1 | @@ -267,7 +267,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 5 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 16 | 0 | 7 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 6 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 157 | 0 | 61 | 0 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 166 | 0 | 67 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 8 | 0 | 8 | 0 | @@ -422,7 +422,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 101 | 0 | 85 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 15 | 0 | 9 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 27 | 2 | 24 | 0 | -| | [@elastic/docs](https://github.com/orgs/elastic/teams/docs) | - | 71 | 0 | 71 | 2 | +| | [@elastic/docs](https://github.com/orgs/elastic/teams/docs) | - | 72 | 0 | 72 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 0 | 34 | 4 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 11 | 0 | @@ -504,6 +504,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 6 | 0 | 6 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 73 | 0 | 65 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 13 | 2 | 8 | 0 | +| | [@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) | - | 107 | 0 | 104 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 41 | 0 | 35 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 4f1d204a682bae..18f78a4ea24275 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-02 +date: 2023-07-03 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 6e9c106ab943e8..ae042466b51ee0 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 2989b9e9beec4b..cdf5e69b2a7bfa 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-02 +date: 2023-07-03 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 2c7e5f970816e5..bde1754b6d36b6 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 5f1d5f492d3307..666e74dc24ee14 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 35e1e83849c180..56ef3a6a083b19 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-02 +date: 2023-07-03 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 a2d078a742c4dc..0e2f5fa7c3ca24 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-02 +date: 2023-07-03 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 34b2a84e8c3f7d..4b755988ed70fc 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-02 +date: 2023-07-03 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 fb0683ffbc92e2..745cc7089a5f75 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-02 +date: 2023-07-03 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 5866100adbe852..24f360208256f5 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-02 +date: 2023-07-03 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 0cdb66a3c12b69..31ca9217da8fae 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-02 +date: 2023-07-03 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 0774c150a95f88..e6213821875828 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-02 +date: 2023-07-03 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 4f9a09475a6a0a..ca16449b6e8bd6 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-02 +date: 2023-07-03 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 1802fef00ac0eb..ddd11a2636676e 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-02 +date: 2023-07-03 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 2f4972f0ce5195..f273270e2ac701 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-02 +date: 2023-07-03 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 685e7c760c0eaa..eeecae3ee29db6 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-02 +date: 2023-07-03 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 05ea5ec3929b26..57a720991cc393 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-02 +date: 2023-07-03 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 f7777b78a06ade..5a543aeb6ccf5a 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index ab63e80837ee13..2442708db81a7f 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-02 +date: 2023-07-03 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 8d15175fe257d7..3c8c535fcfdf68 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-02 +date: 2023-07-03 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 b6cbab543b9d1e..f9592d2e853098 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index ec9c383a6bf33e..f3c01d3ce60216 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index b26a491fb65da1..d2fde45c2ea697 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-02 +date: 2023-07-03 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 26bd21e3de88fd..7e960f24720514 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-02 +date: 2023-07-03 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 0a1abe4a728e90..a0b069f790b58d 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-02 +date: 2023-07-03 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 8fda77f8bfa78b..6bd068ccfb441c 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-02 +date: 2023-07-03 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 a706414ad56f30..871a33484bd3d5 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-02 +date: 2023-07-03 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 7593306b4dce93..26dd11a63e5195 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-02 +date: 2023-07-03 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 341a7e41ed21b3..06ea30b7ee13ab 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-02 +date: 2023-07-03 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 aec532051f98bf..cbc4dcc9297069 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-02 +date: 2023-07-03 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 d80816711d3bb6..a175d612a4e7b3 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-02 +date: 2023-07-03 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 0ceda636e947f6..18a82f1b71edf2 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-02 +date: 2023-07-03 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 fc2bf3eefa2721..79a860406a302a 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-02 +date: 2023-07-03 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 cc74119ee4be8f..50dc9a5316727a 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-02 +date: 2023-07-03 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 731bbc38959d88..34394247d19ceb 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-02 +date: 2023-07-03 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 7853fa4ee3f9c0..b0de367357e961 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-02 +date: 2023-07-03 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 65e4578d007ddc..e7f9632f008611 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-02 +date: 2023-07-03 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 ca5546b51f81e8..cbcb2011869cf8 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-02 +date: 2023-07-03 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 8b28f982c909d2..cad6c4aca0a0d7 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-02 +date: 2023-07-03 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 e3bcc5945648b8..2756ee9783a4fb 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 76dfbd26239fb7..a937258c3abb8f 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-02 +date: 2023-07-03 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 d50428a99432da..0fee1d0bb852af 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-02 +date: 2023-07-03 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 bfe65c2f451ede..4c7e6ec585f92f 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 4375269d97c8a2..52ea956af61732 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-02 +date: 2023-07-03 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 7ed0d48923b76a..28fda03e4c7b04 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-02 +date: 2023-07-03 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 644c92d3e86741..35e49857602257 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-02 +date: 2023-07-03 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 cc394e5ed6c2cb..c46d34717bc975 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-02 +date: 2023-07-03 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 46a0ea46d935b2..963e602c35be5d 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-02 +date: 2023-07-03 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 08104c073aba23..23040c12a4a17c 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-02 +date: 2023-07-03 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 e3d937a0d4e980..3ab7c3e7f5eb47 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-02 +date: 2023-07-03 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 98d46eec4c6648..7efbd34be21d7a 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-02 +date: 2023-07-03 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 090f16f98a6af0..74a5b9517cec4f 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-02 +date: 2023-07-03 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 b9a5529c93792b..20d1d82c6f814e 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-02 +date: 2023-07-03 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 e002acb767b25f..3446f042583a13 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-02 +date: 2023-07-03 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 5a57a88e97d10d..937a47e7be8c44 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-02 +date: 2023-07-03 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 0d980931f1036e..e4ab55019da23f 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 07e94e5d4657b6..4df3e47fce1b6a 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 60733ec32a7feb..b208bb40e55e7b 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-02 +date: 2023-07-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 995d8f1e01f1c1ae5635e71a044eaa3f8f248de7 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Mon, 3 Jul 2023 10:42:21 +0200 Subject: [PATCH 11/98] [Ops] Fix es snapshot startup for params with dots in their path (#161022) ## Summary In a module where we'd copy configuration files, an `isFile` function would give false positives on folders with `.` in their names (mistaking them for extensions). It's now fixed to use `statSync(...).isFile()`. Closes #161013 ### Checklist [x] Unit test added, and works --- .../kbn-es/src/utils/extract_config_files.test.js | 12 ++++++++++++ packages/kbn-es/src/utils/extract_config_files.ts | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/kbn-es/src/utils/extract_config_files.test.js b/packages/kbn-es/src/utils/extract_config_files.test.js index a78dc8111707f7..313a8c68b01944 100644 --- a/packages/kbn-es/src/utils/extract_config_files.test.js +++ b/packages/kbn-es/src/utils/extract_config_files.test.js @@ -10,6 +10,11 @@ jest.mock('fs', () => ({ readFileSync: jest.fn(), existsSync: jest.fn().mockImplementation(() => true), writeFileSync: jest.fn(), + statSync: jest.fn((fileName) => { + return { + isFile: () => fileName.endsWith('.yml'), + }; + }), })); const { extractConfigFiles } = require('./extract_config_files'); @@ -63,3 +68,10 @@ test('ignores directories', () => { expect(config).toEqual(['path=foo.yml', 'foo.bar=/data/bar']); }); + +test('ignores directories with dots in their names', () => { + fs.existsSync = () => true; + const config = extractConfigFiles(['path=/data/foo.yml', 'foo.bar=/data/ba/r.baz'], '/es'); + + expect(config).toEqual(['path=foo.yml', 'foo.bar=/data/ba/r.baz']); +}); diff --git a/packages/kbn-es/src/utils/extract_config_files.ts b/packages/kbn-es/src/utils/extract_config_files.ts index ff07c77258d05a..908005887dbc01 100644 --- a/packages/kbn-es/src/utils/extract_config_files.ts +++ b/packages/kbn-es/src/utils/extract_config_files.ts @@ -29,6 +29,7 @@ export function extractConfigFiles( if (isFile(value)) { const filename = path.basename(value); const destPath = path.resolve(dest, 'config', filename); + copyFileSync(value, destPath); options?.log.info('moved %s in config to %s', value, destPath); @@ -43,7 +44,7 @@ export function extractConfigFiles( } function isFile(dest = '') { - return path.isAbsolute(dest) && path.extname(dest).length > 0 && fs.existsSync(dest); + return fs.existsSync(dest) && fs.statSync(dest).isFile(); } function copyFileSync(src: string, dest: string) { From 80b602db4a8e3c269b3c724f6efa0534294aa645 Mon Sep 17 00:00:00 2001 From: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> Date: Mon, 3 Jul 2023 11:21:02 +0200 Subject: [PATCH 12/98] [Security Solution][Endpoint] Use fleet agent `last_checkin` status to show endpoint last seen status (#160506) ## Summary Shows agent last seen status on endpoint details/responder/hosts/alerts consistent with fleet agent status. - Removes some bit of redundant endpoint details that stored `HostMetadataInterface` from the redux store, as we already have a `hostInfo` that captures `HostInfo` ([`HostInfo` has `HostMetadataInterface`](https://github.com/elastic/kibana/blob/35f115ded0eea75b7e0dc7b57b045d5b43c876e8/x-pack/plugins/security_solution/common/endpoint/types/index.ts#L478)) instead. **Fleet:** ![Screenshot 2023-06-26 at 12 49 05](https://github.com/elastic/kibana/assets/1849116/963728be-51b3-43e8-84cf-e7934a369405) **Endpoints page** ![Screenshot 2023-06-26 at 12 49 01](https://github.com/elastic/kibana/assets/1849116/5cbb294c-d483-4c17-88f8-4560efea64cc) **Endpoint details** ![Screenshot 2023-06-30 at 16 23 26](https://github.com/elastic/kibana/assets/1849116/8c7c858e-b952-4d2c-8863-0ddb3bfd4210) **Responder** ![Screenshot 2023-06-28 at 10 28 23](https://github.com/elastic/kibana/assets/1849116/8c16889d-a89f-428d-978b-533ce92f2100) ### 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: Ashokaditya Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../endpoint_metadata_generator.ts | 1 + .../data_loaders/index_endpoint_hosts.ts | 38 +++++----- .../common/endpoint/types/index.ts | 14 +++- .../integration_tests/status_action.test.tsx | 4 +- .../status_action.tsx | 4 +- .../components/header_endpoint_info.test.tsx | 2 +- .../components/header_endpoint_info.tsx | 6 +- .../endpoint/use_get_endpoints_list.test.ts | 11 ++- .../pages/endpoint_hosts/store/builders.ts | 8 +-- .../pages/endpoint_hosts/store/index.test.ts | 8 +-- .../pages/endpoint_hosts/store/middleware.ts | 17 ++--- .../store/mock_endpoint_result_list.ts | 22 +++--- .../pages/endpoint_hosts/store/reducer.ts | 53 +++++--------- .../pages/endpoint_hosts/store/selectors.ts | 27 ++++---- .../management/pages/endpoint_hosts/types.ts | 19 ++--- .../view/details/components/actions_menu.tsx | 6 +- .../view/details/components/flyout_header.tsx | 8 +-- .../view/details/endpoint_details.tsx | 43 ++++-------- .../view/details/endpoint_details_content.tsx | 69 +++++++++---------- .../pages/endpoint_hosts/view/index.test.tsx | 32 +++++---- .../endpoint_metadata_service.test.ts | 8 ++- .../metadata/endpoint_metadata_service.ts | 14 ++-- 22 files changed, 199 insertions(+), 215 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts index 7d1b6f9086bcda..feb53ffd042b7d 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts @@ -215,6 +215,7 @@ export class EndpointMetadataGenerator extends BaseDataGenerator { }, }, }, + last_checkin: new Date().toISOString(), }; return merge(hostInfo, overrides); } diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts index d778e1cde027f9..eed88ea4d44d25 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts @@ -211,7 +211,7 @@ export async function indexEndpointHostDocs({ await client .index({ index: metadataIndex, - body: hostMetadata, + document: hostMetadata, op_type: 'create', refresh: 'wait_for', }) @@ -225,7 +225,7 @@ export async function indexEndpointHostDocs({ await client .index({ index: policyResponseIndex, - body: hostPolicyResponse, + document: hostPolicyResponse, op_type: 'create', refresh: 'wait_for', }) @@ -281,11 +281,9 @@ export const deleteIndexedEndpointHosts = async ( }; if (indexedData.hosts.length) { - const body = { - query: { - bool: { - filter: [{ terms: { 'agent.id': indexedData.hosts.map((host) => host.agent.id) } }], - }, + const query = { + bool: { + filter: [{ terms: { 'agent.id': indexedData.hosts.map((host) => host.agent.id) } }], }, }; @@ -293,7 +291,7 @@ export const deleteIndexedEndpointHosts = async ( .deleteByQuery({ index: indexedData.metadataIndex, wait_for_completion: true, - body, + query, }) .catch(wrapErrorAndRejectPromise); @@ -302,7 +300,7 @@ export const deleteIndexedEndpointHosts = async ( .deleteByQuery({ index: metadataCurrentIndexPattern, wait_for_completion: true, - body, + query, }) .catch(wrapErrorAndRejectPromise); } @@ -312,19 +310,17 @@ export const deleteIndexedEndpointHosts = async ( .deleteByQuery({ index: indexedData.policyResponseIndex, wait_for_completion: true, - body: { - query: { - bool: { - filter: [ - { - terms: { - 'agent.id': indexedData.policyResponses.map( - (policyResponse) => policyResponse.agent.id - ), - }, + query: { + bool: { + filter: [ + { + terms: { + 'agent.id': indexedData.policyResponses.map( + (policyResponse) => policyResponse.agent.id + ), }, - ], - }, + }, + ], }, }, }) diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index aa1881195a0b61..3e48770cd5b397 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -474,7 +474,7 @@ export type PolicyInfo = Immutable<{ }>; // Host Information as returned by the Host Details API. -// NOTE: `HostInfo` type is the original and defined as Immutable. +// NOTE:The `HostInfo` type is the original and defined as Immutable. export interface HostInfoInterface { metadata: HostMetadataInterface; host_status: HostStatus; @@ -485,7 +485,7 @@ export interface HostInfoInterface { */ configured: PolicyInfo; /** - * Last reported running in agent (may lag behind configured) + * Last reported running in agent (might lag behind configured) */ applied: PolicyInfo; }; @@ -494,14 +494,22 @@ export interface HostInfoInterface { */ endpoint: PolicyInfo; }; + /** + * The time when the Elastic Agent associated with this Endpoint host checked in with fleet + * Conceptually the value is the same as Agent['last_checkin'] if present, but we fall back to + * UnitedAgentMetadataPersistedData['united']['endpoint']['metadata']['@timestamp'] + * if `Agent.last_checkin` value is `undefined` + */ + last_checkin: string; } export type HostInfo = Immutable; // Host metadata document streamed up to ES by the Endpoint running on host machines. -// NOTE: `HostMetadata` type is the original and defined as Immutable. If needing to +// NOTE: The `HostMetadata` type is the original and defined as Immutable. If you need to // work with metadata that is not mutable, use `HostMetadataInterface` export type HostMetadata = Immutable; + export interface HostMetadataInterface { '@timestamp': number; event: { diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx index d229b297f239fc..3888af95da7043 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx @@ -53,9 +53,10 @@ describe('When using processes action from response actions console', () => { }; const endpointDetailsMock = () => { + const newDate = new Date('2023-04-20T09:37:40.309Z'); const endpointMetadata = new EndpointMetadataGenerator('seed').generateHostInfo({ metadata: { - '@timestamp': new Date('2023-04-20T09:37:40.309Z').getTime(), + '@timestamp': newDate.getTime(), agent: { id: agentId, version: '8.8.0', @@ -69,6 +70,7 @@ describe('When using processes action from response actions console', () => { }, }, }, + last_checkin: newDate.toISOString(), }); useGetEndpointDetailsMock.mockReturnValue({ data: endpointMetadata, diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/status_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/status_action.tsx index e901e9b1a116d9..357d0e566e3284 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/status_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/status_action.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { memo, useEffect, useMemo, useCallback } from 'react'; +import React, { memo, useCallback, useEffect, useMemo } from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import { v4 as uuidV4 } from 'uuid'; import { i18n } from '@kbn/i18n'; @@ -242,7 +242,7 @@ export const EndpointStatusActionResult = memo< 'xpack.securitySolution.endpointResponseActions.status.lastActive', { defaultMessage: 'Last active' } )} - value={endpointDetails.metadata['@timestamp']} + value={endpointDetails.last_checkin} /> ), diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.test.tsx index 4941fd59686ccc..5a1c8bab4c05ca 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.test.tsx @@ -58,7 +58,7 @@ describe('Responder header endpoint info', () => { ); expect(agentStatus.textContent).toBe(`UnhealthyIsolating`); }); - it('should show last updated time', async () => { + it('should show last checkin time', async () => { const lastUpdated = await renderResult.findByTestId('responderHeaderLastSeen'); expect(lastUpdated).toBeTruthy(); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.tsx index b56746e7890a66..e51989ce0cb7ec 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/components/header_endpoint_info.tsx @@ -9,10 +9,10 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, - EuiText, EuiSkeletonText, - EuiToolTip, EuiSpacer, + EuiText, + EuiToolTip, } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { FormattedMessage, FormattedRelative } from '@kbn/i18n-react'; @@ -88,7 +88,7 @@ export const HeaderEndpointInfo = memo(({ endpointId }) id="xpack.securitySolution.responder.header.lastSeen" defaultMessage="Last seen {date}" values={{ - date: , + date: , }} /> diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts index d6497c3516d820..d7f073b2a83382 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts @@ -142,6 +142,7 @@ describe('useGetEndpointsList hook', () => { : item.metadata.Endpoint.status, }, }, + last_checkin: item.last_checkin, }; }), }; @@ -164,9 +165,11 @@ describe('useGetEndpointsList hook', () => { const generator = new EndpointDocGenerator('seed'); const total = 60; const data = Array.from({ length: total }, () => { + const newDate = new Date(); const endpoint = { - metadata: generator.generateHostMetadata(), + metadata: generator.generateHostMetadata(newDate.getTime()), host_status: HostStatus.UNHEALTHY, + last_checkin: newDate.toISOString(), }; generator.updateCommonInfo(); @@ -200,9 +203,11 @@ describe('useGetEndpointsList hook', () => { const generator = new EndpointDocGenerator('seed'); const total = 61; const data = Array.from({ length: total }, () => { + const newDate = new Date(); const endpoint = { - metadata: generator.generateHostMetadata(), + metadata: generator.generateHostMetadata(newDate.getTime()), host_status: HostStatus.UNHEALTHY, + last_checkin: newDate.toISOString(), }; generator.updateCommonInfo(); @@ -229,7 +234,7 @@ describe('useGetEndpointsList hook', () => { .data.map((d) => d.metadata.agent.id) .slice(0, 50); - // call useGetEndpointsList with all 50 agents selected + // call useGetEndpointsList with all 50 agents selected const res = await renderReactQueryHook(() => useGetEndpointsList({ searchString: '', selectedAgentIds: agentIdsToSelect }) ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts index e3b7bb29ba2b3c..fb4270ee6dad54 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts @@ -19,11 +19,9 @@ export const initialEndpointPageState = (): Immutable => { loading: false, error: undefined, endpointDetails: { - hostDetails: { - details: undefined, - detailsLoading: false, - detailsError: undefined, - }, + hostInfo: undefined, + hostInfoError: undefined, + isHostInfoLoading: false, }, policyResponse: undefined, policyResponseLoading: false, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts index f83b58f57fb12a..1524b721cb07c6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts @@ -44,11 +44,9 @@ describe('EndpointList store concerns', () => { loading: false, error: undefined, endpointDetails: { - hostDetails: { - details: undefined, - detailsLoading: false, - detailsError: undefined, - }, + hostInfo: undefined, + hostInfoError: undefined, + isHostInfoLoading: false, }, policyResponse: undefined, policyResponseLoading: false, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts index 580a3b761d245c..d407a6cc27cce5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts @@ -16,22 +16,22 @@ import type { } from '@kbn/timelines-plugin/common'; import { BASE_POLICY_RESPONSE_ROUTE, + ENDPOINT_FIELDS_SEARCH_STRATEGY, HOST_METADATA_GET_ROUTE, HOST_METADATA_LIST_ROUTE, - metadataCurrentIndexPattern, - METADATA_UNITED_INDEX, METADATA_TRANSFORMS_STATUS_ROUTE, - ENDPOINT_FIELDS_SEARCH_STRATEGY, + METADATA_UNITED_INDEX, + metadataCurrentIndexPattern, } from '../../../../../common/endpoint/constants'; import type { GetHostPolicyResponse, HostInfo, HostIsolationRequestBody, - ResponseActionApiResponse, HostResultList, Immutable, ImmutableObject, MetadataListResponse, + ResponseActionApiResponse, } from '../../../../../common/endpoint/types'; import { isolateHost, unIsolateHost } from '../../../../common/lib/endpoint_isolation'; import { fetchPendingActionsByAgentId } from '../../../../common/lib/endpoint_pending_actions'; @@ -59,9 +59,9 @@ import type { } from '../types'; import type { EndpointPackageInfoStateChanged } from './action'; import { - detailsData, endpointPackageInfo, endpointPackageVersion, + fullDetailsHostInfo, getCurrentIsolationRequestState, getIsEndpointPackageInfoUninitialized, getIsIsolationRequestPending, @@ -86,7 +86,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory { // this needs to be called after endpointPackageVersion is loaded (getEndpointPackageInfo) - // or else wrong pattern might be loaded + // or else the wrong pattern might be loaded async function fetchIndexPatterns( state: ImmutableObject ): Promise { @@ -115,6 +115,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory (next) => async (action) => { next(action); @@ -329,13 +330,13 @@ const loadEndpointsPendingActions = async ({ dispatch, }: EndpointPageStore): Promise => { const state = getState(); - const detailsEndpoint = detailsData(state); + const detailsEndpoint = fullDetailsHostInfo(state); const listEndpoints = listData(state); const agentsIds = new Set(); // get all agent ids for the endpoints in the list if (detailsEndpoint) { - agentsIds.add(detailsEndpoint.elastic.agent.id); + agentsIds.add(detailsEndpoint.metadata.elastic.agent.id); } for (const endpointInfo of listEndpoints) { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts index 671347dcd27b36..f6c5c144f529b4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/mock_endpoint_result_list.ts @@ -7,11 +7,11 @@ import type { HttpStart } from '@kbn/core/public'; import type { + BulkGetPackagePoliciesResponse, GetAgentPoliciesResponse, GetAgentPoliciesResponseItem, - GetPackagesResponse, GetAgentsResponse, - BulkGetPackagePoliciesResponse, + GetPackagesResponse, } from '@kbn/fleet-plugin/common/types/rest_spec'; import type { GetHostPolicyResponse, @@ -25,8 +25,8 @@ import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_da import { INGEST_API_AGENT_POLICIES, INGEST_API_EPM_PACKAGES, - INGEST_API_PACKAGE_POLICIES, INGEST_API_FLEET_AGENTS, + INGEST_API_PACKAGE_POLICIES, } from '../../../services/policies/ingest'; import type { GetPolicyListResponse } from '../../policy/types'; import { pendingActionsResponseMock } from '../../../../common/lib/endpoint_pending_actions/mocks'; @@ -54,9 +54,12 @@ export const mockEndpointResultList: (options?: { const hosts: HostInfo[] = []; for (let index = 0; index < actualCountToReturn; index++) { + const newDate = new Date(); + const metadata = generator.generateHostMetadata(newDate.getTime()); hosts.push({ - metadata: generator.generateHostMetadata(), + metadata, host_status: HostStatus.UNHEALTHY, + last_checkin: newDate.toISOString(), }); } const mock: MetadataListResponse = { @@ -72,9 +75,12 @@ export const mockEndpointResultList: (options?: { * returns a mocked API response for retrieving a single host metadata */ export const mockEndpointDetailsApiResult = (): HostInfo => { + const newDate = new Date(); + const metadata = generator.generateHostMetadata(newDate.getTime()); return { - metadata: generator.generateHostMetadata(), + metadata, host_status: HostStatus.UNHEALTHY, + last_checkin: newDate.toISOString(), }; }; @@ -118,8 +124,8 @@ const endpointListApiPathHandlerMocks = ({ }; }, - // Do policies referenced in endpoint list exist - // just returns 1 single agent policy that includes all of the packagePolicy IDs provided + // Do policies reference in endpoint list exist + // just returns 1 single agent policy that includes all the packagePolicy IDs provided [INGEST_API_AGENT_POLICIES]: (): GetAgentPoliciesResponse => { return { items: [agentPolicy], @@ -184,7 +190,7 @@ const endpointListApiPathHandlerMocks = ({ }; /** - * Sets up mock impelementations in support of the Endpoints list view + * Sets up mock implementations in support of the Endpoints list view * * @param mockedHttpService * @param endpointsResults diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts index 8ad781c60dd201..db15ebcfa7343e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts @@ -11,11 +11,11 @@ import type { MetadataTransformStatsChanged, } from './action'; import { - isOnEndpointPage, + getCurrentIsolationRequestState, + getIsOnEndpointDetailsActivityLog, hasSelectedEndpoint, + isOnEndpointPage, uiQueryParams, - getIsOnEndpointDetailsActivityLog, - getCurrentIsolationRequestState, } from './selectors'; import type { EndpointState } from '../types'; import { initialEndpointPageState } from './builders'; @@ -97,7 +97,7 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta }, }; } else if (action.type === 'serverReturnedMetadataPatterns') { - // handle error case + // handle an error case return { ...state, patterns: action.payload, @@ -114,12 +114,8 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta endpointDetails: { ...state.endpointDetails, hostInfo: action.payload, - hostDetails: { - ...state.endpointDetails.hostDetails, - details: action.payload.metadata, - detailsLoading: false, - detailsError: undefined, - }, + hostInfoError: undefined, + isHostInfoLoading: false, }, policyVersionInfo: action.payload.policy_info, hostStatus: action.payload.host_status, @@ -129,11 +125,8 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta ...state, endpointDetails: { ...state.endpointDetails, - hostDetails: { - ...state.endpointDetails.hostDetails, - detailsError: action.payload, - detailsLoading: false, - }, + hostInfoError: action.payload, + isHostInfoLoading: false, }, }; } else if (action.type === 'endpointPendingActionsStateChanged') { @@ -262,44 +255,35 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta ...stateUpdates, endpointDetails: { ...state.endpointDetails, - hostDetails: { - ...state.endpointDetails.hostDetails, - detailsError: undefined, - }, + hostInfoError: undefined, }, loading: true, policyItemsLoading: true, }; } } else if (isCurrentlyOnDetailsPage) { - // if previous page was the list or another endpoint details page, load endpoint details only + // if the previous page was the list or another endpoint details page, load endpoint details only if (wasPreviouslyOnDetailsPage || wasPreviouslyOnListPage) { return { ...state, ...stateUpdates, endpointDetails: { ...state.endpointDetails, - hostDetails: { - ...state.endpointDetails.hostDetails, - detailsLoading: !isNotLoadingDetails, - detailsError: undefined, - }, + hostInfoError: undefined, + isHostInfoLoading: !isNotLoadingDetails, }, detailsLoading: true, policyResponseLoading: true, }; } else { - // if previous page was not endpoint list or endpoint details, load both list and details + // if the previous page was not endpoint list or endpoint details, load both list and details return { ...state, ...stateUpdates, endpointDetails: { ...state.endpointDetails, - hostDetails: { - ...state.endpointDetails.hostDetails, - detailsLoading: true, - detailsError: undefined, - }, + hostInfoError: undefined, + isHostInfoLoading: true, }, loading: true, policyResponseLoading: true, @@ -307,16 +291,13 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta }; } } - // otherwise we are not on a endpoint list or details page + // otherwise, we are not on an endpoint list or details page return { ...state, ...stateUpdates, endpointDetails: { ...state.endpointDetails, - hostDetails: { - ...state.endpointDetails.hostDetails, - detailsError: undefined, - }, + hostInfoError: undefined, }, endpointsExist: true, }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts index 1b4c716c374629..c01a7ea65a8d6f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts @@ -11,9 +11,9 @@ import { createSelector } from 'reselect'; import { matchPath } from 'react-router-dom'; import { decode } from '@kbn/rison'; import type { Query } from '@kbn/es-query'; -import type { Immutable, EndpointPendingActions } from '../../../../../common/endpoint/types'; +import type { EndpointPendingActions, Immutable } from '../../../../../common/endpoint/types'; import { HostStatus } from '../../../../../common/endpoint/types'; -import type { EndpointState, EndpointIndexUIQueryParams } from '../types'; +import type { EndpointIndexUIQueryParams, EndpointState } from '../types'; import { extractListPaginationParams } from '../../../common/routing'; import { MANAGEMENT_DEFAULT_PAGE, @@ -43,26 +43,23 @@ export const listLoading = (state: Immutable): boolean => state.l export const listError = (state: Immutable) => state.error; -export const detailsData = (state: Immutable) => - state.endpointDetails.hostDetails.details; - -export const fullDetailsHostInfo = (state: Immutable) => - state.endpointDetails.hostInfo; +export const fullDetailsHostInfo = ( + state: Immutable +): EndpointState['endpointDetails']['hostInfo'] => state.endpointDetails.hostInfo; -export const detailsLoading = (state: Immutable): boolean => - state.endpointDetails.hostDetails.detailsLoading; +export const isHostInfoLoading = ( + state: Immutable +): EndpointState['endpointDetails']['isHostInfoLoading'] => state.endpointDetails.isHostInfoLoading; -export const detailsError = ( +export const hostInfoError = ( state: Immutable -): EndpointState['endpointDetails']['hostDetails']['detailsError'] => - state.endpointDetails.hostDetails.detailsError; +): EndpointState['endpointDetails']['hostInfoError'] => state.endpointDetails.hostInfoError; export const policyItems = (state: Immutable) => state.policyItems; export const policyItemsLoading = (state: Immutable) => state.policyItemsLoading; export const selectedPolicyId = (state: Immutable) => state.selectedPolicyId; - export const endpointPackageInfo = (state: Immutable) => state.endpointPackageInfo; export const getIsEndpointPackageInfoUninitialized: (state: Immutable) => boolean = createSelector(endpointPackageInfo, (packageInfo) => isUninitialisedResourceState(packageInfo)); @@ -258,8 +255,8 @@ export const getIsOnEndpointDetailsActivityLog: (state: Immutable return searchParams.show === EndpointDetailsTabsTypes.activityLog; }); -export const getIsEndpointHostIsolated = createSelector(detailsData, (details) => { - return (details && isEndpointHostIsolated(details)) || false; +export const getIsEndpointHostIsolated = createSelector(fullDetailsHostInfo, (details) => { + return (details && isEndpointHostIsolated(details.metadata)) || false; }); export const getEndpointPendingActionsState = ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts index cdd5020226697b..c7de43f6bc3743 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts @@ -8,15 +8,14 @@ import type { DataViewBase } from '@kbn/es-query'; import type { GetInfoResponse } from '@kbn/fleet-plugin/common'; import type { + AppLocation, + EndpointPendingActions, HostInfo, - Immutable, - HostMetadata, HostPolicyResponse, - AppLocation, - PolicyData, HostStatus, + Immutable, + PolicyData, ResponseActionApiResponse, - EndpointPendingActions, } from '../../../../common/endpoint/types'; import type { ServerApiError } from '../../../common/types'; import type { AsyncResourceState } from '../../state'; @@ -39,14 +38,8 @@ export interface EndpointState { // Adding `hostInfo` to store full API response in order to support the // refactoring effort with AgentStatus component hostInfo?: HostInfo; - hostDetails: { - /** details data for a specific host */ - details?: Immutable; - /** details page is retrieving data */ - detailsLoading: boolean; - /** api error from retrieving host details */ - detailsError?: ServerApiError; - }; + hostInfoError?: ServerApiError; + isHostInfoLoading: boolean; }; /** Holds the Policy Response for the Host currently being displayed in the details */ policyResponse?: HostPolicyResponse; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.tsx index 69a4dd2054e6c9..7942b10059bcb7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.tsx @@ -9,12 +9,12 @@ import React, { useState, useCallback, useMemo } from 'react'; import { EuiContextMenuPanel, EuiButton, EuiPopover } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useEndpointActionItems, useEndpointSelector } from '../../hooks'; -import { detailsData } from '../../../store/selectors'; +import { fullDetailsHostInfo } from '../../../store/selectors'; import { ContextMenuItemNavByRouter } from '../../../../../components/context_menu_with_router_support/context_menu_item_nav_by_router'; export const ActionsMenu = React.memo<{}>(() => { - const endpointDetails = useEndpointSelector(detailsData); - const menuOptions = useEndpointActionItems(endpointDetails); + const endpointDetails = useEndpointSelector(fullDetailsHostInfo); + const menuOptions = useEndpointActionItems(endpointDetails?.metadata); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const closePopoverHandler = useCallback(() => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx index 8cc41f19e94a38..256b606ad51107 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx @@ -6,9 +6,9 @@ */ import React, { memo } from 'react'; -import { EuiFlyoutHeader, EuiSkeletonText, EuiToolTip, EuiTitle } from '@elastic/eui'; +import { EuiFlyoutHeader, EuiSkeletonText, EuiTitle, EuiToolTip } from '@elastic/eui'; import { useEndpointSelector } from '../../hooks'; -import { detailsLoading } from '../../../store/selectors'; +import { isHostInfoLoading } from '../../../store/selectors'; import { BackToEndpointDetailsFlyoutSubHeader } from './back_to_endpoint_details_flyout_subheader'; export const EndpointDetailsFlyoutHeader = memo( @@ -21,9 +21,9 @@ export const EndpointDetailsFlyoutHeader = memo( endpointId?: string; hasBorder?: boolean; hostname?: string; - children?: React.ReactNode | React.ReactNodeArray; + children?: React.ReactNode | React.ReactNode[]; }) => { - const hostDetailsLoading = useEndpointSelector(detailsLoading); + const hostDetailsLoading = useEndpointSelector(isHostInfoLoading); return ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx index b52aaa0da42235..a7f02fbb5da03b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx @@ -14,9 +14,8 @@ import type { HostMetadata } from '../../../../../../common/endpoint/types'; import { useToasts } from '../../../../../common/lib/kibana'; import { getEndpointDetailsPath } from '../../../../common/routing'; import { - detailsData, - detailsError, - hostStatusInfo, + fullDetailsHostInfo, + hostInfoError, policyVersionInfo, showView, uiQueryParams, @@ -26,8 +25,8 @@ import * as i18 from '../translations'; import { ActionsMenu } from './components/actions_menu'; import { EndpointDetailsFlyoutTabs, - EndpointDetailsTabsTypes, type EndpointDetailsTabs, + EndpointDetailsTabsTypes, } from './components/endpoint_details_tabs'; import { EndpointIsolationFlyoutPanel } from './components/endpoint_isolate_flyout_panel'; import { EndpointDetailsFlyoutHeader } from './components/flyout_header'; @@ -37,11 +36,10 @@ export const EndpointDetails = memo(() => { const toasts = useToasts(); const queryParams = useEndpointSelector(uiQueryParams); - const hostDetails = useEndpointSelector(detailsData); - const hostDetailsError = useEndpointSelector(detailsError); + const hostInfo = useEndpointSelector(fullDetailsHostInfo); + const hostDetailsError = useEndpointSelector(hostInfoError); const policyInfo = useEndpointSelector(policyVersionInfo); - const hostStatus = useEndpointSelector(hostStatusInfo); const show = useEndpointSelector(showView); const { canAccessEndpointActionsLogManagement } = useUserPrivileges().endpointPrivileges; @@ -68,14 +66,10 @@ export const EndpointDetails = memo(() => { selected_endpoint: id, }), content: - hostDetails === undefined ? ( + hostInfo === undefined ? ( ContentLoadingMarkup ) : ( - + ), }, ]; @@ -96,14 +90,7 @@ export const EndpointDetails = memo(() => { } return tabs; }, - [ - canAccessEndpointActionsLogManagement, - ContentLoadingMarkup, - hostDetails, - policyInfo, - hostStatus, - queryParams, - ] + [canAccessEndpointActionsLogManagement, ContentLoadingMarkup, hostInfo, policyInfo, queryParams] ); const showFlyoutFooter = @@ -127,11 +114,11 @@ export const EndpointDetails = memo(() => { {(show === 'policy_response' || show === 'isolate' || show === 'unisolate') && ( )} - {hostDetails === undefined ? ( + {hostInfo === undefined ? ( @@ -139,18 +126,18 @@ export const EndpointDetails = memo(() => { <> {(show === 'details' || show === 'activity_log') && ( )} - {show === 'policy_response' && } + {show === 'policy_response' && } {(show === 'isolate' || show === 'unisolate') && ( - + )} {showFlyoutFooter && ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx index b33f98078b9fbb..13878c9377eb49 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx @@ -8,21 +8,20 @@ import styled from 'styled-components'; import { EuiDescriptionList, - EuiText, EuiFlexGroup, EuiFlexItem, - EuiSpacer, - EuiLink, EuiHealth, + EuiLink, + EuiSpacer, + EuiText, } from '@elastic/eui'; import React, { memo, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EndpointAgentStatus } from '../../../../../common/components/endpoint/endpoint_agent_status'; import { isPolicyOutOfDate } from '../../utils'; -import type { HostInfo, HostMetadata, HostStatus } from '../../../../../../common/endpoint/types'; +import type { HostInfo } from '../../../../../../common/endpoint/types'; import { useEndpointSelector } from '../hooks'; import { - fullDetailsHostInfo, getEndpointPendingActionsCallback, nonExistingPolicies, policyResponseStatus, @@ -39,9 +38,11 @@ const EndpointDetailsContentStyled = styled.div` dl dt { max-width: 27%; } + dl dd { max-width: 73%; } + .policyLineText { padding-right: 5px; } @@ -55,34 +56,28 @@ const ColumnTitle = ({ children }: { children: React.ReactNode }) => { ); }; -export const EndpointDetailsContent = memo( - ({ - details, - policyInfo, - hostStatus, - }: { - details: HostMetadata; - policyInfo?: HostInfo['policy_info']; - hostStatus: HostStatus; - }) => { +interface EndpointDetailsContentProps { + hostInfo: HostInfo; + policyInfo?: HostInfo['policy_info']; +} + +export const EndpointDetailsContent = memo( + ({ hostInfo, policyInfo }) => { const queryParams = useEndpointSelector(uiQueryParams); const policyStatus = useEndpointSelector( policyResponseStatus ) as keyof typeof POLICY_STATUS_TO_BADGE_COLOR; const getHostPendingActions = useEndpointSelector(getEndpointPendingActionsCallback); const missingPolicies = useEndpointSelector(nonExistingPolicies); - const hostInfo = useEndpointSelector(fullDetailsHostInfo); const policyResponseRoutePath = useMemo(() => { - // eslint-disable-next-line @typescript-eslint/naming-convention - const { selected_endpoint, show, ...currentUrlParams } = queryParams; - const path = getEndpointDetailsPath({ + const { selected_endpoint: selectedEndpoint, show, ...currentUrlParams } = queryParams; + return getEndpointDetailsPath({ name: 'endpointPolicyResponse', ...currentUrlParams, - selected_endpoint: details.agent.id, + selected_endpoint: hostInfo.metadata.agent.id, }); - return path; - }, [details.agent.id, queryParams]); + }, [hostInfo.metadata.agent.id, queryParams]); const policyStatusClickHandler = useNavigateByRouterEventHandler(policyResponseRoutePath); @@ -97,7 +92,7 @@ export const EndpointDetailsContent = memo( /> ), - description: {details.host.os.full}, + description: {hostInfo.metadata.host.os.full}, }, { title: ( @@ -108,13 +103,11 @@ export const EndpointDetailsContent = memo( /> ), - description: hostInfo ? ( + description: ( - ) : ( - <> ), }, { @@ -128,7 +121,10 @@ export const EndpointDetailsContent = memo( ), description: ( - + ), }, @@ -144,14 +140,14 @@ export const EndpointDetailsContent = memo( description: ( - {details.Endpoint.policy.applied.name} + {hostInfo.metadata.Endpoint.policy.applied.name} - {details.Endpoint.policy.applied.endpoint_policy_version && ( + {hostInfo.metadata.Endpoint.policy.applied.endpoint_policy_version && ( )} - {isPolicyOutOfDate(details.Endpoint.policy.applied, policyInfo) && } + {isPolicyOutOfDate(hostInfo.metadata.Endpoint.policy.applied, policyInfo) && ( + + )} ), }, @@ -206,7 +204,7 @@ export const EndpointDetailsContent = memo( /> ), - description: {details.agent.version}, + description: {hostInfo.metadata.agent.version}, }, { title: ( @@ -219,7 +217,7 @@ export const EndpointDetailsContent = memo( ), description: ( - {details.host.ip.map((ip: string, index: number) => ( + {hostInfo.metadata.host.ip.map((ip: string, index: number) => ( {ip} @@ -229,9 +227,8 @@ export const EndpointDetailsContent = memo( }, ]; }, [ - details, - getHostPendingActions, hostInfo, + getHostPendingActions, missingPolicies, policyInfo, policyStatus, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 9b2e681e4f4beb..027f2cc20780dc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -48,8 +48,8 @@ import { import type { TransformStats } from '../types'; import { HOST_METADATA_LIST_ROUTE, - metadataTransformPrefix, METADATA_UNITED_TRANSFORM, + metadataTransformPrefix, } from '../../../../../common/endpoint/constants'; import { useUserPrivileges } from '../../../../common/components/user_privileges'; import { @@ -62,7 +62,7 @@ import { getEndpointPrivilegesInitialStateMock } from '../../../../common/compon const mockUserPrivileges = useUserPrivileges as jest.Mock; // not sure why this can't be imported from '../../../../common/mock/formatted_relative'; -// but sure enough it needs to be inline in this one file +// but sure enough, it needs to be inline in this one file jest.mock('@kbn/i18n-react', () => { const originalModule = jest.requireActual('@kbn/i18n-react'); const FormattedRelative = jest.fn().mockImplementation(() => '20 hours ago'); @@ -310,6 +310,7 @@ describe('when on the endpoint list page', () => { hostListData[index].metadata.Endpoint.policy.applied, setup.policy ), + last_checkin: hostListData[index].last_checkin, }; }); hostListData.forEach((item, index) => { @@ -485,17 +486,17 @@ describe('when on the endpoint list page', () => { }); describe('when there is a selected host in the url', () => { - let hostDetails: HostInfo; + let hostInfo: HostInfo; let renderAndWaitForData: () => Promise>; const mockEndpointListApi = (mockedPolicyResponse?: HostPolicyResponse) => { const { - // eslint-disable-next-line @typescript-eslint/naming-convention - host_status, + host_status: hostStatus, + last_checkin: lastCheckin, metadata: { agent, Endpoint, ...details }, } = mockEndpointDetailsApiResult(); - hostDetails = { - host_status, + hostInfo = { + host_status: hostStatus, metadata: { ...details, Endpoint: { @@ -510,13 +511,14 @@ describe('when on the endpoint list page', () => { id: '1', }, }, + last_checkin: lastCheckin, }; const policy = docGenerator.generatePolicyPackagePolicy(); - policy.id = hostDetails.metadata.Endpoint.policy.applied.id; + policy.id = hostInfo.metadata.Endpoint.policy.applied.id; setEndpointListApiMockImplementation(coreStart.http, { - endpointsResults: [hostDetails], + endpointsResults: [hostInfo], endpointPackagePolicies: [policy], policyResponse: mockedPolicyResponse, }); @@ -617,7 +619,7 @@ describe('when on the endpoint list page', () => { const policyDetailsLink = await renderResult.findByTestId('policyDetailsValue'); expect(policyDetailsLink).not.toBeNull(); expect(policyDetailsLink.getAttribute('href')).toEqual( - `${APP_PATH}${MANAGEMENT_PATH}/policy/${hostDetails.metadata.Endpoint.policy.applied.id}/settings` + `${APP_PATH}${MANAGEMENT_PATH}/policy/${hostInfo.metadata.Endpoint.policy.applied.id}/settings` ); }); @@ -626,7 +628,7 @@ describe('when on the endpoint list page', () => { const policyDetailsRevElement = await renderResult.findByTestId('policyDetailsRevNo'); expect(policyDetailsRevElement).not.toBeNull(); expect(policyDetailsRevElement.textContent).toEqual( - `rev. ${hostDetails.metadata.Endpoint.policy.applied.endpoint_policy_version}` + `rev. ${hostInfo.metadata.Endpoint.policy.applied.endpoint_policy_version}` ); }); @@ -639,7 +641,7 @@ describe('when on the endpoint list page', () => { }); const changedUrlAction = await userChangedUrlChecker; expect(changedUrlAction.payload.pathname).toEqual( - `${MANAGEMENT_PATH}/policy/${hostDetails.metadata.Endpoint.policy.applied.id}/settings` + `${MANAGEMENT_PATH}/policy/${hostInfo.metadata.Endpoint.policy.applied.id}/settings` ); }); @@ -1019,6 +1021,7 @@ describe('when on the endpoint list page', () => { version: '7.14.0', }, }, + last_checkin: hosts[0].last_checkin, }, { host_status: hosts[1].host_status, @@ -1044,6 +1047,7 @@ describe('when on the endpoint list page', () => { version: '8.4.0', }, }, + last_checkin: hosts[1].last_checkin, }, ]; @@ -1333,7 +1337,7 @@ describe('when on the endpoint list page', () => { beforeEach(async () => { const { data: hosts } = mockEndpointResultList({ total: 2 }); - // second host is isolated, for unisolate testing + // the second host is isolated, for unisolate testing const hostInfo: HostInfo[] = [ { host_status: hosts[0].host_status, @@ -1359,6 +1363,7 @@ describe('when on the endpoint list page', () => { version: '7.14.0', }, }, + last_checkin: hosts[0].last_checkin, }, { host_status: hosts[1].host_status, @@ -1384,6 +1389,7 @@ describe('when on the endpoint list page', () => { version: '8.4.0', }, }, + last_checkin: hosts[1].last_checkin, }, ]; setEndpointListApiMockImplementation(coreStart.http, { diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts index 27c758ca43a8b5..ebe8a34580f76e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts @@ -15,8 +15,8 @@ import { } from '../../routes/metadata/support/test_support'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { - getESQueryHostMetadataByFleetAgentIds, buildUnitedIndexQuery, + getESQueryHostMetadataByFleetAgentIds, } from '../../routes/metadata/query_builders'; import type { HostMetadata } from '../../../../common/endpoint/types'; import type { Agent, PackagePolicy } from '@kbn/fleet-plugin/common'; @@ -137,11 +137,14 @@ describe('EndpointMetadataService', () => { package_policies: packagePolicies, }), ]; + + const newDate = new Date(); const agentPolicyIds = agentPolicies.map((policy) => policy.id); - const endpointMetadataDoc = endpointDocGenerator.generateHostMetadata(); + const endpointMetadataDoc = endpointDocGenerator.generateHostMetadata(newDate.getTime()); const mockAgent = { policy_id: agentPolicies[0].id, policy_revision: agentPolicies[0].revision, + last_checkin: newDate.toISOString(), } as unknown as Agent; const mockDoc = unitedMetadataSearchResponseMock(endpointMetadataDoc, mockAgent); esClient.search.mockResponse(mockDoc); @@ -203,6 +206,7 @@ describe('EndpointMetadataService', () => { revision: packagePolicies[0].revision, }, }, + last_checkin: newDate.toISOString(), }, ], total: 1, diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts index 98f42c1a4d8ced..d6247ad1b572b7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts @@ -12,7 +12,7 @@ import type { SavedObjectsServiceStart, } from '@kbn/core/server'; -import type { SearchTotalHits, SearchResponse } from '@elastic/elasticsearch/lib/api/types'; +import type { SearchResponse, SearchTotalHits } from '@elastic/elasticsearch/lib/api/types'; import type { Agent, AgentPolicy, AgentStatus, PackagePolicy } from '@kbn/fleet-plugin/common'; import type { AgentPolicyServiceInterface, PackagePolicyClient } from '@kbn/fleet-plugin/server'; import { AgentNotFoundError } from '@kbn/fleet-plugin/server'; @@ -32,9 +32,9 @@ import { FleetEndpointPackagePolicyNotFoundError, } from './errors'; import { + buildUnitedIndexQuery, getESQueryHostMetadataByFleetAgentIds, getESQueryHostMetadataByID, - buildUnitedIndexQuery, getESQueryHostMetadataByIDs, } from '../../routes/metadata/query_builders'; import { @@ -176,7 +176,7 @@ export class EndpointMetadataService { } } - // If the agent is not longer active, then that means that the Agent/Endpoint have been un-enrolled from the host + // If the agent is no longer active, then that means that the Agent/Endpoint have been un-enrolled from the host if (fleetAgent && !fleetAgent.active) { throw new EndpointHostUnEnrolledError( `Endpoint with id ${endpointId} (Fleet agent id ${fleetAgentId}) is unenrolled` @@ -251,7 +251,7 @@ export class EndpointMetadataService { } } - // The fleetAgentPolicy might have the endpoint policy in the `package_policies`, lets check that first + // The fleetAgentPolicy might have the endpoint policy in the `package_policies`, let's check that first if ( !endpointPackagePolicy && fleetAgentPolicy && @@ -262,7 +262,7 @@ export class EndpointMetadataService { ); } - // if we still don't have an endpoint package policy, try retrieving it from fleet + // if we still don't have an endpoint package policy, try retrieving it from `fleet` if (!endpointPackagePolicy) { try { endpointPackagePolicy = await this.getFleetEndpointPackagePolicy( @@ -294,6 +294,8 @@ export class EndpointMetadataService { id: endpointPackagePolicy?.id ?? '', }, }, + last_checkin: + _fleetAgent?.last_checkin || new Date(endpointMetadata['@timestamp']).toISOString(), }; } @@ -363,6 +365,8 @@ export class EndpointMetadataService { * * @param esClient * @param queryOptions + * @param soClient + * @param fleetServices * * @throws */ From a6a8f5b9ab518e3bbd254fc24b547df162ffa194 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:04:17 +0300 Subject: [PATCH 13/98] [Cloud Security] convert status api router to be versioned (#159548) --- .../journeys/cloud_security_dashboard.ts | 1 + .../common/constants.ts | 2 + .../public/common/api/use_setup_status_api.ts | 4 +- .../get_csp_rule_template.ts | 11 +-- .../server/routes/status/status.ts | 79 +++++++++++-------- .../cloud_security_posture/tsconfig.json | 1 + .../status/status_index_timeout.ts | 4 + .../status/status_indexed.ts | 4 + .../status/status_indexing.ts | 4 + .../status_not_deployed_not_installed.ts | 4 + .../status/status_unprivileged.ts | 5 ++ .../status/status_waiting_for_results.ts | 4 + .../telemetry/telemetry.ts | 2 + .../page_objects/csp_dashboard_page.ts | 2 + .../page_objects/findings_page.ts | 2 + 15 files changed, 88 insertions(+), 41 deletions(-) diff --git a/x-pack/performance/journeys/cloud_security_dashboard.ts b/x-pack/performance/journeys/cloud_security_dashboard.ts index 39625126e70674..a7256f44717f26 100644 --- a/x-pack/performance/journeys/cloud_security_dashboard.ts +++ b/x-pack/performance/journeys/cloud_security_dashboard.ts @@ -14,6 +14,7 @@ export const journey = new Journey({ const response = await kibanaServer.request({ path: '/internal/cloud_security_posture/status?check=init', method: 'GET', + headers: { 'elastic-api-version': '1' }, }); expect(response.status).to.eql(200); expect(response.data).to.eql({ isPluginInitialized: true }); diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 8b6ed65bb18533..cc01567f553474 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -8,6 +8,8 @@ import { PostureTypes, VulnSeverity } from './types'; export const STATUS_ROUTE_PATH = '/internal/cloud_security_posture/status'; +export const STATUS_API_CURRENT_VERSION = '1'; + export const STATS_ROUTE_PATH = '/internal/cloud_security_posture/stats/{policy_template}'; export const VULNERABILITIES_DASHBOARD_ROUTE_PATH = diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts index 99e277b30bb544..afb7a89c69e6f1 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_setup_status_api.ts @@ -8,7 +8,7 @@ import { useQuery, type UseQueryOptions } from '@tanstack/react-query'; import { useKibana } from '../hooks/use_kibana'; import { type CspSetupStatus } from '../../../common/types'; -import { STATUS_ROUTE_PATH } from '../../../common/constants'; +import { STATUS_API_CURRENT_VERSION, STATUS_ROUTE_PATH } from '../../../common/constants'; const getCspSetupStatusQueryKey = 'csp_status_key'; @@ -18,7 +18,7 @@ export const useCspSetupStatusApi = ( const { http } = useKibana().services; return useQuery( [getCspSetupStatusQueryKey], - () => http.get(STATUS_ROUTE_PATH), + () => http.get(STATUS_ROUTE_PATH, { version: STATUS_API_CURRENT_VERSION }), options ); }; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts index 6d41f87eaff7f9..63e2bdb6ee1020 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts @@ -7,7 +7,6 @@ import { NewPackagePolicy } from '@kbn/fleet-plugin/common'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import pMap from 'p-map'; import { transformError } from '@kbn/securitysolution-es-utils'; import { GetCspRuleTemplateRequest, GetCspRuleTemplateResponse } from '../../../common/types'; import { CspRuleTemplate } from '../../../common/schemas'; @@ -61,13 +60,9 @@ const findCspRuleTemplateHandler = async ( filter: getBenchmarkTypeFilter(benchmarkId), }); - const cspRulesTemplates = await pMap( - cspRulesTemplatesSo.saved_objects, - async (cspRuleTemplate) => { - return { ...cspRuleTemplate.attributes }; - }, - { concurrency: 50 } - ); + const cspRulesTemplates = cspRulesTemplatesSo.saved_objects.map((cspRuleTemplate) => { + return { ...cspRuleTemplate.attributes }; + }); return { items: cspRulesTemplates, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts b/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts index 60f634b4c32b89..86b0d0a66802be 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/status/status.ts @@ -16,6 +16,7 @@ import type { import moment from 'moment'; import { Installation, PackagePolicy } from '@kbn/fleet-plugin/common'; import { schema } from '@kbn/config-schema'; +import { VersionedRoute } from '@kbn/core-http-server/src/versioning/types'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, STATUS_ROUTE_PATH, @@ -29,7 +30,12 @@ import { LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, VULN_MGMT_POLICY_TEMPLATE, } from '../../../common/constants'; -import type { CspApiRequestHandlerContext, CspRouter, StatusResponseInfo } from '../../types'; +import type { + CspApiRequestHandlerContext, + CspRequestHandlerContext, + CspRouter, + StatusResponseInfo, +} from '../../types'; import type { CspSetupStatus, CspStatusCode, @@ -328,44 +334,55 @@ export const statusQueryParamsSchema = schema.object({ check: schema.oneOf([schema.literal('all'), schema.literal('init')], { defaultValue: 'all' }), }); -export const defineGetCspStatusRoute = (router: CspRouter): void => - router.get( - { +export const defineGetCspStatusRoute = ( + router: CspRouter +): VersionedRoute<'get', CspRequestHandlerContext> => + router.versioned + .get({ + access: 'internal', path: STATUS_ROUTE_PATH, - validate: { query: statusQueryParamsSchema }, options: { tags: ['access:cloud-security-posture-read'], }, - }, - async (context, request, response) => { - const cspContext = await context.csp; - try { - if (request.query.check === 'init') { + }) + .addVersion( + { + version: '1', + validate: { + request: { + query: statusQueryParamsSchema, + }, + }, + }, + async (context, request, response) => { + const cspContext = await context.csp; + try { + if (request.query.check === 'init') { + return response.ok({ + body: { + isPluginInitialized: cspContext.isPluginInitialized(), + }, + }); + } + const status: CspSetupStatus = await getCspStatus({ + ...cspContext, + esClient: cspContext.esClient.asCurrentUser, + }); return response.ok({ - body: { - isPluginInitialized: cspContext.isPluginInitialized(), - }, + body: status, + }); + } catch (err) { + cspContext.logger.error(`Error getting csp status`); + cspContext.logger.error(err); + + const error = transformError(err); + return response.customError({ + body: { message: error.message }, + statusCode: error.statusCode, }); } - const status = await getCspStatus({ - ...cspContext, - esClient: cspContext.esClient.asCurrentUser, - }); - return response.ok({ - body: status, - }); - } catch (err) { - cspContext.logger.error(`Error getting csp status`); - cspContext.logger.error(err); - - const error = transformError(err); - return response.customError({ - body: { message: error.message }, - statusCode: error.statusCode, - }); } - } - ); + ); const getStatusResponse = (statusResponseInfo: StatusResponseInfo) => { const { diff --git a/x-pack/plugins/cloud_security_posture/tsconfig.json b/x-pack/plugins/cloud_security_posture/tsconfig.json index 6dd9ba33a3165b..ae8f7d610002bd 100755 --- a/x-pack/plugins/cloud_security_posture/tsconfig.json +++ b/x-pack/plugins/cloud_security_posture/tsconfig.json @@ -48,6 +48,7 @@ "@kbn/shared-ux-router", "@kbn/core-saved-objects-server", "@kbn/share-plugin", + "@kbn/core-http-server", ], "exclude": [ "target/**/*", diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts index eae7154763bc0f..fe52d8d3a07736 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { FINDINGS_INDEX_DEFAULT_NS, LATEST_FINDINGS_INDEX_DEFAULT_NS, @@ -105,6 +106,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -131,6 +133,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -157,6 +160,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts index c8cd9927c72d42..aa9d6d3289e95d 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts @@ -5,6 +5,7 @@ * 2.0. */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; import { FINDINGS_INDEX_DEFAULT_NS, @@ -71,6 +72,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -89,6 +91,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -107,6 +110,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts index d7c11c446544a2..ef16eb94d8a333 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts @@ -5,6 +5,7 @@ * 2.0. */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; import { FINDINGS_INDEX_DEFAULT_NS, @@ -70,6 +71,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -88,6 +90,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -106,6 +109,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts index 93b8c81ad44de2..d7d77c93ecad4a 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { createPackagePolicy } from '../helper'; @@ -50,6 +51,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -72,6 +74,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); @@ -94,6 +97,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts index 3127519b2bc4cc..2432165566de81 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts @@ -5,6 +5,7 @@ * 2.0. */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; import { BENCHMARK_SCORE_INDEX_DEFAULT_NS, @@ -79,6 +80,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertestWithoutAuth .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); @@ -127,6 +129,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertestWithoutAuth .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); @@ -157,6 +160,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertestWithoutAuth .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); @@ -190,6 +194,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertestWithoutAuth .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts index 81538511243293..53692014f767a1 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts @@ -5,6 +5,7 @@ * 2.0. */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { CspSetupStatus } from '@kbn/cloud-security-posture-plugin/common/types'; import { setupFleetAndAgents } from '../../../../fleet_api_integration/apis/agents/services'; import { generateAgent } from '../../../../fleet_api_integration/helpers'; @@ -87,6 +88,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); expect(res.kspm.status).to.be('waiting_for_results'); @@ -112,6 +114,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); expect(res.cspm.status).to.be('waiting_for_results'); @@ -137,6 +140,7 @@ export default function (providerContext: FtrProviderContext) { const { body: res }: { body: CspSetupStatus } = await supertest .get(`/internal/cloud_security_posture/status`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); expect(res.vuln_mgmt.status).to.be('waiting_for_results'); diff --git a/x-pack/test/cloud_security_posture_api/telemetry/telemetry.ts b/x-pack/test/cloud_security_posture_api/telemetry/telemetry.ts index ede036d93239f9..797a88881a87bd 100644 --- a/x-pack/test/cloud_security_posture_api/telemetry/telemetry.ts +++ b/x-pack/test/cloud_security_posture_api/telemetry/telemetry.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { data, MockTelemetryFindings } from './data'; import type { FtrProviderContext } from '../ftr_provider_context'; @@ -26,6 +27,7 @@ export default function ({ getService }: FtrProviderContext) { log.debug('Check CSP plugin is initialized'); const response = await supertest .get('/internal/cloud_security_posture/status?check=init') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .expect(200); expect(response.body).to.eql({ isPluginInitialized: true }); log.debug('CSP plugin is initialized'); diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/csp_dashboard_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/csp_dashboard_page.ts index 635cf88965e5f6..c7265ece4744a8 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/csp_dashboard_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/csp_dashboard_page.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { FtrProviderContext } from '../ftr_provider_context'; // Defined in CSP plugin @@ -27,6 +28,7 @@ export function CspDashboardPageProvider({ getService, getPageObjects }: FtrProv log.debug('Check CSP plugin is initialized'); const response = await supertest .get('/internal/cloud_security_posture/status?check=init') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .expect(200); expect(response.body).to.eql({ isPluginInitialized: true }); log.debug('CSP plugin is initialized'); diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts index 6bb3a78e44cb41..59ec355ca770f3 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { FtrProviderContext } from '../ftr_provider_context'; // Defined in CSP plugin @@ -28,6 +29,7 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider log.debug('Check CSP plugin is initialized'); const response = await supertest .get('/internal/cloud_security_posture/status?check=init') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .expect(200); expect(response.body).to.eql({ isPluginInitialized: true }); log.debug('CSP plugin is initialized'); From 61b792f50f1841340c0f81cca1fa6a8672d9e80a Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Mon, 3 Jul 2023 11:12:03 +0100 Subject: [PATCH 14/98] [SecuritySolution] Get Started Page UI update (#160850) ## Summary 1. Add content max-width: 1150px 2. Change wording `runtime` to `realtime` 3. Enable product toggles based on `product type` if no data from local storage. (Product type `security` displayed as `Analytics` in toggle but it's product id changed to `security` to aligned with product types' configs) **Follow up:** Wait for UX to confirm if `product tiers (essential / complete)` affects the cards. Screenshot 2023-06-29 at 22 06 39 ### 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 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../serverless_security/common/config.ts | 13 +- .../common/pli/pli_features.test.ts | 11 +- .../get_started/get_started.test.tsx | 19 +- .../components/get_started/get_started.tsx | 49 +++- .../components/get_started/helpers.test.ts | 36 +-- .../public/components/get_started/helpers.ts | 19 +- .../public/components/get_started/index.tsx | 6 +- .../public/components/get_started/lazy.tsx | 5 +- .../get_started/product_switch.test.tsx | 8 +- .../components/get_started/product_switch.tsx | 17 +- .../components/get_started/reducer.test.ts | 22 +- .../public/components/get_started/reducer.tsx | 6 +- .../components/get_started/sections.tsx | 15 +- .../get_started/toggle_panel.test.tsx | 75 ++++-- .../components/get_started/toggle_panel.tsx | 96 ++----- .../components/get_started/translations.ts | 4 +- .../public/components/get_started/types.ts | 17 +- .../get_started/use_setup_cards.test.tsx | 4 +- .../get_started/use_setup_cards.tsx | 6 +- .../get_started/use_toggle_panel.test.tsx | 239 ++++++++++++++++++ .../get_started/use_toggle_panel.tsx | 77 ++++++ .../upselling/register_upsellings.test.tsx | 8 +- .../public/lib/get_started/storage.test.ts | 18 +- .../public/lib/get_started/storage.ts | 11 +- .../serverless_security/public/plugin.ts | 4 +- 25 files changed, 568 insertions(+), 217 deletions(-) create mode 100644 x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx create mode 100644 x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx diff --git a/x-pack/plugins/serverless_security/common/config.ts b/x-pack/plugins/serverless_security/common/config.ts index 05c1cb4f0b01b7..63b173ff3930e0 100644 --- a/x-pack/plugins/serverless_security/common/config.ts +++ b/x-pack/plugins/serverless_security/common/config.ts @@ -7,11 +7,18 @@ import { schema, TypeOf } from '@kbn/config-schema'; +export enum ProductLine { + security = 'security', + cloud = 'cloud', + endpoint = 'endpoint', +} + export const productLine = schema.oneOf([ - schema.literal('security'), - schema.literal('endpoint'), - schema.literal('cloud'), + schema.literal(ProductLine.security), + schema.literal(ProductLine.endpoint), + schema.literal(ProductLine.cloud), ]); + export type SecurityProductLine = TypeOf; export const productTier = schema.oneOf([schema.literal('essentials'), schema.literal('complete')]); diff --git a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts b/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts index 0d46bcc421ec00..c00f8d7fdd9ec1 100644 --- a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts +++ b/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts @@ -6,6 +6,7 @@ */ import { getProductAppFeatures } from './pli_features'; import * as pliConfig from './pli_config'; +import { ProductLine } from '../config'; describe('getProductAppFeatures', () => { it('should return the essentials PLIs features', () => { @@ -18,7 +19,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: 'security', product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: 'essentials' }, ]); expect(appFeatureKeys).toEqual(['foo']); @@ -34,7 +35,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: 'security', product_tier: 'complete' }, + { product_line: ProductLine.security, product_tier: 'complete' }, ]); expect(appFeatureKeys).toEqual(['foo', 'baz']); @@ -58,9 +59,9 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: 'security', product_tier: 'essentials' }, - { product_line: 'endpoint', product_tier: 'complete' }, - { product_line: 'cloud', product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: 'essentials' }, + { product_line: ProductLine.endpoint, product_tier: 'complete' }, + { product_line: ProductLine.cloud, product_tier: 'essentials' }, ]); expect(appFeatureKeys).toEqual(['foo', 'bar', 'repeated', 'qux', 'quux', 'corge', 'garply']); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx index a81d2525f6a842..ddf0b179852230 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { GetStartedComponent } from './get_started'; +import { SecurityProductTypes } from '../../../common/config'; jest.mock('./toggle_panel'); jest.mock('./welcome_panel'); @@ -20,9 +21,15 @@ jest.mock('@elastic/eui', () => { }; }); +const productTypes = [ + { product_line: 'security', product_tier: 'essentials' }, + { product_line: 'endpoint', product_tier: 'complete' }, + { product_line: 'cloud', product_tier: 'complete' }, +] as SecurityProductTypes; + describe('GetStartedComponent', () => { it('should render page title, subtitle, and description', () => { - const { getByText } = render(); + const { getByText } = render(); const pageTitle = getByText('Welcome'); const subtitle = getByText('Let’s get started'); @@ -35,8 +42,16 @@ describe('GetStartedComponent', () => { expect(description).toBeInTheDocument(); }); + it('should render Product Switch', () => { + const { getByTestId } = render(); + + const productSwitch = getByTestId('product-switch'); + + expect(productSwitch).toBeInTheDocument(); + }); + it('should render WelcomePanel and TogglePanel', () => { - const { getByTestId } = render(); + const { getByTestId } = render(); const welcomePanel = getByTestId('welcome-panel'); const togglePanel = getByTestId('toggle-panel'); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx b/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx index 1532528b6ff530..b29ba3b30d6a4f 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiTitle, useEuiTheme } from '@elastic/eui'; +import { EuiTitle, useEuiTheme, useEuiShadow } from '@elastic/eui'; import React from 'react'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { css } from '@emotion/react'; @@ -17,10 +17,22 @@ import { GET_STARTED_PAGE_SUBTITLE, GET_STARTED_PAGE_TITLE, } from './translations'; +import { SecurityProductTypes } from '../../../common/config'; +import { ProductSwitch } from './product_switch'; +import { useTogglePanel } from './use_toggle_panel'; -export const GetStartedComponent: React.FC = () => { - const { euiTheme } = useEuiTheme(); +const CONTENT_WIDTH = 1150; +export const GetStartedComponent: React.FC<{ productTypes: SecurityProductTypes }> = ({ + productTypes, +}) => { + const { euiTheme } = useEuiTheme(); + const shadow = useEuiShadow('s'); + const { + onProductSwitchChanged, + onStepClicked, + state: { activeProducts, activeCards, finishedSteps }, + } = useTogglePanel({ productTypes }); return ( { `} > { > + + + - + ); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts b/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts index 0a4e32834bc947..f5511d4eaa85d8 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts +++ b/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts @@ -13,18 +13,18 @@ import { updateCard, } from './helpers'; import { - ActiveCard, + ActiveCards, Card, CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, - ProductId, Section, SectionId, StepId, } from './types'; import * as sectionsConfigs from './sections'; +import { ProductLine } from '../../../common/config'; const mockSections = jest.spyOn(sectionsConfigs, 'getSections'); describe('getCardTimeInMinutes', () => { it('should calculate the total time in minutes for a card correctly', () => { @@ -74,8 +74,8 @@ describe('getCardStepsLeft', () => { describe('isCardActive', () => { it('should return true if the card is active based on the active products', () => { - const card = { productTypeRequired: [ProductId.analytics, ProductId.cloud] } as Card; - const activeProducts = new Set([ProductId.analytics]); + const card = { productLineRequired: [ProductLine.security, ProductLine.cloud] } as Card; + const activeProducts = new Set([ProductLine.security]); const isActive = isCardActive(card, activeProducts); @@ -84,7 +84,7 @@ describe('isCardActive', () => { it('should return true if the card has no product type requirement', () => { const card = {} as Card; - const activeProducts = new Set([ProductId.analytics]); + const activeProducts = new Set([ProductLine.security]); const isActive = isCardActive(card, activeProducts); @@ -92,8 +92,8 @@ describe('isCardActive', () => { }); it('should return false if the card is not active based on the active products', () => { - const card = { productTypeRequired: [ProductId.analytics, ProductId.cloud] } as Card; - const activeProducts = new Set([ProductId.endpoint]); + const card = { productLineRequired: [ProductLine.security, ProductLine.cloud] } as Card; + const activeProducts = new Set([ProductLine.endpoint]); const isActive = isCardActive(card, activeProducts); @@ -140,7 +140,7 @@ describe('setupCards', () => { }; it('should set up active cards based on active products', () => { const finishedSteps = {} as unknown as Record>; - const activeProducts = new Set([ProductId.cloud]); + const activeProducts = new Set([ProductLine.cloud]); const activeCards = setupCards(finishedSteps, activeProducts); @@ -148,8 +148,8 @@ describe('setupCards', () => { ...analyticProductActiveCards, [SectionId.getSetUp]: { ...analyticProductActiveCards[SectionId.getSetUp], - [GetSetUpCardId.protectYourEnvironmentInRuntime]: { - id: GetSetUpCardId.protectYourEnvironmentInRuntime, + [GetSetUpCardId.protectYourEnvironmentInRealtime]: { + id: GetSetUpCardId.protectYourEnvironmentInRealtime, timeInMins: 0, stepsLeft: 0, }, @@ -159,7 +159,7 @@ describe('setupCards', () => { it('should skip inactive cards based on finished steps and active products', () => { const finishedSteps = {} as Record>; - const activeProducts = new Set([ProductId.analytics]); + const activeProducts = new Set([ProductLine.security]); const activeCards = setupCards(finishedSteps, activeProducts); @@ -171,7 +171,7 @@ describe('setupCards', () => { [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), } as unknown as Record>; - const activeProducts: Set = new Set(); + const activeProducts: Set = new Set(); const activeCards = setupCards(finishedSteps, activeProducts); @@ -188,7 +188,7 @@ describe('setupCards', () => { const finishedSteps = { [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), } as unknown as Record>; - const activeProducts = new Set([ProductId.analytics]); + const activeProducts = new Set([ProductLine.security]); const activeCards = setupCards(finishedSteps, activeProducts); @@ -202,7 +202,7 @@ describe('updateCard', () => { const finishedSteps = { [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), } as unknown as Record>; - const activeProducts = new Set([ProductId.analytics, ProductId.cloud]); + const activeProducts = new Set([ProductLine.security, ProductLine.cloud]); const activeCards = { [SectionId.getSetUp]: { @@ -221,8 +221,8 @@ describe('updateCard', () => { timeInMins: 0, stepsLeft: 0, }, - [GetSetUpCardId.protectYourEnvironmentInRuntime]: { - id: GetSetUpCardId.protectYourEnvironmentInRuntime, + [GetSetUpCardId.protectYourEnvironmentInRealtime]: { + id: GetSetUpCardId.protectYourEnvironmentInRealtime, timeInMins: 0, stepsLeft: 0, }, @@ -244,7 +244,7 @@ describe('updateCard', () => { timeInMins: 0, }, }, - } as Record>; + } as ActiveCards; it('should update the active card based on finished steps and active products', () => { const sectionId = SectionId.getSetUp; @@ -273,7 +273,7 @@ describe('updateCard', () => { it('should return null if the card is inactive based on active products', () => { const sectionId = SectionId.getSetUp; - const cardId = GetSetUpCardId.protectYourEnvironmentInRuntime; + const cardId = GetSetUpCardId.protectYourEnvironmentInRealtime; const updatedCards = updateCard({ finishedSteps, diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts b/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts index 1f4380e5afae67..0042550a34c4bf 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts +++ b/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts @@ -5,8 +5,9 @@ * 2.0. */ +import { ProductLine } from '../../../common/config'; import { getSections } from './sections'; -import { ActiveCard, Card, CardId, ProductId, SectionId, StepId } from './types'; +import { ActiveCard, ActiveCards, Card, CardId, SectionId, StepId } from './types'; export const getCardTimeInMinutes = (card: Card, stepsDone: Set) => card.steps?.reduce( @@ -18,13 +19,13 @@ export const getCardTimeInMinutes = (card: Card, stepsDone: Set) => export const getCardStepsLeft = (card: Card, stepsDone: Set) => (card.steps?.length ?? 0) - (stepsDone.size ?? 0); -export const isCardActive = (card: Card, activeProducts: Set) => - !card.productTypeRequired || - card.productTypeRequired?.some((condition) => activeProducts.has(condition)); +export const isCardActive = (card: Card, activeProducts: Set) => + !card.productLineRequired || + card.productLineRequired?.some((condition) => activeProducts.has(condition)); export const setupCards = ( finishedSteps: Record>, - activeProducts: Set + activeProducts: Set ) => activeProducts.size > 0 ? getSections().reduce((acc, section) => { @@ -46,7 +47,7 @@ export const setupCards = ( acc[section.id] = cardsInSections; } return acc; - }, {} as Record>) + }, {} as ActiveCards) : null; export const updateCard = ({ @@ -57,11 +58,11 @@ export const updateCard = ({ cardId, }: { finishedSteps: Record>; - activeProducts: Set; - activeCards: Record> | null; + activeProducts: Set; + activeCards: ActiveCards | null; sectionId: SectionId; cardId: CardId; -}): Record> | null => { +}): ActiveCards | null => { const sections = getSections(); const section = sections.find(({ id }) => id === sectionId); const cards = section?.cards; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx b/x-pack/plugins/serverless_security/public/components/get_started/index.tsx index 88227330bfde94..48326496d44221 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/index.tsx @@ -13,14 +13,16 @@ import type { GetStartedComponent } from './types'; import { GetStarted } from './lazy'; import { KibanaServicesProvider } from '../../services'; import { ServerlessSecurityPluginStartDependencies } from '../../types'; +import { SecurityProductTypes } from '../../../common/config'; export const getSecurityGetStartedComponent = ( core: CoreStart, - pluginsStart: ServerlessSecurityPluginStartDependencies + pluginsStart: ServerlessSecurityPluginStartDependencies, + productTypes: SecurityProductTypes ): GetStartedComponent => { return () => ( - + ); }; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx b/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx index f968ad5d2ab22d..3130bbe272f527 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx @@ -6,13 +6,14 @@ */ import React, { lazy, Suspense } from 'react'; import { EuiLoadingLogo } from '@elastic/eui'; +import { SecurityProductTypes } from '../../../common/config'; const GetStartedLazy = lazy(() => import('./get_started')); const centerLogoStyle = { display: 'flex', margin: 'auto' }; -export const GetStarted = () => ( +export const GetStarted = ({ productTypes }: { productTypes: SecurityProductTypes }) => ( }> - + ); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx index 49c0087f598309..29c01ddce5376a 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { ProductSwitch } from './product_switch'; import { EuiThemeComputed } from '@elastic/eui'; -import { ProductId } from './types'; +import { ProductLine } from '../../../common/config'; describe('ProductSwitch', () => { const onProductSwitchChangedMock = jest.fn(); @@ -49,12 +49,12 @@ describe('ProductSwitch', () => { fireEvent.click(analyticsSwitch); expect(onProductSwitchChangedMock).toHaveBeenCalledWith( - expect.objectContaining({ id: 'analytics' }) + expect.objectContaining({ id: 'security' }) ); }); it('should have checked switches for activeProducts', () => { - const activeProducts = new Set([ProductId.analytics, ProductId.endpoint]); + const activeProducts = new Set([ProductLine.security, ProductLine.endpoint]); const { getByTestId } = render( { /> ); - const analyticsSwitch = getByTestId('analytics'); + const analyticsSwitch = getByTestId('security'); const cloudSwitch = getByTestId('cloud'); const endpointSwitch = getByTestId('endpoint'); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx b/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx index 910618c1a3f4cf..822e5f3e69ca09 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx @@ -8,30 +8,30 @@ import { EuiPanel, EuiSwitch, EuiText, EuiThemeComputed, EuiTitle } from '@elastic/eui'; import { css } from '@emotion/react'; import React, { useMemo } from 'react'; +import { ProductLine } from '../../../common/config'; import * as i18n from './translations'; -import { ProductId, Switch } from './types'; +import { Switch } from './types'; const switches: Switch[] = [ { - id: ProductId.analytics, + id: ProductLine.security, label: i18n.ANALYTICS_SWITCH_LABEL, }, { - id: ProductId.cloud, + id: ProductLine.cloud, label: i18n.CLOUD_SWITCH_LABEL, }, { - id: ProductId.endpoint, + id: ProductLine.endpoint, label: i18n.ENDPOINT_SWITCH_LABEL, }, ]; const ProductSwitchComponent: React.FC<{ onProductSwitchChanged: (item: Switch) => void; - activeProducts: Set; - shadow?: string; + activeProducts: Set; euiTheme: EuiThemeComputed; -}> = ({ onProductSwitchChanged, activeProducts, euiTheme, shadow = '' }) => { +}> = ({ onProductSwitchChanged, activeProducts, euiTheme }) => { const switchNodes = useMemo( () => switches.map((item) => ( @@ -58,8 +58,7 @@ const ProductSwitchComponent: React.FC<{ paddingSize="none" hasShadow={false} css={css` - padding: ${euiTheme.base * 1.25}px ${euiTheme.base * 2.25}px; - ${shadow}; + padding: ${euiTheme.base * 1.25}px 0; `} borderRadius="none" > diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts b/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts index 970b7ac6dbef09..259923080bfaa9 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts +++ b/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { ProductLine } from '../../../common/config'; import { reducer, getFinishedStepsInitialStates, @@ -12,12 +13,11 @@ import { getActiveCardsInitialStates, } from './reducer'; import { - ActiveCard, + ActiveCards, CardId, GetSetUpCardId, GetStartedPageActions, IntroductionSteps, - ProductId, SectionId, StepId, ToggleProductAction, @@ -28,25 +28,25 @@ import { describe('reducer', () => { it('should toggle section correctly', () => { const initialState = { - activeProducts: new Set([ProductId.analytics]), + activeProducts: new Set([ProductLine.security]), finishedSteps: {} as Record>, - activeCards: {} as Record> | null, + activeCards: {} as ActiveCards | null, }; const action: ToggleProductAction = { type: GetStartedPageActions.ToggleProduct, - payload: { section: ProductId.analytics }, + payload: { section: ProductLine.security }, }; const nextState = reducer(initialState, action); - expect(nextState.activeProducts.has(ProductId.analytics)).toBe(false); + expect(nextState.activeProducts.has(ProductLine.security)).toBe(false); expect(nextState.activeCards).toBeNull(); }); it('should add a finished step correctly', () => { const initialState = { - activeProducts: new Set([ProductId.analytics]), + activeProducts: new Set([ProductLine.security]), finishedSteps: {} as Record>, activeCards: { getSetUp: { @@ -56,7 +56,7 @@ describe('reducer', () => { timeInMins: 3, }, }, - } as unknown as Record> | null, + } as unknown as ActiveCards | null, }; const action: AddFinishedStepAction = { @@ -103,17 +103,17 @@ describe('getFinishedStepsInitialStates', () => { describe('getActiveSectionsInitialStates', () => { it('should return the initial states of active sections correctly', () => { - const activeProducts = [ProductId.analytics]; + const activeProducts = [ProductLine.security]; const initialStates = getActiveSectionsInitialStates({ activeProducts }); - expect(initialStates.has(ProductId.analytics)).toBe(true); + expect(initialStates.has(ProductLine.security)).toBe(true); }); }); describe('getActiveCardsInitialStates', () => { it('should return the initial states of active cards correctly', () => { - const activeProducts = new Set([ProductId.analytics]); + const activeProducts = new Set([ProductLine.security]); const finishedSteps = { [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), } as unknown as Record>; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx b/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx index 2164bbee177bd9..403bfb85e0a932 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx @@ -5,11 +5,11 @@ * 2.0. */ +import { ProductLine } from '../../../common/config'; import { setupCards, updateCard } from './helpers'; import { CardId, GetStartedPageActions, - ProductId, StepId, ToggleProductAction, TogglePanelReducer, @@ -80,13 +80,13 @@ export const getFinishedStepsInitialStates = ({ export const getActiveSectionsInitialStates = ({ activeProducts, }: { - activeProducts: ProductId[]; + activeProducts: ProductLine[]; }) => new Set(activeProducts); export const getActiveCardsInitialStates = ({ activeProducts, finishedSteps, }: { - activeProducts: Set; + activeProducts: Set; finishedSteps: Record>; }) => setupCards(finishedSteps, activeProducts); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx b/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx index 4a03eaff2dd765..33dbb6f62aa405 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { Section, - ProductId, SectionId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, @@ -17,12 +16,7 @@ import { import * as i18n from './translations'; import respond from './images/respond.svg'; import protect from './images/protect.svg'; - -export const ActiveConditions = { - analyticsToggled: [ProductId.analytics], - cloudToggled: [ProductId.cloud], - endpointToggled: [ProductId.endpoint], -}; +import { ProductLine } from '../../../common/config'; export const introductionSteps = [ { @@ -85,11 +79,8 @@ export const sections: Section[] = [ { icon: { type: protect, size: 'xl' }, title: i18n.PROTECT_YOUR_ENVIRONMENT_TITLE, - id: GetSetUpCardId.protectYourEnvironmentInRuntime, - productTypeRequired: [ - ...ActiveConditions.cloudToggled, - ...ActiveConditions.endpointToggled, - ], + id: GetSetUpCardId.protectYourEnvironmentInRealtime, + productLineRequired: [ProductLine.cloud, ProductLine.endpoint], }, ], }, diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx index a8350826ed6dab..53f51cdc09a8bf 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx @@ -5,10 +5,11 @@ * 2.0. */ import React from 'react'; -import { render, fireEvent } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { TogglePanel } from './toggle_panel'; -import { getStartedStorage as mockGetStartedStorage } from '../../lib/get_started/storage'; import { useSetUpCardSections } from './use_setup_cards'; +import { ActiveCards, CardId, GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; +import { ProductLine } from '../../../common/config'; jest.mock('@elastic/eui', () => ({ ...jest.requireActual('@elastic/eui'), @@ -30,23 +31,57 @@ jest.mock('./use_setup_cards', () => ({ useSetUpCardSections: jest.fn(), })); +const finishedSteps = { + [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), +} as unknown as Record>; +const activeProducts = new Set([ProductLine.security, ProductLine.cloud]); + +const activeCards = { + [SectionId.getSetUp]: { + [GetSetUpCardId.introduction]: { + id: GetSetUpCardId.introduction, + timeInMins: 3, + stepsLeft: 1, + }, + [GetSetUpCardId.bringInYourData]: { + id: GetSetUpCardId.bringInYourData, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.activateAndCreateRules]: { + id: GetSetUpCardId.activateAndCreateRules, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.protectYourEnvironmentInRealtime]: { + id: GetSetUpCardId.protectYourEnvironmentInRealtime, + timeInMins: 0, + stepsLeft: 0, + }, + }, +} as ActiveCards; + describe('TogglePanel', () => { - const mockUseSetUpCardSections = { setUpSections: jest.fn(() => null) }; + const mockUseSetUpCardSections = { + setUpSections: jest.fn(() =>
), + }; + const onStepClicked = jest.fn(); beforeEach(() => { jest.clearAllMocks(); (useSetUpCardSections as jest.Mock).mockReturnValue(mockUseSetUpCardSections); }); - it('should render the product switch ', () => { - const { getByTestId } = render(); - - expect(getByTestId('product-switch')).toBeInTheDocument(); - }); - it('should render empty prompt', () => { - const { getByText } = render(); + const { getByText } = render( + + ); expect(getByText(`Hmm, there doesn't seem to be anything there`)).toBeInTheDocument(); expect( @@ -54,16 +89,16 @@ describe('TogglePanel', () => { ).toBeInTheDocument(); }); - it('should toggle active sections when a product switch is changed', () => { - const { getByText } = render(); - - const analyticsSwitch = getByText('Analytics'); - const cloudSwitch = getByText('Cloud'); - - fireEvent.click(analyticsSwitch); - expect(mockGetStartedStorage.toggleActiveProductsInStorage).toHaveBeenCalledWith('analytics'); + it('should render sections', () => { + const { getByTestId } = render( + + ); - fireEvent.click(cloudSwitch); - expect(mockGetStartedStorage.toggleActiveProductsInStorage).toHaveBeenCalledWith('cloud'); + expect(getByTestId(`mock-sections`)).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx index 3ce851fc8a2322..af365b83bd80c3 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx @@ -5,98 +5,46 @@ * 2.0. */ -import React, { useCallback, useMemo, useReducer } from 'react'; +import React from 'react'; import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, useEuiShadow, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; -import { Switch, GetStartedPageActions, StepId, CardId, SectionId } from './types'; import * as i18n from './translations'; -import { ProductSwitch } from './product_switch'; import { useSetUpCardSections } from './use_setup_cards'; -import { getStartedStorage } from '../../lib/get_started/storage'; -import { - getActiveCardsInitialStates, - getActiveSectionsInitialStates, - getFinishedStepsInitialStates, - reducer, -} from './reducer'; -const TogglePanelComponent = () => { +import { ActiveCards, CardId, IntroductionSteps, SectionId } from './types'; +import { ProductLine } from '../../../common/config'; + +const TogglePanelComponent: React.FC<{ + finishedSteps: Record>; + activeCards: ActiveCards | null; + activeProducts: Set; + onStepClicked: ({ + stepId, + cardId, + sectionId, + }: { + stepId: IntroductionSteps; + cardId: CardId; + sectionId: SectionId; + }) => void; +}> = ({ finishedSteps, activeCards, activeProducts, onStepClicked }) => { const { euiTheme } = useEuiTheme(); const shadow = useEuiShadow('s'); - const { - getAllFinishedStepsFromStorage, - getActiveProductsFromStorage, - toggleActiveProductsInStorage, - addFinishedStepToStorage, - } = getStartedStorage; - const finishedStepsInitialStates = useMemo( - () => getFinishedStepsInitialStates({ finishedSteps: getAllFinishedStepsFromStorage() }), - [getAllFinishedStepsFromStorage] - ); - - const activeSectionsInitialStates = useMemo( - () => getActiveSectionsInitialStates({ activeProducts: getActiveProductsFromStorage() }), - [getActiveProductsFromStorage] - ); - - const activeCardsInitialStates = useMemo( - () => - getActiveCardsInitialStates({ - activeProducts: activeSectionsInitialStates, - finishedSteps: finishedStepsInitialStates, - }), - [activeSectionsInitialStates, finishedStepsInitialStates] - ); - const [state, dispatch] = useReducer(reducer, { - activeProducts: activeSectionsInitialStates, - finishedSteps: finishedStepsInitialStates, - activeCards: activeCardsInitialStates, - }); const { setUpSections } = useSetUpCardSections({ euiTheme, shadow }); - const onStepClicked = useCallback( - ({ stepId, cardId, sectionId }: { stepId: StepId; cardId: CardId; sectionId: SectionId }) => { - dispatch({ - type: GetStartedPageActions.AddFinishedStep, - payload: { stepId, cardId, sectionId }, - }); - addFinishedStepToStorage(cardId, stepId); - }, - [addFinishedStepToStorage] - ); const sectionNodes = setUpSections({ onStepClicked, - finishedSteps: state.finishedSteps, - activeCards: state.activeCards, + finishedSteps, + activeCards, }); - const onProductSwitchChanged = useCallback( - (section: Switch) => { - dispatch({ type: GetStartedPageActions.ToggleProduct, payload: { section: section.id } }); - toggleActiveProductsInStorage(section.id); - }, - [toggleActiveProductsInStorage] - ); return ( - - - - - {state.activeProducts.size > 0 ? ( + + {activeProducts.size > 0 ? ( sectionNodes ) : ( >; export enum SectionId { getSetUp = 'getSetUp', @@ -71,7 +68,7 @@ export enum GetSetUpCardId { activateAndCreateRules = 'activateAndCreateRules', bringInYourData = 'bringInYourData', introduction = 'introduction', - protectYourEnvironmentInRuntime = 'protectYourEnvironmentInRuntime', + protectYourEnvironmentInRealtime = 'protectYourEnvironmentInRealtime', } export enum IntroductionSteps { @@ -90,14 +87,14 @@ export interface ActiveCard { stepsLeft: number; } export interface TogglePanelReducer { - activeProducts: Set; + activeProducts: Set; finishedSteps: Record>; activeCards: Record> | null; } export interface ToggleProductAction { type: GetStartedPageActions.ToggleProduct; - payload: { section: ProductId }; + payload: { section: ProductLine }; } export interface AddFinishedStepAction { @@ -106,7 +103,7 @@ export interface AddFinishedStepAction { } export interface Switch { - id: ProductId; + id: ProductLine; label: string; } diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx index dcf8c6a3cfb386..6e726fd9a002f9 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx @@ -9,7 +9,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { EuiThemeComputed } from '@elastic/eui'; import { useSetUpCardSections } from './use_setup_cards'; import { - ActiveCard, + ActiveCards, CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, @@ -44,7 +44,7 @@ describe('useSetUpCardSections', () => { id: GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow, }, }, - } as Record>; + } as ActiveCards; const sections = result.current.setUpSections({ activeCards, diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx b/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx index 082aadeae88eea..bd762042196eec 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx @@ -9,7 +9,7 @@ import { EuiSpacer, EuiThemeComputed } from '@elastic/eui'; import React, { useCallback } from 'react'; import { css } from '@emotion/react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; -import { ActiveCard, CardId, SectionId, StepId } from './types'; +import { ActiveCards, CardId, SectionId, StepId } from './types'; import { CardItem } from './card_item'; import { getSections } from './sections'; @@ -30,7 +30,7 @@ export const useSetUpCardSections = ({ }: { onStepClicked: (params: { stepId: StepId; cardId: CardId; sectionId: SectionId }) => void; finishedSteps: Record>; - activeCards: Record> | null; + activeCards: ActiveCards | null; sectionId: SectionId; }) => { const section = activeCards?.[sectionId]; @@ -63,7 +63,7 @@ export const useSetUpCardSections = ({ }: { onStepClicked: (params: { stepId: StepId; cardId: CardId; sectionId: SectionId }) => void; finishedSteps: Record>; - activeCards: Record> | null; + activeCards: ActiveCards | null; }) => getSections().reduce((acc, currentSection) => { const cardNodes = setUpCards({ diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx new file mode 100644 index 00000000000000..62010093959356 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx @@ -0,0 +1,239 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { renderHook, act } from '@testing-library/react-hooks'; +import { useTogglePanel } from './use_toggle_panel'; +import { getStartedStorage } from '../../lib/get_started/storage'; +import { ProductLine, SecurityProductTypes } from '../../../common/config'; +import { + GetMoreFromElasticSecurityCardId, + GetSetUpCardId, + IntroductionSteps, + SectionId, +} from './types'; + +jest.mock('../../lib/get_started/storage'); + +describe('useTogglePanel', () => { + const productTypes = [ + { product_line: 'security', product_tier: 'essentials' }, + { product_line: 'endpoint', product_tier: 'complete' }, + ] as SecurityProductTypes; + + beforeEach(() => { + jest.clearAllMocks(); + + (getStartedStorage.getAllFinishedStepsFromStorage as jest.Mock).mockReturnValue({ + [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), + }); + (getStartedStorage.getActiveProductsFromStorage as jest.Mock).mockReturnValue([ + ProductLine.security, + ProductLine.cloud, + ProductLine.endpoint, + ]); + }); + + test('should initialize state with correct initial values - when no active products from local storage', () => { + (getStartedStorage.getAllFinishedStepsFromStorage as jest.Mock).mockReturnValue({}); + (getStartedStorage.getActiveProductsFromStorage as jest.Mock).mockReturnValue([]); + + const { result } = renderHook(() => useTogglePanel({ productTypes })); + + const { state } = result.current; + + expect(state.activeProducts).toEqual(new Set([ProductLine.security, ProductLine.endpoint])); + expect(state.finishedSteps).toEqual({}); + + expect(state.activeCards).toEqual( + expect.objectContaining({ + [SectionId.getSetUp]: { + [GetSetUpCardId.introduction]: { + id: GetSetUpCardId.introduction, + timeInMins: 3, + stepsLeft: 1, + }, + [GetSetUpCardId.activateAndCreateRules]: { + id: GetSetUpCardId.activateAndCreateRules, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.bringInYourData]: { + id: GetSetUpCardId.bringInYourData, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.protectYourEnvironmentInRealtime]: { + id: GetSetUpCardId.protectYourEnvironmentInRealtime, + timeInMins: 0, + stepsLeft: 0, + }, + }, + [SectionId.getMoreFromElasticSecurity]: { + [GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow]: { + id: GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace]: { + id: GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.respondToThreats]: { + id: GetMoreFromElasticSecurityCardId.respondToThreats, + timeInMins: 0, + stepsLeft: 0, + }, + }, + }) + ); + }); + + test('should initialize state with correct initial values - when all products active', () => { + const { result } = renderHook(() => useTogglePanel({ productTypes })); + + const { state } = result.current; + + expect(state.activeProducts).toEqual( + new Set([ProductLine.security, ProductLine.cloud, ProductLine.endpoint]) + ); + expect(state.finishedSteps).toEqual({ + [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), + }); + + expect(state.activeCards).toEqual( + expect.objectContaining({ + [SectionId.getSetUp]: { + [GetSetUpCardId.introduction]: { + id: GetSetUpCardId.introduction, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.activateAndCreateRules]: { + id: GetSetUpCardId.activateAndCreateRules, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.bringInYourData]: { + id: GetSetUpCardId.bringInYourData, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.protectYourEnvironmentInRealtime]: { + id: GetSetUpCardId.protectYourEnvironmentInRealtime, + timeInMins: 0, + stepsLeft: 0, + }, + }, + [SectionId.getMoreFromElasticSecurity]: { + [GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow]: { + id: GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace]: { + id: GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.respondToThreats]: { + id: GetMoreFromElasticSecurityCardId.respondToThreats, + timeInMins: 0, + stepsLeft: 0, + }, + }, + }) + ); + }); + + test('should initialize state with correct initial values - when only security product active', () => { + (getStartedStorage.getActiveProductsFromStorage as jest.Mock).mockReturnValue([ + ProductLine.security, + ]); + const { result } = renderHook(() => useTogglePanel({ productTypes })); + + const { state } = result.current; + + expect(state.activeProducts).toEqual(new Set([ProductLine.security])); + expect(state.finishedSteps).toEqual({ + [GetSetUpCardId.introduction]: new Set([IntroductionSteps.watchOverviewVideo]), + }); + + expect(state.activeCards).toEqual( + expect.objectContaining({ + [SectionId.getSetUp]: { + [GetSetUpCardId.introduction]: { + id: GetSetUpCardId.introduction, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.activateAndCreateRules]: { + id: GetSetUpCardId.activateAndCreateRules, + timeInMins: 0, + stepsLeft: 0, + }, + [GetSetUpCardId.bringInYourData]: { + id: GetSetUpCardId.bringInYourData, + timeInMins: 0, + stepsLeft: 0, + }, + }, + [SectionId.getMoreFromElasticSecurity]: { + [GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow]: { + id: GetMoreFromElasticSecurityCardId.masterTheInvestigationsWorkflow, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace]: { + id: GetMoreFromElasticSecurityCardId.optimizeYourWorkSpace, + timeInMins: 0, + stepsLeft: 0, + }, + [GetMoreFromElasticSecurityCardId.respondToThreats]: { + id: GetMoreFromElasticSecurityCardId.respondToThreats, + timeInMins: 0, + stepsLeft: 0, + }, + }, + }) + ); + }); + + test('should call addFinishedStepToStorage', () => { + const { result } = renderHook(() => useTogglePanel({ productTypes })); + + const { onStepClicked } = result.current; + + act(() => { + onStepClicked({ + stepId: IntroductionSteps.watchOverviewVideo, + cardId: GetSetUpCardId.introduction, + sectionId: SectionId.getSetUp, + }); + }); + + expect(getStartedStorage.addFinishedStepToStorage).toHaveBeenCalledTimes(1); + expect(getStartedStorage.addFinishedStepToStorage).toHaveBeenCalledWith( + GetSetUpCardId.introduction, + IntroductionSteps.watchOverviewVideo + ); + }); + + test('should call toggleActiveProductsInStorage', () => { + const { result } = renderHook(() => useTogglePanel({ productTypes })); + + const { onProductSwitchChanged } = result.current; + + act(() => { + onProductSwitchChanged({ id: ProductLine.security, label: 'Analytics' }); + }); + + expect(getStartedStorage.toggleActiveProductsInStorage).toHaveBeenCalledTimes(1); + expect(getStartedStorage.toggleActiveProductsInStorage).toHaveBeenCalledWith( + ProductLine.security + ); + }); +}); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx b/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx new file mode 100644 index 00000000000000..f449478572c45d --- /dev/null +++ b/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useMemo, useReducer } from 'react'; +import { ProductLine, SecurityProductTypes } from '../../../common/config'; +import { getStartedStorage } from '../../lib/get_started/storage'; +import { + getActiveCardsInitialStates, + getActiveSectionsInitialStates, + getFinishedStepsInitialStates, + reducer, +} from './reducer'; +import { CardId, GetStartedPageActions, SectionId, StepId, Switch } from './types'; + +export const useTogglePanel = ({ productTypes }: { productTypes: SecurityProductTypes }) => { + const { + getAllFinishedStepsFromStorage, + getActiveProductsFromStorage, + toggleActiveProductsInStorage, + addFinishedStepToStorage, + } = getStartedStorage; + + const finishedStepsInitialStates = useMemo( + () => getFinishedStepsInitialStates({ finishedSteps: getAllFinishedStepsFromStorage() }), + [getAllFinishedStepsFromStorage] + ); + + const activeSectionsInitialStates = useMemo(() => { + const activeProductsFromStorage = getActiveSectionsInitialStates({ + activeProducts: getActiveProductsFromStorage(), + }); + return activeProductsFromStorage.size > 0 + ? activeProductsFromStorage + : new Set(productTypes.map(({ product_line: productLine }) => ProductLine[productLine])) ?? + new Set([ProductLine.security, ProductLine.endpoint, ProductLine.cloud]); + }, [getActiveProductsFromStorage, productTypes]); + + const activeCardsInitialStates = useMemo( + () => + getActiveCardsInitialStates({ + activeProducts: activeSectionsInitialStates, + finishedSteps: finishedStepsInitialStates, + }), + [activeSectionsInitialStates, finishedStepsInitialStates] + ); + + const [state, dispatch] = useReducer(reducer, { + activeProducts: activeSectionsInitialStates, + finishedSteps: finishedStepsInitialStates, + activeCards: activeCardsInitialStates, + }); + + const onStepClicked = useCallback( + ({ stepId, cardId, sectionId }: { stepId: StepId; cardId: CardId; sectionId: SectionId }) => { + dispatch({ + type: GetStartedPageActions.AddFinishedStep, + payload: { stepId, cardId, sectionId }, + }); + addFinishedStepToStorage(cardId, stepId); + }, + [addFinishedStepToStorage] + ); + + const onProductSwitchChanged = useCallback( + (section: Switch) => { + dispatch({ type: GetStartedPageActions.ToggleProduct, payload: { section: section.id } }); + toggleActiveProductsInStorage(section.id); + }, + [toggleActiveProductsInStorage] + ); + + return { state, onStepClicked, onProductSwitchChanged }; +}; diff --git a/x-pack/plugins/serverless_security/public/components/upselling/register_upsellings.test.tsx b/x-pack/plugins/serverless_security/public/components/upselling/register_upsellings.test.tsx index b2a1390ee098f1..304ee02de256cc 100644 --- a/x-pack/plugins/serverless_security/public/components/upselling/register_upsellings.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/upselling/register_upsellings.test.tsx @@ -8,7 +8,7 @@ import { UpsellingService } from '@kbn/security-solution-plugin/public'; import { ALL_APP_FEATURE_KEYS } from '@kbn/security-solution-plugin/common'; import { registerUpsellings, upsellingPages, upsellingSections } from './register_upsellings'; -import type { SecurityProductTypes } from '../../../common/config'; +import { ProductLine, SecurityProductTypes } from '../../../common/config'; const mockGetProductAppFeatures = jest.fn(); jest.mock('../../../common/pli/pli_features', () => ({ @@ -16,9 +16,9 @@ jest.mock('../../../common/pli/pli_features', () => ({ })); const allProductTypes: SecurityProductTypes = [ - { product_line: 'security', product_tier: 'complete' }, - { product_line: 'endpoint', product_tier: 'complete' }, - { product_line: 'cloud', product_tier: 'complete' }, + { product_line: ProductLine.security, product_tier: 'complete' }, + { product_line: ProductLine.endpoint, product_tier: 'complete' }, + { product_line: ProductLine.cloud, product_tier: 'complete' }, ]; describe('registerUpsellings', () => { diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts b/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts index 158c271470768a..e55c4ef28948b3 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts +++ b/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts @@ -6,14 +6,10 @@ */ import { getStartedStorage } from './storage'; -import { - GetSetUpCardId, - IntroductionSteps, - ProductId, - StepId, -} from '../../components/get_started/types'; +import { GetSetUpCardId, IntroductionSteps, StepId } from '../../components/get_started/types'; import { storage } from '../storage'; import { MockStorage } from '../__mocks__/storage'; +import { ProductLine } from '../../../common/config'; jest.mock('../storage'); @@ -33,13 +29,13 @@ describe('useStorage', () => { }); it('should toggle active products in storage', () => { - expect(getStartedStorage.toggleActiveProductsInStorage(ProductId.analytics)).toEqual([ - ProductId.analytics, + expect(getStartedStorage.toggleActiveProductsInStorage(ProductLine.security)).toEqual([ + ProductLine.security, ]); - expect(mockStorage.set).toHaveBeenCalledWith('ACTIVE_PRODUCTS', [ProductId.analytics]); + expect(mockStorage.set).toHaveBeenCalledWith('ACTIVE_PRODUCTS', [ProductLine.security]); - mockStorage.set('ACTIVE_PRODUCTS', [ProductId.analytics]); - expect(getStartedStorage.toggleActiveProductsInStorage(ProductId.analytics)).toEqual([]); + mockStorage.set('ACTIVE_PRODUCTS', [ProductLine.security]); + expect(getStartedStorage.toggleActiveProductsInStorage(ProductLine.security)).toEqual([]); expect(mockStorage.set).toHaveBeenCalledWith('ACTIVE_PRODUCTS', []); }); diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts b/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts index 691cbb5f102f0a..1d9c52813c8325 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts +++ b/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { CardId, ProductId, StepId } from '../../components/get_started/types'; +import { ProductLine } from '../../../common/config'; +import { CardId, StepId } from '../../components/get_started/types'; import { storage } from '../storage'; export const ACTIVE_PRODUCTS_STORAGE_KEY = 'ACTIVE_PRODUCTS'; @@ -13,12 +14,12 @@ export const FINISHED_STEPS_STORAGE_KEY = 'FINISHED_STEPS'; export const getStartedStorage = { getActiveProductsFromStorage: () => { - const activeProducts: ProductId[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY); + const activeProducts: ProductLine[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY); return activeProducts ?? new Array(); }, - toggleActiveProductsInStorage: (productId: ProductId) => { - const activeProducts: ProductId[] = - storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? new Array(); + toggleActiveProductsInStorage: (productId: ProductLine) => { + const activeProducts: ProductLine[] = + storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? new Array(); const index = activeProducts.indexOf(productId); if (index < 0) { activeProducts.push(productId); diff --git a/x-pack/plugins/serverless_security/public/plugin.ts b/x-pack/plugins/serverless_security/public/plugin.ts index f0729330de4afe..b93be1b16dcd49 100644 --- a/x-pack/plugins/serverless_security/public/plugin.ts +++ b/x-pack/plugins/serverless_security/public/plugin.ts @@ -48,7 +48,9 @@ export class ServerlessSecurityPlugin const { securitySolution, serverless } = startDeps; securitySolution.setIsSidebarEnabled(false); - securitySolution.setGetStartedPage(getSecurityGetStartedComponent(core, startDeps)); + securitySolution.setGetStartedPage( + getSecurityGetStartedComponent(core, startDeps, this.config.productTypes) + ); serverless.setProjectHome('/app/security'); serverless.setSideNavComponent(getSecuritySideNavComponent(core, startDeps)); From 09df093735a17ba636db38f051ce0b2e96cdf7d8 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Mon, 3 Jul 2023 12:13:56 +0200 Subject: [PATCH 15/98] [ftr/test_serverless] Remove common tests from serverless pipeline (#161065) This PR removes the common tests from the serverless buildkite pipeline. --- .buildkite/pipelines/serverless.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.buildkite/pipelines/serverless.yml b/.buildkite/pipelines/serverless.yml index ec09f77e751ec9..f4d7d0d49469b9 100644 --- a/.buildkite/pipelines/serverless.yml +++ b/.buildkite/pipelines/serverless.yml @@ -21,19 +21,6 @@ steps: - exit_status: '-1' limit: 3 - - command: SERVERLESS_ENVIRONMENT=common .buildkite/scripts/steps/functional/serverless_ftr.sh - label: 'Serverless Common Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 40 - retry: - automatic: - - exit_status: '-1' - limit: 3 - - exit_status: '*' - limit: 1 - - command: SERVERLESS_ENVIRONMENT=observability .buildkite/scripts/steps/functional/serverless_ftr.sh label: 'Serverless Observability Tests' agents: From 646d2e897e92471ea29448ca6a792181ed699e99 Mon Sep 17 00:00:00 2001 From: Gerard Soldevila Date: Mon, 3 Jul 2023 12:38:13 +0200 Subject: [PATCH 16/98] Increase timeout for costly ".kibana split" integration test (#160631) Tackles https://github.com/elastic/kibana/issues/157510 Nothing's wrong with the test, it's only that it's a bit costly, as it migrates a 100k SO archive. This PR simply increases the timeout for the conflicting test. --- .../migrations/group3/dot_kibana_split.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/dot_kibana_split.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/dot_kibana_split.test.ts index 258a33fe591d6a..30888521d651ef 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/dot_kibana_split.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/dot_kibana_split.test.ts @@ -412,9 +412,8 @@ describe('split .kibana index into multiple system indices', () => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/157510 - // This test takes too long. Can be manually executed to verify the correct behavior. - describe.skip('when multiple Kibana migrators run in parallel', () => { + describe('when multiple Kibana migrators run in parallel', () => { + jest.setTimeout(1200000); it('correctly migrates 7.7.2_xpack_100k_obj.zip archive', async () => { esServer = await startElasticsearch({ dataArchive: Path.join(__dirname, '..', 'archives', '7.7.2_xpack_100k_obj.zip'), @@ -491,7 +490,7 @@ describe('split .kibana index into multiple system indices', () => { task: 5, }, }); - }, 1200000); + }); afterEach(async () => { await esServer?.stop(); From b3ce69692916b307a9514eb36cf12455b97ec0ab Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Mon, 3 Jul 2023 06:30:57 -0500 Subject: [PATCH 17/98] [main] Sync bundled packages with Package Storage (#161009) Automated by https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/5138/ Co-authored-by: apmmachine --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index 208d8f079abc8a..e35f69b4dbc174 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -58,6 +58,6 @@ }, { "name": "security_detection_engine", - "version": "8.8.6" + "version": "8.9.1" } ] \ No newline at end of file From 831e858f50d8e12ed3663496b7e71814394b4438 Mon Sep 17 00:00:00 2001 From: Katerina Patticha Date: Mon, 3 Jul 2023 13:39:48 +0200 Subject: [PATCH 18/98] [Serverless] Update observability side navigation (#160866) Update once again the side navigation tree to match the latest mocks - https://www.figma.com/file/S4fn8L4j8fG1H6331Lw3kb/IA%2FNavigation?type=design&node-id=1265-151762&mode=design ### Before ![image](https://github.com/elastic/kibana/assets/3369346/65e1a394-e3ad-43da-a193-c2b2861bbbb1) ### After https://github.com/elastic/kibana/assets/3369346/ba570fba-798e-4273-95e7-e0e5a1ec9a88 ### Notes for reviewers - ML deep links will be visible after the https://github.com/elastic/kibana/pull/159433 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/deeplinks/management/deep_links.ts | 6 +- .../components/side_navigation/index.tsx | 106 +++++++++++++----- 2 files changed, 84 insertions(+), 28 deletions(-) diff --git a/packages/deeplinks/management/deep_links.ts b/packages/deeplinks/management/deep_links.ts index 1fa3d0f7d30bdb..0e9b16dd7dc8fd 100644 --- a/packages/deeplinks/management/deep_links.ts +++ b/packages/deeplinks/management/deep_links.ts @@ -54,4 +54,8 @@ export type ManagementDeepLinkId = MonitoringAppId | `${ManagementAppId}:${Manag // Combined export type AppId = MonitoringAppId | IntegrationsAppId | ManagementAppId; export type LinkId = ManagementId; -export type DeepLinkId = MonitoringDeepLinkId | IntegrationsDeepLinkId | ManagementDeepLinkId; +export type DeepLinkId = + | AppId + | MonitoringDeepLinkId + | IntegrationsDeepLinkId + | ManagementDeepLinkId; diff --git a/x-pack/plugins/serverless_observability/public/components/side_navigation/index.tsx b/x-pack/plugins/serverless_observability/public/components/side_navigation/index.tsx index 23987f7d86e95c..70ba2b98d5707f 100644 --- a/x-pack/plugins/serverless_observability/public/components/side_navigation/index.tsx +++ b/x-pack/plugins/serverless_observability/public/components/side_navigation/index.tsx @@ -11,7 +11,6 @@ import { DefaultNavigation, NavigationKibanaProvider, NavigationTreeDefinition, - getPresets, } from '@kbn/shared-ux-chrome-navigation'; import React from 'react'; import { i18n } from '@kbn/i18n'; @@ -28,7 +27,7 @@ const navigationTree: NavigationTreeDefinition = { breadcrumbStatus: 'hidden', children: [ { - id: 'discover-dashboard-viz', + id: 'discover-dashboard-alerts-slos', children: [ { link: 'discover', @@ -39,44 +38,75 @@ const navigationTree: NavigationTreeDefinition = { }), link: 'dashboards', }, - { - title: i18n.translate('xpack.serverlessObservability.nav.visualizations', { - defaultMessage: 'Visualizations', - }), - link: 'visualize', - }, - ], - }, - { - id: 'alerts-cases-slos', - children: [ { link: 'observability-overview:alerts', }, { - link: 'observability-overview:cases', + link: 'observability-overview:slos', }, { - link: 'observability-overview:slos', + id: 'aiops', + title: 'AIOps', + children: [ + { + title: i18n.translate('xpack.serverlessObservability.nav.ml.jobs', { + defaultMessage: 'Anomaly detection', + }), + link: 'ml:anomalyDetection', + }, + { + title: i18n.translate('xpack.serverlessObservability.ml.spike.analysis', { + defaultMessage: 'Spike analysis', + }), + link: 'ml:explainLogRateSpikes', + icon: 'beaker', + }, + { + link: 'ml:changePointDetections', + icon: 'beaker', + }, + { + title: i18n.translate('xpack.serverlessObservability.nav.ml.job.notifications', { + defaultMessage: 'Job notifications', + }), + link: 'ml:notifications', + }, + ], }, ], }, + { - id: 'apm', - title: 'APM', + id: 'applications', children: [ - { link: 'apm:services' }, { - link: 'apm:traces', + id: 'apm', + title: 'Applications', + children: [ + { + link: 'apm:services', + }, + { + link: 'apm:traces', + }, + { + link: 'apm:dependencies', + }, + ], }, + ], + }, + { + id: 'cases-vis', + children: [ { - title: i18n.translate('xpack.serverlessObservability.nav.logs', { - defaultMessage: 'Logs', - }), - link: 'logs:stream', + link: 'observability-overview:cases', }, { - link: 'apm:dependencies', + title: i18n.translate('xpack.serverlessObservability.nav.visualizations', { + defaultMessage: 'Visualizations', + }), + link: 'visualize', }, ], }, @@ -85,9 +115,8 @@ const navigationTree: NavigationTreeDefinition = { children: [ { title: i18n.translate('xpack.serverlessObservability.nav.getStarted', { - defaultMessage: 'Get started', + defaultMessage: 'Add data', }), - icon: 'launch', link: 'observabilityOnboarding', }, ], @@ -98,7 +127,30 @@ const navigationTree: NavigationTreeDefinition = { footer: [ { type: 'navGroup', - ...getPresets('management'), + id: 'projest_settings_project_nav', + title: 'Project settings', + icon: 'gear', + defaultIsCollapsed: true, + breadcrumbStatus: 'hidden', + children: [ + { + id: 'settings', + children: [ + { + link: 'management', + title: i18n.translate('xpack.serverlessObservability.nav.mngt', { + defaultMessage: 'Management', + }), + }, + { + link: 'integrations', + }, + { + link: 'fleet', + }, + ], + }, + ], }, ], }; From 933a3666d056e16dbd0aca4044ac904b7723a24f Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 3 Jul 2023 13:45:31 +0200 Subject: [PATCH 19/98] [Synthetics] Fix test now monitor in non default space (#160976) --- .../state/manual_test_runs/actions.ts | 6 +- .../state/manual_test_runs/index.ts | 22 ++-- .../apps/synthetics/state/utils/actions.ts | 6 +- .../routes/monitor_cruds/add_monitor.ts | 10 +- .../routes/monitor_cruds/delete_monitor.ts | 15 ++- .../synthetics_service/test_now_monitor.ts | 5 +- .../api_integration/apis/synthetics/index.ts | 1 + .../synthetics_monitor_test_service.ts | 33 ++++++ .../apis/synthetics/test_now_monitor.ts | 112 ++++++++++++++++++ 9 files changed, 188 insertions(+), 22 deletions(-) create mode 100644 x-pack/test/api_integration/apis/synthetics/test_now_monitor.ts diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/actions.ts index b1eb68738bc503..65cf3ab97d0705 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/actions.ts @@ -13,8 +13,12 @@ import { createAsyncAction } from '../utils/actions'; export const toggleTestNowFlyoutAction = createAction('TOGGLE TEST NOW FLYOUT ACTION'); export const hideTestNowFlyoutAction = createAction('HIDE ALL TEST NOW FLYOUT ACTION'); +export interface TestNowPayload { + configId: string; + name: string; +} export const manualTestMonitorAction = createAsyncAction< - { configId: string; name: string }, + TestNowPayload, TestNowResponse | undefined >('TEST_NOW_MONITOR_ACTION'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/index.ts index 73f6ec9f76a22d..53a99a651ee930 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/index.ts @@ -10,12 +10,14 @@ import { createReducer, PayloadAction } from '@reduxjs/toolkit'; import { WritableDraft } from 'immer/dist/types/types-external'; import { IHttpFetchError } from '@kbn/core-http-browser'; +import { ActionPayload } from '../utils/actions'; import { TestNowResponse } from '../../../../../common/types'; import { clearTestNowMonitorAction, hideTestNowFlyoutAction, manualTestMonitorAction, manualTestRunUpdateAction, + TestNowPayload, toggleTestNowFlyoutAction, } from './actions'; import { @@ -57,10 +59,7 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => { builder .addCase( String(manualTestMonitorAction.get), - ( - state: WritableDraft, - action: PayloadAction<{ configId: string; name: string }> - ) => { + (state: WritableDraft, action: PayloadAction) => { state = Object.values(state).reduce((acc, curr) => { acc[curr.configId] = { ...curr, @@ -98,9 +97,12 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => { ) .addCase( String(manualTestMonitorAction.fail), - (state: WritableDraft, action: PayloadAction) => { + ( + state: WritableDraft, + action: ActionPayload + ) => { const fetchError = action.payload as unknown as IHttpFetchError; - if (fetchError?.request.url) { + if (fetchError?.request?.url) { const { name, message } = fetchError; const [, errorMonitor] = @@ -117,10 +119,10 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => { }; } } - - if (action.payload.configId) { - state[action.payload.configId] = { - ...state[action.payload.configId], + const configId = action.payload.configId ?? action.payload.getPayload?.configId; + if (configId) { + state[configId] = { + ...state[configId], status: TestRunStatus.COMPLETED, errors: action.payload.errors, fetchError: undefined, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/utils/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/utils/actions.ts index 2a8d13a0f60257..789728faf70d93 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/utils/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/utils/actions.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createAction } from '@reduxjs/toolkit'; +import { createAction, PayloadAction } from '@reduxjs/toolkit'; import type { IHttpSerializedFetchError } from './http_error'; export function createAsyncAction< @@ -31,3 +31,7 @@ function prepareForTimestamp(payload: Payload) { }, }; } + +export interface ActionPayload extends PayloadAction

{ + payload: P & { getPayload?: G }; +} diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts index 8ff63923aba162..f675f10d6be926 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts @@ -316,9 +316,13 @@ const setupGettingStarted = (configId: string, routeContext: RouteContext) => { if (gettingStarted) { // ignore await, since we don't want to block the response - triggerTestNow(configId, routeContext).then(() => { - server.logger.debug(`Successfully triggered test for monitor: ${configId}`); - }); + triggerTestNow(configId, routeContext) + .then(() => { + server.logger.debug(`Successfully triggered test for monitor: ${configId}`); + }) + .catch((e) => { + server.logger.error(`Error triggering test for monitor: ${configId}: ${e}`); + }); } } catch (e) { server.logger.info(`Error triggering test for getting started monitor: ${configId}`); diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts index 032a48695ec976..91a7a03429030b 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor.ts @@ -6,7 +6,6 @@ */ import { schema } from '@kbn/config-schema'; import { SavedObjectsClientContract, SavedObjectsErrorHelpers } from '@kbn/core/server'; -import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsServerSetup } from '../../types'; import { RouteContext, SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsMonitorType } from '../../../common/types/saved_objects'; @@ -69,19 +68,19 @@ export const deleteMonitor = async ({ routeContext: RouteContext; monitorId: string; }) => { - const { savedObjectsClient, server, syntheticsMonitorClient, request } = routeContext; + const { spaceId, savedObjectsClient, server, syntheticsMonitorClient, request } = routeContext; const { logger, telemetry, stackVersion } = server; const { monitor, monitorWithSecret } = await getMonitorToDelete( monitorId, savedObjectsClient, - server + server, + spaceId ); let deletePromise; try { - const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; deletePromise = savedObjectsClient.delete(syntheticsMonitorType, monitorId); const deleteSyncPromise = syntheticsMonitorClient.deleteMonitors( @@ -140,7 +139,8 @@ export const deleteMonitor = async ({ const getMonitorToDelete = async ( monitorId: string, soClient: SavedObjectsClientContract, - server: SyntheticsServerSetup + server: SyntheticsServerSetup, + spaceId: string ) => { const encryptedSOClient = server.encryptedSavedObjects.getClient(); @@ -148,7 +148,10 @@ const getMonitorToDelete = async ( const monitor = await encryptedSOClient.getDecryptedAsInternalUser( syntheticsMonitorType, - monitorId + monitorId, + { + namespace: spaceId, + } ); return { monitor: normalizeSecrets(monitor), monitorWithSecret: normalizeSecrets(monitor) }; } catch (e) { diff --git a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts index 22fc903055eba1..bf34e200398676 100644 --- a/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/synthetics_service/test_now_monitor.ts @@ -40,7 +40,10 @@ export const triggerTestNow = async ( const monitorWithSecrets = await encryptedClient.getDecryptedAsInternalUser( syntheticsMonitorType, - monitorId + monitorId, + { + namespace: spaceId, + } ); const normalizedMonitor = normalizeSecrets(monitorWithSecrets); diff --git a/x-pack/test/api_integration/apis/synthetics/index.ts b/x-pack/test/api_integration/apis/synthetics/index.ts index 13c581bf168b00..b00ff699ca1b65 100644 --- a/x-pack/test/api_integration/apis/synthetics/index.ts +++ b/x-pack/test/api_integration/apis/synthetics/index.ts @@ -32,5 +32,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./add_edit_params')); loadTestFile(require.resolve('./add_monitor_project_private_location')); loadTestFile(require.resolve('./inspect_monitor')); + loadTestFile(require.resolve('./test_now_monitor')); }); } diff --git a/x-pack/test/api_integration/apis/synthetics/services/synthetics_monitor_test_service.ts b/x-pack/test/api_integration/apis/synthetics/services/synthetics_monitor_test_service.ts index 7dea2de5453d75..ea465986fadc56 100644 --- a/x-pack/test/api_integration/apis/synthetics/services/synthetics_monitor_test_service.ts +++ b/x-pack/test/api_integration/apis/synthetics/services/synthetics_monitor_test_service.ts @@ -10,14 +10,17 @@ import { syntheticsMonitorType } from '@kbn/synthetics-plugin/common/types/saved import { SavedObject } from '@kbn/core-saved-objects-common/src/server_types'; import { MonitorFields } from '@kbn/synthetics-plugin/common/runtime_types'; import { MonitorInspectResponse } from '@kbn/synthetics-plugin/public/apps/synthetics/state/monitor_management/api'; +import { v4 as uuidv4 } from 'uuid'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { KibanaSupertestProvider } from '../../../../../../test/api_integration/services/supertest'; export class SyntheticsMonitorTestService { private supertest: ReturnType; + private getService: FtrProviderContext['getService']; constructor(getService: FtrProviderContext['getService']) { this.supertest = getService('supertest'); + this.getService = getService; } async getMonitor(monitorId: string, decrypted: boolean = true, space?: string) { @@ -95,4 +98,34 @@ export class SyntheticsMonitorTestService { console.error(e); } } + + async addsNewSpace() { + const username = 'admin'; + const password = `${username}-password`; + const roleName = 'uptime-role'; + const SPACE_ID = `test-space-${uuidv4()}`; + const SPACE_NAME = `test-space-name ${uuidv4()}`; + + const security = this.getService('security'); + const kibanaServer = this.getService('kibanaServer'); + + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + + return { username, password, SPACE_ID }; + } } diff --git a/x-pack/test/api_integration/apis/synthetics/test_now_monitor.ts b/x-pack/test/api_integration/apis/synthetics/test_now_monitor.ts new file mode 100644 index 00000000000000..400e073f8a3f37 --- /dev/null +++ b/x-pack/test/api_integration/apis/synthetics/test_now_monitor.ts @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { MonitorFields } from '@kbn/synthetics-plugin/common/runtime_types'; +import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; +import expect from '@kbn/expect'; +import { omit } from 'lodash'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { getFixtureJson } from './helper/get_fixture_json'; +import { SyntheticsMonitorTestService } from './services/synthetics_monitor_test_service'; + +export default function ({ getService }: FtrProviderContext) { + describe('RunTestManually', function () { + this.tags('skipCloud'); + + const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + const monitorTestService = new SyntheticsMonitorTestService(getService); + const kibanaServer = getService('kibanaServer'); + + let newMonitor: MonitorFields; + + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + await supertest + .put(SYNTHETICS_API_URLS.SYNTHETICS_ENABLEMENT) + .set('kbn-xsrf', 'true') + .expect(200); + newMonitor = getFixtureJson('http_monitor'); + }); + + it('runs test manually', async () => { + const resp = await monitorTestService.addMonitor(newMonitor); + + const res = await supertest + .get(SYNTHETICS_API_URLS.TRIGGER_MONITOR + `/${resp.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const result = res.body; + expect(typeof result.testRunId).to.eql('string'); + expect(typeof result.configId).to.eql('string'); + expect(result.schedule).to.eql({ number: '5', unit: 'm' }); + expect(result.locations).to.eql([ + { + id: 'eu-west-01', + label: 'Europe East', + geo: { lat: 33.2343132435, lon: 73.2342343434 }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + { + id: 'eu-west-02', + label: 'Europe West', + geo: { lat: 33.2343132435, lon: 73.2342343434 }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + ]); + + expect(omit(result.monitor, ['id', 'config_id'])).to.eql( + omit(newMonitor, ['id', 'config_id']) + ); + }); + + it('works in non default space', async () => { + const { username, SPACE_ID, password } = await monitorTestService.addsNewSpace(); + + const resp = await supertestWithoutAuth + .post(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(newMonitor) + .expect(200); + + const res = await supertest + .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.TRIGGER_MONITOR}/${resp.body.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const result = res.body; + expect(typeof result.testRunId).to.eql('string'); + expect(typeof result.configId).to.eql('string'); + expect(result.schedule).to.eql({ number: '5', unit: 'm' }); + expect(result.locations).to.eql([ + { + id: 'eu-west-01', + label: 'Europe East', + geo: { lat: 33.2343132435, lon: 73.2342343434 }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + { + id: 'eu-west-02', + label: 'Europe West', + geo: { lat: 33.2343132435, lon: 73.2342343434 }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + ]); + + expect(omit(result.monitor, ['id', 'config_id'])).to.eql( + omit(newMonitor, ['id', 'config_id']) + ); + }); + }); +} From 25c6446711392fbc2a71b1a88a46edd9599a2c16 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Mon, 3 Jul 2023 14:10:25 +0200 Subject: [PATCH 20/98] [Discover] Fix search sessions using temporary data views (#161029) Enables search sessions in Discover to work correctly with temporary data view Co-authored-by: Julia Rechkunova --- .../main/services/discover_state.test.ts | 33 +++++++++++++++---- .../main/services/discover_state.ts | 14 ++++---- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/plugins/discover/public/application/main/services/discover_state.test.ts b/src/plugins/discover/public/application/main/services/discover_state.test.ts index bcf9aef7d80f17..0316ddd1b383dd 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.test.ts @@ -183,18 +183,21 @@ describe('Test createSearchSessionRestorationDataProvider', () => { let mockSavedSearch: SavedSearch = {} as unknown as SavedSearch; const history = createBrowserHistory(); const mockDataPlugin = dataPluginMock.createStartContract(); + const discoverStateContainer = getDiscoverStateContainer({ + services: discoverServiceMock, + history, + }); + discoverStateContainer.appState.update({ + index: savedSearchMock.searchSource.getField('index')!.id, + }); const searchSessionInfoProvider = createSearchSessionRestorationDataProvider({ data: mockDataPlugin, - appStateContainer: getDiscoverStateContainer({ - savedSearch: savedSearchMock, - services: discoverServiceMock, - history, - }).appState, + appStateContainer: discoverStateContainer.appState, getSavedSearch: () => mockSavedSearch, }); describe('session name', () => { - test('No saved search returns default name', async () => { + test('No persisted saved search returns default name', async () => { expect(await searchSessionInfoProvider.getName()).toBe('Discover'); }); @@ -211,6 +214,7 @@ describe('Test createSearchSessionRestorationDataProvider', () => { describe('session state', () => { test('restoreState has sessionId and initialState has not', async () => { + mockSavedSearch = savedSearchMock; const searchSessionId = 'id'; (mockDataPlugin.search.session.getSessionId as jest.Mock).mockImplementation( () => searchSessionId @@ -221,6 +225,7 @@ describe('Test createSearchSessionRestorationDataProvider', () => { }); test('restoreState has absoluteTimeRange', async () => { + mockSavedSearch = savedSearchMock; const relativeTime = 'relativeTime'; const absoluteTime = 'absoluteTime'; (mockDataPlugin.query.timefilter.timefilter.getTime as jest.Mock).mockImplementation( @@ -235,6 +240,7 @@ describe('Test createSearchSessionRestorationDataProvider', () => { }); test('restoreState has paused autoRefresh', async () => { + mockSavedSearch = savedSearchMock; const { initialState, restoreState } = await searchSessionInfoProvider.getLocatorData(); expect(initialState.refreshInterval).toBe(undefined); expect(restoreState.refreshInterval).toEqual({ @@ -242,6 +248,21 @@ describe('Test createSearchSessionRestorationDataProvider', () => { value: 0, }); }); + + test('restoreState has persisted data view', async () => { + mockSavedSearch = savedSearchMock; + const { initialState, restoreState } = await searchSessionInfoProvider.getLocatorData(); + expect(initialState.dataViewSpec).toEqual(undefined); + expect(restoreState.dataViewSpec).toEqual(undefined); + expect(initialState.dataViewId).toEqual(savedSearchMock.searchSource.getField('index')?.id); + }); + + test('restoreState has temporary data view', async () => { + mockSavedSearch = savedSearchAdHoc; + const { initialState, restoreState } = await searchSessionInfoProvider.getLocatorData(); + expect(initialState.dataViewSpec).toEqual({}); + expect(restoreState.dataViewSpec).toEqual({}); + }); }); }); 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 79eea9eed99640..e80f6e5c338b79 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.ts @@ -476,7 +476,7 @@ export function createSearchSessionRestorationDataProvider(deps: { data: DataPublicPluginStart; getSavedSearch: () => SavedSearch; }): SearchSessionInfoProvider { - const getSavedSearchId = () => deps.getSavedSearch().id; + const getSavedSearch = () => deps.getSavedSearch(); return { getName: async () => { const savedSearch = deps.getSavedSearch(); @@ -492,12 +492,12 @@ export function createSearchSessionRestorationDataProvider(deps: { id: DISCOVER_APP_LOCATOR, initialState: createUrlGeneratorState({ ...deps, - getSavedSearchId, + getSavedSearch, shouldRestoreSearchSession: false, }), restoreState: createUrlGeneratorState({ ...deps, - getSavedSearchId, + getSavedSearch, shouldRestoreSearchSession: true, }), }; @@ -508,20 +508,21 @@ export function createSearchSessionRestorationDataProvider(deps: { function createUrlGeneratorState({ appStateContainer, data, - getSavedSearchId, + getSavedSearch, shouldRestoreSearchSession, }: { appStateContainer: StateContainer; data: DataPublicPluginStart; - getSavedSearchId: () => string | undefined; + getSavedSearch: () => SavedSearch; shouldRestoreSearchSession: boolean; }): DiscoverAppLocatorParams { const appState = appStateContainer.get(); + const dataView = getSavedSearch().searchSource.getField('index'); return { filters: data.query.filterManager.getFilters(), dataViewId: appState.index, query: appState.query, - savedSearchId: getSavedSearchId(), + savedSearchId: getSavedSearch().id, timeRange: shouldRestoreSearchSession ? data.query.timefilter.timefilter.getAbsoluteTime() : data.query.timefilter.timefilter.getTime(), @@ -540,5 +541,6 @@ function createUrlGeneratorState({ viewMode: appState.viewMode, hideAggregatedPreview: appState.hideAggregatedPreview, breakdownField: appState.breakdownField, + dataViewSpec: !dataView?.isPersisted() ? dataView?.toSpec(false) : undefined, }; } From 90b3e712cbc6ca725f8fd5cc2adc5e0309b89f9e Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Mon, 3 Jul 2023 14:16:35 +0200 Subject: [PATCH 21/98] [http] capture errors thrown from handlers (#161063) ## Summary Fix https://github.com/elastic/kibana/issues/156803 Use `apm.captureError` to properly capture errors thrown by the route handler (as those errors are then converted to generic 500 errors before being returned by the server to avoid leaking internal info) --- .../src/router.ts | 7 ++++++ .../http/router.test.mocks.ts | 17 ++++++++++++++ .../integration_tests/http/router.test.ts | 20 ++++++++++++++++ .../http/versioned_router.test.mocks.ts | 17 ++++++++++++++ .../http/versioned_router.test.ts | 23 +++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100644 src/core/server/integration_tests/http/router.test.mocks.ts create mode 100644 src/core/server/integration_tests/http/versioned_router.test.mocks.ts diff --git a/packages/core/http/core-http-router-server-internal/src/router.ts b/packages/core/http/core-http-router-server-internal/src/router.ts index 7aede8bfc01a7f..509f407ff401a2 100644 --- a/packages/core/http/core-http-router-server-internal/src/router.ts +++ b/packages/core/http/core-http-router-server-internal/src/router.ts @@ -7,6 +7,7 @@ */ import type { Request, ResponseToolkit } from '@hapi/hapi'; +import apm from 'elastic-apm-node'; import { isConfigSchema } from '@kbn/config-schema'; import type { Logger } from '@kbn/logging'; import { @@ -206,18 +207,24 @@ export class Router = undefined; + public get versioned(): VersionedRouter { if (this.versionedRouter === undefined) { this.versionedRouter = CoreVersionedRouter.from({ diff --git a/src/core/server/integration_tests/http/router.test.mocks.ts b/src/core/server/integration_tests/http/router.test.mocks.ts new file mode 100644 index 00000000000000..fd2862acd437c0 --- /dev/null +++ b/src/core/server/integration_tests/http/router.test.mocks.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. + */ + +export const captureErrorMock = jest.fn(); + +jest.doMock('elastic-apm-node', () => { + const real = jest.requireActual('elastic-apm-node'); + return { + ...real, + captureError: captureErrorMock, + }; +}); diff --git a/src/core/server/integration_tests/http/router.test.ts b/src/core/server/integration_tests/http/router.test.ts index c9dca25eea0446..743624f2f46b3e 100644 --- a/src/core/server/integration_tests/http/router.test.ts +++ b/src/core/server/integration_tests/http/router.test.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +import { captureErrorMock } from './router.test.mocks'; + import { Stream } from 'stream'; import Boom from '@hapi/boom'; import supertest from 'supertest'; @@ -35,6 +37,7 @@ beforeEach(async () => { }); afterEach(async () => { + captureErrorMock.mockReset(); await server.stop(); }); @@ -581,6 +584,22 @@ describe('Handler', () => { `); }); + it('captures the error if handler throws', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + const error = new Error(`some error`); + router.get({ path: '/', validate: false }, (context, req, res) => { + throw error; + }); + await server.start(); + + await supertest(innerServer.listener).get('/').expect(500); + + expect(captureErrorMock).toHaveBeenCalledTimes(1); + expect(captureErrorMock).toHaveBeenCalledWith(error); + }); + it('returns 500 Server error if handler throws Boom error', async () => { const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter('/'); @@ -602,6 +621,7 @@ describe('Handler', () => { ], ] `); + expect(captureErrorMock).toHaveBeenCalledTimes(1); }); it('returns 500 Server error if handler returns unexpected result', async () => { diff --git a/src/core/server/integration_tests/http/versioned_router.test.mocks.ts b/src/core/server/integration_tests/http/versioned_router.test.mocks.ts new file mode 100644 index 00000000000000..fd2862acd437c0 --- /dev/null +++ b/src/core/server/integration_tests/http/versioned_router.test.mocks.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. + */ + +export const captureErrorMock = jest.fn(); + +jest.doMock('elastic-apm-node', () => { + const real = jest.requireActual('elastic-apm-node'); + return { + ...real, + captureError: captureErrorMock, + }; +}); diff --git a/src/core/server/integration_tests/http/versioned_router.test.ts b/src/core/server/integration_tests/http/versioned_router.test.ts index 0fbd64acad9cee..adde119815d785 100644 --- a/src/core/server/integration_tests/http/versioned_router.test.ts +++ b/src/core/server/integration_tests/http/versioned_router.test.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +import { captureErrorMock } from './versioned_router.test.mocks'; + import Supertest from 'supertest'; import { createTestEnv, getEnvOptions } from '@kbn/config-mocks'; import { schema } from '@kbn/config-schema'; @@ -59,6 +61,7 @@ describe('Routing versioned requests', () => { }); afterEach(async () => { + captureErrorMock.mockReset(); await server.stop(); }); @@ -167,6 +170,7 @@ describe('Routing versioned requests', () => { message: expect.stringMatching(/expected value of type/), }) ); + expect(captureErrorMock).not.toHaveBeenCalled(); }); it('returns the version in response headers', async () => { @@ -210,6 +214,7 @@ describe('Routing versioned requests', () => { message: expect.stringMatching(/Failed output validation/), }) ); + expect(captureErrorMock).not.toHaveBeenCalled(); }); it('does not run response validation in prod', async () => { @@ -295,6 +300,7 @@ describe('Routing versioned requests', () => { ).resolves.toEqual( expect.objectContaining({ message: expect.stringMatching(/No handlers registered/) }) ); + expect(captureErrorMock).not.toHaveBeenCalled(); }); it('resolves the newest handler on serverless', async () => { @@ -340,4 +346,21 @@ describe('Routing versioned requests', () => { .then(({ body }) => body.v) ).resolves.toEqual('oldest'); }); + + it('captures the error if handler throws', async () => { + const error = new Error(`some error`); + + router.versioned + .get({ path: '/my-path', access: 'internal' }) + .addVersion({ validate: false, version: '1' }, async (ctx, req, res) => { + throw error; + }); + + await server.start(); + + await supertest.get('/my-path').set('Elastic-Api-Version', '1').expect(500); + + expect(captureErrorMock).toHaveBeenCalledTimes(1); + expect(captureErrorMock).toHaveBeenCalledWith(error); + }); }); From e8b2303875a8f7c1ed7ac9210fb8397dbed52073 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 3 Jul 2023 15:18:05 +0300 Subject: [PATCH 22/98] [Text based] Configure Lens suggestion on the fly from Discover (#159559) ## Summary Part of https://github.com/elastic/kibana/issues/158802 This PR removes the navigation from Discover to Lens and renders a push flyout instead. ![textbased](https://github.com/elastic/kibana/assets/17003240/92c6f290-6cf9-4daa-920e-f1409595d765) Next tasks (follow-up PRs): - [ ] Remove the text based support from Lens dataview picker. The FTs should be removed from there and possibly moved to discover FTs - [ ] Apply the same flyout in dashboard for text based panels - [ ] Allow drag and drop between dimensions - [ ] Investigate why the Field select doesnt close when you click outside the dropdown ### Checklist - [ ] 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 - [ ] 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)) - [ ] 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: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Andrea Del Rio --- .../public/__mocks__/lens_table_adapter.ts | 40 ++ .../__mocks__/{services.ts => services.tsx} | 3 +- .../public/chart/chart.test.tsx | 11 + .../unified_histogram/public/chart/chart.tsx | 76 ++- .../public/chart/histogram.tsx | 1 + .../hooks/use_chart_config_panel.test.tsx | 66 +++ .../chart/hooks/use_chart_config_panel.tsx | 101 ++++ .../public/chart/hooks/use_chart_styles.tsx | 6 + .../hooks/use_edit_visualization.test.ts | 15 + .../chart/hooks/use_edit_visualization.ts | 4 +- .../public/chart/suggestion_selector.tsx | 8 +- .../container/hooks/use_state_props.test.ts | 126 +++++ .../public/container/hooks/use_state_props.ts | 5 +- .../container/services/state_service.test.ts | 4 + .../container/services/state_service.ts | 13 + .../public/container/utils/state_selectors.ts | 1 + .../public/layout/layout.tsx | 4 + .../get_edit_lens_configuration.tsx | 129 ++++++ .../lens_configuration_flyout.test.tsx | 433 ++++++++++++++++++ .../lens_configuration_flyout.tsx | 174 +++++++ x-pack/plugins/lens/public/async_services.ts | 1 + .../text_based/text_based_languages.test.ts | 16 + .../text_based/text_based_languages.tsx | 8 + .../public/datasources/text_based/types.ts | 2 +- .../config_panel/config_panel.test.tsx | 9 +- .../config_panel/config_panel.tsx | 67 ++- .../config_panel/layer_panel.test.tsx | 9 + .../editor_frame/config_panel/layer_panel.tsx | 35 +- .../editor_frame/config_panel/types.ts | 6 +- .../editor_frame/workspace_panel/index.ts | 1 + .../workspace_panel_wrapper.test.tsx | 8 +- .../workspace_panel_wrapper.tsx | 79 ++-- .../public/editor_frame_service/mocks.tsx | 4 + .../embeddable/embeddable_component.tsx | 2 + .../lens/public/mocks/lens_plugin_mock.tsx | 1 + x-pack/plugins/lens/public/plugin.ts | 22 + .../lens/public/state_management/index.ts | 1 + .../state_management/lens_slice.test.ts | 23 + .../public/state_management/lens_slice.ts | 44 ++ .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../apps/discover/visualize_field.ts | 8 +- 43 files changed, 1477 insertions(+), 92 deletions(-) create mode 100644 src/plugins/unified_histogram/public/__mocks__/lens_table_adapter.ts rename src/plugins/unified_histogram/public/__mocks__/{services.ts => services.tsx} (92%) create mode 100644 src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx create mode 100644 src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx create mode 100644 x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx create mode 100644 x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx create mode 100644 x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx diff --git a/src/plugins/unified_histogram/public/__mocks__/lens_table_adapter.ts b/src/plugins/unified_histogram/public/__mocks__/lens_table_adapter.ts new file mode 100644 index 00000000000000..60e38fecbbfaea --- /dev/null +++ b/src/plugins/unified_histogram/public/__mocks__/lens_table_adapter.ts @@ -0,0 +1,40 @@ +/* + * Copyright 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 { Datatable } from '@kbn/expressions-plugin/common'; + +export const lensTablesAdapterMock: Record = { + default: { + columns: [ + { + id: 'col-0-1', + meta: { + dimensionName: 'Slice size', + type: 'number', + }, + name: 'Field 1', + }, + { + id: 'col-0-2', + meta: { + dimensionName: 'Slice', + type: 'number', + }, + name: 'Field 2', + }, + ], + rows: [ + { + 'col-0-1': 0, + 'col-0-2': 0, + 'col-0-3': 0, + 'col-0-4': 0, + }, + ], + type: 'datatable', + }, +}; diff --git a/src/plugins/unified_histogram/public/__mocks__/services.ts b/src/plugins/unified_histogram/public/__mocks__/services.tsx similarity index 92% rename from src/plugins/unified_histogram/public/__mocks__/services.ts rename to src/plugins/unified_histogram/public/__mocks__/services.tsx index 71058be4f634fc..6b6e5a7f468647 100644 --- a/src/plugins/unified_histogram/public/__mocks__/services.ts +++ b/src/plugins/unified_histogram/public/__mocks__/services.tsx @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - +import React from 'react'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; @@ -33,6 +33,7 @@ export const unifiedHistogramServicesMock = { suggestions: jest.fn(() => allSuggestionsMock), }; }), + EditLensConfigPanelApi: jest.fn().mockResolvedValue(Lens Config Panel Component), }, storage: { get: jest.fn(), diff --git a/src/plugins/unified_histogram/public/chart/chart.test.tsx b/src/plugins/unified_histogram/public/chart/chart.test.tsx index a2c5f3b195a215..b32979cc004e55 100644 --- a/src/plugins/unified_histogram/public/chart/chart.test.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.test.tsx @@ -233,6 +233,17 @@ describe('Chart', () => { expect(component.find(SuggestionSelector).exists()).toBeTruthy(); }); + it('should render the edit on the fly button when chart is visible and suggestions exist', async () => { + const component = await mountComponent({ + currentSuggestion: currentSuggestionMock, + allSuggestions: allSuggestionsMock, + isPlainRecord: true, + }); + expect( + component.find('[data-test-subj="unifiedHistogramEditFlyoutVisualization"]').exists() + ).toBeTruthy(); + }); + it('should render the save button when chart is visible and suggestions exist', async () => { const component = await mountComponent({ currentSuggestion: currentSuggestionMock, diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index f99d9b3de1cea0..6b112f3578df96 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -6,8 +6,7 @@ * Side Public License, v 1. */ -import { ReactElement, useMemo, useState } from 'react'; -import React, { memo } from 'react'; +import React, { ReactElement, useMemo, useState, useEffect, useCallback, memo } from 'react'; import { EuiButtonIcon, EuiContextMenu, @@ -18,6 +17,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { Suggestion } from '@kbn/lens-plugin/public'; +import type { Datatable } from '@kbn/expressions-plugin/common'; import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/public'; import type { LensEmbeddableInput } from '@kbn/lens-plugin/public'; import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; @@ -42,6 +42,7 @@ import { useTotalHits } from './hooks/use_total_hits'; import { useRequestParams } from './hooks/use_request_params'; import { useChartStyles } from './hooks/use_chart_styles'; import { useChartActions } from './hooks/use_chart_actions'; +import { useChartConfigPanel } from './hooks/use_chart_config_panel'; import { getLensAttributes } from './utils/get_lens_attributes'; import { useRefetch } from './hooks/use_refetch'; import { useEditVisualization } from './hooks/use_edit_visualization'; @@ -67,6 +68,7 @@ export interface ChartProps { disableTriggers?: LensEmbeddableInput['disableTriggers']; disabledActions?: LensEmbeddableInput['disabledActions']; input$?: UnifiedHistogramInput$; + lensTablesAdapter?: Record; onResetChartHeight?: () => void; onChartHiddenChange?: (chartHidden: boolean) => void; onTimeIntervalChange?: (timeInterval: string) => void; @@ -101,6 +103,7 @@ export function Chart({ disableTriggers, disabledActions, input$: originalInput$, + lensTablesAdapter, onResetChartHeight, onChartHiddenChange, onTimeIntervalChange, @@ -112,6 +115,7 @@ export function Chart({ onBrushEnd, }: ChartProps) { const [isSaveModalVisible, setIsSaveModalVisible] = useState(false); + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); const { showChartOptionsPopover, chartRef, @@ -190,6 +194,7 @@ export function Chart({ histogramCss, breakdownFieldSelectorGroupCss, breakdownFieldSelectorItemCss, + suggestionsSelectorItemCss, chartToolButtonCss, } = useChartStyles(chartVisible); @@ -215,6 +220,34 @@ export function Chart({ ] ); + const ChartConfigPanel = useChartConfigPanel({ + services, + lensAttributesContext, + dataView, + lensTablesAdapter, + currentSuggestion, + isFlyoutVisible, + setIsFlyoutVisible, + isPlainRecord, + query: originalQuery, + onSuggestionChange, + }); + + const onSuggestionSelectorChange = useCallback( + (s: Suggestion | undefined) => { + onSuggestionChange?.(s); + }, + [onSuggestionChange] + ); + + useEffect(() => { + // close the flyout for dataview mode + // or if no chart is visible + if (!chartVisible && isFlyoutVisible) { + setIsFlyoutVisible(false); + } + }, [chartVisible, isFlyoutVisible]); + const onEditVisualization = useEditVisualization({ services, dataView, @@ -226,6 +259,24 @@ export function Chart({ const canSaveVisualization = chartVisible && currentSuggestion && services.capabilities.dashboard?.showWriteControls; + const renderEditButton = useMemo( + () => ( + setIsFlyoutVisible(true)} + data-test-subj="unifiedHistogramEditFlyoutVisualization" + aria-label={i18n.translate('unifiedHistogram.editVisualizationButton', { + defaultMessage: 'Edit visualization', + })} + disabled={isFlyoutVisible} + /> + ), + [isFlyoutVisible] + ); + + const canEditVisualizationOnTheFly = isPlainRecord && chartVisible; + return ( )} {chartVisible && currentSuggestion && allSuggestions && allSuggestions?.length > 1 && ( - + )} @@ -296,6 +348,21 @@ export function Chart({ )} + {canEditVisualizationOnTheFly && ( + + {!isFlyoutVisible ? ( + + {renderEditButton} + + ) : ( + renderEditButton + )} + + )} {onEditVisualization && ( )} + {isFlyoutVisible && ChartConfigPanel} ); } diff --git a/src/plugins/unified_histogram/public/chart/histogram.tsx b/src/plugins/unified_histogram/public/chart/histogram.tsx index 61320c627bb13c..63a0c9897b8c74 100644 --- a/src/plugins/unified_histogram/public/chart/histogram.tsx +++ b/src/plugins/unified_histogram/public/chart/histogram.tsx @@ -146,6 +146,7 @@ export function Histogram({ const chartCss = css` position: relative; flex-grow: 1; + margin-block: ${euiTheme.size.xs}; & > div { height: 100%; diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx b/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx new file mode 100644 index 00000000000000..5f0d4b17e80db4 --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx @@ -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 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 { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import { renderHook } from '@testing-library/react-hooks'; +import { act } from 'react-test-renderer'; +import { setTimeout } from 'timers/promises'; +import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield'; +import { unifiedHistogramServicesMock } from '../../__mocks__/services'; +import { lensTablesAdapterMock } from '../../__mocks__/lens_table_adapter'; +import { useChartConfigPanel } from './use_chart_config_panel'; +import type { LensAttributesContext } from '../utils/get_lens_attributes'; + +describe('useChartConfigPanel', () => { + it('should return a jsx element to edit the visualization', async () => { + const lensAttributes = { + visualizationType: 'lnsXY', + title: 'test', + } as TypedLensByValueInput['attributes']; + const hook = renderHook(() => + useChartConfigPanel({ + services: unifiedHistogramServicesMock, + dataView: dataViewWithTimefieldMock, + lensAttributesContext: { + attributes: lensAttributes, + } as unknown as LensAttributesContext, + isFlyoutVisible: true, + setIsFlyoutVisible: jest.fn(), + isPlainRecord: true, + lensTablesAdapter: lensTablesAdapterMock, + query: { + sql: 'Select * from test', + }, + }) + ); + await act(() => setTimeout(0)); + expect(hook.result.current).toBeDefined(); + expect(hook.result.current).not.toBeNull(); + }); + + it('should return null if not in text based mode', async () => { + const lensAttributes = { + visualizationType: 'lnsXY', + title: 'test', + } as TypedLensByValueInput['attributes']; + const hook = renderHook(() => + useChartConfigPanel({ + services: unifiedHistogramServicesMock, + dataView: dataViewWithTimefieldMock, + lensAttributesContext: { + attributes: lensAttributes, + } as unknown as LensAttributesContext, + isFlyoutVisible: true, + setIsFlyoutVisible: jest.fn(), + isPlainRecord: false, + }) + ); + await act(() => setTimeout(0)); + expect(hook.result.current).toBeNull(); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx b/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx new file mode 100644 index 00000000000000..99fb8fbb8fe31b --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, useEffect, useRef, useState } from 'react'; +import type { AggregateQuery, Query } from '@kbn/es-query'; +import { isEqual } from 'lodash'; +import type { Suggestion } from '@kbn/lens-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/public'; +import type { Datatable } from '@kbn/expressions-plugin/common'; + +import type { UnifiedHistogramServices } from '../../types'; +import type { LensAttributesContext } from '../utils/get_lens_attributes'; + +export function useChartConfigPanel({ + services, + lensAttributesContext, + dataView, + lensTablesAdapter, + currentSuggestion, + isFlyoutVisible, + setIsFlyoutVisible, + isPlainRecord, + query, + onSuggestionChange, +}: { + services: UnifiedHistogramServices; + lensAttributesContext: LensAttributesContext; + dataView: DataView; + isFlyoutVisible: boolean; + setIsFlyoutVisible: (flag: boolean) => void; + lensTablesAdapter?: Record; + currentSuggestion?: Suggestion; + isPlainRecord?: boolean; + query?: Query | AggregateQuery; + onSuggestionChange?: (suggestion: Suggestion | undefined) => void; +}) { + const [editLensConfigPanel, setEditLensConfigPanel] = useState(null); + const previousSuggestion = useRef(undefined); + const previousAdapters = useRef | undefined>(undefined); + const previousQuery = useRef(undefined); + const updateSuggestion = useCallback( + (datasourceState, visualizationState) => { + const updatedSuggestion = { + ...currentSuggestion, + ...(datasourceState && { datasourceState }), + ...(visualizationState && { visualizationState }), + } as Suggestion; + onSuggestionChange?.(updatedSuggestion); + }, + [currentSuggestion, onSuggestionChange] + ); + + useEffect(() => { + const dataHasChanged = + Boolean(lensTablesAdapter) && + !isEqual(previousAdapters.current, lensTablesAdapter) && + query !== previousQuery?.current; + async function fetchLensConfigComponent() { + const Component = await services.lens.EditLensConfigPanelApi(); + const panel = ( + + ); + setEditLensConfigPanel(panel); + previousSuggestion.current = currentSuggestion; + previousAdapters.current = lensTablesAdapter; + if (dataHasChanged) { + previousQuery.current = query; + } + } + const suggestionHasChanged = currentSuggestion?.title !== previousSuggestion?.current?.title; + // rerender the component if the data has changed or the suggestion + // as I can have different suggestions for the same data + if (isPlainRecord && (dataHasChanged || suggestionHasChanged || !isFlyoutVisible)) { + fetchLensConfigComponent(); + } + }, [ + lensAttributesContext.attributes, + services.lens, + dataView, + updateSuggestion, + isPlainRecord, + currentSuggestion, + query, + isFlyoutVisible, + lensTablesAdapter, + setIsFlyoutVisible, + ]); + + return isPlainRecord ? editLensConfigPanel : null; +} diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_chart_styles.tsx b/src/plugins/unified_histogram/public/chart/hooks/use_chart_styles.tsx index c019c7cef981ef..13b527be702c1b 100644 --- a/src/plugins/unified_histogram/public/chart/hooks/use_chart_styles.tsx +++ b/src/plugins/unified_histogram/public/chart/hooks/use_chart_styles.tsx @@ -56,6 +56,11 @@ export const useChartStyles = (chartVisible: boolean) => { align-items: flex-end; padding-left: ${euiTheme.size.s}; `; + const suggestionsSelectorItemCss = css` + min-width: 0; + align-items: flex-start; + padding-left: ${euiTheme.size.s}; + `; const chartToolButtonCss = css` display: flex; justify-content: center; @@ -70,6 +75,7 @@ export const useChartStyles = (chartVisible: boolean) => { histogramCss, breakdownFieldSelectorGroupCss, breakdownFieldSelectorItemCss, + suggestionsSelectorItemCss, chartToolButtonCss, }; }; diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts index 8bd9e9161c8377..ec213dd53e1413 100644 --- a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts +++ b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.test.ts @@ -81,6 +81,21 @@ describe('useEditVisualization', () => { expect(hook.result.current).toBeUndefined(); }); + it('should return undefined if is on text based mode', async () => { + getTriggerCompatibleActions.mockReturnValue(Promise.resolve([{ id: 'test' }])); + const hook = renderHook(() => + useEditVisualization({ + services: unifiedHistogramServicesMock, + dataView: dataViewWithTimefieldMock, + relativeTimeRange: { from: 'now-15m', to: 'now' }, + lensAttributes: {} as unknown as TypedLensByValueInput['attributes'], + isPlainRecord: true, + }) + ); + await act(() => setTimeout(0)); + expect(hook.result.current).toBeUndefined(); + }); + it('should return undefined if the time field is not visualizable', async () => { getTriggerCompatibleActions.mockReturnValue(Promise.resolve([{ id: 'test' }])); const dataView = { diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts index e681fd34cd91ef..b02732bfcbfc96 100644 --- a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts +++ b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts @@ -32,10 +32,10 @@ export const useEditVisualization = ({ const [canVisualize, setCanVisualize] = useState(false); const checkCanVisualize = useCallback(async () => { - if (!dataView.id) { + if (!dataView.id || isPlainRecord) { return false; } - if (!isPlainRecord && (!dataView.isTimeBased() || !dataView.getTimeField().visualizable)) { + if (!dataView.isTimeBased() || !dataView.getTimeField().visualizable) { return false; } diff --git a/src/plugins/unified_histogram/public/chart/suggestion_selector.tsx b/src/plugins/unified_histogram/public/chart/suggestion_selector.tsx index 85860cf2c9bc86..0196387633396b 100644 --- a/src/plugins/unified_histogram/public/chart/suggestion_selector.tsx +++ b/src/plugins/unified_histogram/public/chart/suggestion_selector.tsx @@ -67,7 +67,7 @@ export const SuggestionSelector = ({ const { euiTheme } = useEuiTheme(); const suggestionComboCss = css` width: 100%; - max-width: ${euiTheme.base * 22}px; + max-width: ${euiTheme.base * 15}px; `; return ( @@ -78,9 +78,7 @@ export const SuggestionSelector = ({ > } placeholder={i18n.translate('unifiedHistogram.suggestionSelectorPlaceholder', { defaultMessage: 'Select visualization', })} @@ -88,9 +86,9 @@ export const SuggestionSelector = ({ options={suggestionOptions} selectedOptions={selectedSuggestion} onChange={onSelectionChange} - compressed fullWidth={true} isClearable={false} + compressed onFocus={disableFieldPopover} onBlur={enableFieldPopover} renderOption={(option) => { diff --git a/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts b/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts index fcdd194410db06..c0eeb9448eee7c 100644 --- a/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts +++ b/src/plugins/unified_histogram/public/container/hooks/use_state_props.test.ts @@ -15,6 +15,7 @@ import { UnifiedHistogramFetchStatus } from '../../types'; import { dataViewMock } from '../../__mocks__/data_view'; import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield'; import { currentSuggestionMock } from '../../__mocks__/suggestions'; +import { lensTablesAdapterMock } from '../../__mocks__/lens_table_adapter'; import { unifiedHistogramServicesMock } from '../../__mocks__/services'; import { createStateService, @@ -28,6 +29,7 @@ describe('useStateProps', () => { breakdownField: 'bytes', chartHidden: false, lensRequestAdapter: new RequestAdapter(), + lensTablesAdapter: lensTablesAdapterMock, timeInterval: 'auto', topPanelHeight: 100, totalHitsStatus: UnifiedHistogramFetchStatus.uninitialized, @@ -82,6 +84,37 @@ describe('useStateProps', () => { "total": undefined, }, "isPlainRecord": false, + "lensTablesAdapter": Object { + "default": Object { + "columns": Array [ + Object { + "id": "col-0-1", + "meta": Object { + "dimensionName": "Slice size", + "type": "number", + }, + "name": "Field 1", + }, + Object { + "id": "col-0-2", + "meta": Object { + "dimensionName": "Slice", + "type": "number", + }, + "name": "Field 2", + }, + ], + "rows": Array [ + Object { + "col-0-1": 0, + "col-0-2": 0, + "col-0-3": 0, + "col-0-4": 0, + }, + ], + "type": "datatable", + }, + }, "onBreakdownFieldChange": [Function], "onChartHiddenChange": [Function], "onChartLoad": [Function], @@ -126,6 +159,37 @@ describe('useStateProps', () => { "total": undefined, }, "isPlainRecord": true, + "lensTablesAdapter": Object { + "default": Object { + "columns": Array [ + Object { + "id": "col-0-1", + "meta": Object { + "dimensionName": "Slice size", + "type": "number", + }, + "name": "Field 1", + }, + Object { + "id": "col-0-2", + "meta": Object { + "dimensionName": "Slice", + "type": "number", + }, + "name": "Field 2", + }, + ], + "rows": Array [ + Object { + "col-0-1": 0, + "col-0-2": 0, + "col-0-3": 0, + "col-0-4": 0, + }, + ], + "type": "datatable", + }, + }, "onBreakdownFieldChange": [Function], "onChartHiddenChange": [Function], "onChartLoad": [Function], @@ -191,6 +255,37 @@ describe('useStateProps', () => { "total": undefined, }, "isPlainRecord": false, + "lensTablesAdapter": Object { + "default": Object { + "columns": Array [ + Object { + "id": "col-0-1", + "meta": Object { + "dimensionName": "Slice size", + "type": "number", + }, + "name": "Field 1", + }, + Object { + "id": "col-0-2", + "meta": Object { + "dimensionName": "Slice", + "type": "number", + }, + "name": "Field 2", + }, + ], + "rows": Array [ + Object { + "col-0-1": 0, + "col-0-2": 0, + "col-0-3": 0, + "col-0-4": 0, + }, + ], + "type": "datatable", + }, + }, "onBreakdownFieldChange": [Function], "onChartHiddenChange": [Function], "onChartLoad": [Function], @@ -232,6 +327,37 @@ describe('useStateProps', () => { "total": undefined, }, "isPlainRecord": false, + "lensTablesAdapter": Object { + "default": Object { + "columns": Array [ + Object { + "id": "col-0-1", + "meta": Object { + "dimensionName": "Slice size", + "type": "number", + }, + "name": "Field 1", + }, + Object { + "id": "col-0-2", + "meta": Object { + "dimensionName": "Slice", + "type": "number", + }, + "name": "Field 2", + }, + ], + "rows": Array [ + Object { + "col-0-1": 0, + "col-0-2": 0, + "col-0-3": 0, + "col-0-4": 0, + }, + ], + "type": "datatable", + }, + }, "onBreakdownFieldChange": [Function], "onChartHiddenChange": [Function], "onChartLoad": [Function], diff --git a/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts b/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts index b9c4570cdecb98..a5845731cf12ed 100644 --- a/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts +++ b/src/plugins/unified_histogram/public/container/hooks/use_state_props.ts @@ -23,6 +23,7 @@ import { timeIntervalSelector, totalHitsResultSelector, totalHitsStatusSelector, + lensTablesAdapterSelector, } from '../utils/state_selectors'; import { useStateSelector } from '../utils/use_state_selector'; @@ -44,7 +45,7 @@ export const useStateProps = ({ const timeInterval = useStateSelector(stateService?.state$, timeIntervalSelector); const totalHitsResult = useStateSelector(stateService?.state$, totalHitsResultSelector); const totalHitsStatus = useStateSelector(stateService?.state$, totalHitsStatusSelector); - + const lensTablesAdapter = useStateSelector(stateService?.state$, lensTablesAdapterSelector); /** * Contexts */ @@ -139,6 +140,7 @@ export const useStateProps = ({ (event: UnifiedHistogramChartLoadEvent) => { // We need to store the Lens request adapter in order to inspect its requests stateService?.setLensRequestAdapter(event.adapters.requests); + stateService?.setLensTablesAdapter(event.adapters.tables?.tables); }, [stateService] ); @@ -174,6 +176,7 @@ export const useStateProps = ({ breakdown, request, isPlainRecord, + lensTablesAdapter, onTopPanelHeightChange, onTimeIntervalChange, onTotalHitsChange, diff --git a/src/plugins/unified_histogram/public/container/services/state_service.test.ts b/src/plugins/unified_histogram/public/container/services/state_service.test.ts index eb839e6eaba0f2..eb7232e889037d 100644 --- a/src/plugins/unified_histogram/public/container/services/state_service.test.ts +++ b/src/plugins/unified_histogram/public/container/services/state_service.test.ts @@ -9,6 +9,7 @@ import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { UnifiedHistogramFetchStatus } from '../..'; import { unifiedHistogramServicesMock } from '../../__mocks__/services'; +import { lensTablesAdapterMock } from '../../__mocks__/lens_table_adapter'; import { getChartHidden, getTopPanelHeight, @@ -46,6 +47,7 @@ describe('UnifiedHistogramStateService', () => { breakdownField: 'bytes', chartHidden: false, lensRequestAdapter: new RequestAdapter(), + lensTablesAdapter: lensTablesAdapterMock, timeInterval: 'auto', topPanelHeight: 100, totalHitsStatus: UnifiedHistogramFetchStatus.uninitialized, @@ -134,6 +136,8 @@ describe('UnifiedHistogramStateService', () => { expect(state).toEqual(newState); stateService.setLensRequestAdapter(undefined); newState = { ...newState, lensRequestAdapter: undefined }; + stateService.setLensTablesAdapter(undefined); + newState = { ...newState, lensTablesAdapter: undefined }; expect(state).toEqual(newState); stateService.setTotalHits({ totalHitsStatus: UnifiedHistogramFetchStatus.complete, diff --git a/src/plugins/unified_histogram/public/container/services/state_service.ts b/src/plugins/unified_histogram/public/container/services/state_service.ts index 01d1a7f0c3f608..1fd0905d86c7af 100644 --- a/src/plugins/unified_histogram/public/container/services/state_service.ts +++ b/src/plugins/unified_histogram/public/container/services/state_service.ts @@ -8,6 +8,7 @@ import type { RequestAdapter } from '@kbn/inspector-plugin/common'; import type { Suggestion } from '@kbn/lens-plugin/public'; +import type { Datatable } from '@kbn/expressions-plugin/common'; import { BehaviorSubject, Observable } from 'rxjs'; import { UnifiedHistogramFetchStatus } from '../..'; import type { UnifiedHistogramServices } from '../../types'; @@ -40,6 +41,10 @@ export interface UnifiedHistogramState { * The current Lens request adapter */ lensRequestAdapter: RequestAdapter | undefined; + /** + * The current Lens request table + */ + lensTablesAdapter?: Record; /** * The current time interval of the chart */ @@ -108,6 +113,10 @@ export interface UnifiedHistogramStateService { * Sets the current Lens request adapter */ setLensRequestAdapter: (lensRequestAdapter: RequestAdapter | undefined) => void; + /** + * Sets the current Lens tables + */ + setLensTablesAdapter: (lensTablesAdapter: Record | undefined) => void; /** * Sets the current total hits status and result */ @@ -190,6 +199,10 @@ export const createStateService = ( updateState({ lensRequestAdapter }); }, + setLensTablesAdapter: (lensTablesAdapter: Record | undefined) => { + updateState({ lensTablesAdapter }); + }, + setTotalHits: (totalHits: { totalHitsStatus: UnifiedHistogramFetchStatus; totalHitsResult: number | Error | undefined; diff --git a/src/plugins/unified_histogram/public/container/utils/state_selectors.ts b/src/plugins/unified_histogram/public/container/utils/state_selectors.ts index d11fb1182cc457..80e809f4fc38fd 100644 --- a/src/plugins/unified_histogram/public/container/utils/state_selectors.ts +++ b/src/plugins/unified_histogram/public/container/utils/state_selectors.ts @@ -15,3 +15,4 @@ export const topPanelHeightSelector = (state: UnifiedHistogramState) => state.to export const totalHitsResultSelector = (state: UnifiedHistogramState) => state.totalHitsResult; export const totalHitsStatusSelector = (state: UnifiedHistogramState) => state.totalHitsStatus; export const currentSuggestionSelector = (state: UnifiedHistogramState) => state.currentSuggestion; +export const lensTablesAdapterSelector = (state: UnifiedHistogramState) => state.lensTablesAdapter; diff --git a/src/plugins/unified_histogram/public/layout/layout.tsx b/src/plugins/unified_histogram/public/layout/layout.tsx index 3c5b021e0b08db..cd6d2ffb5ec07d 100644 --- a/src/plugins/unified_histogram/public/layout/layout.tsx +++ b/src/plugins/unified_histogram/public/layout/layout.tsx @@ -11,6 +11,7 @@ import { PropsWithChildren, ReactElement, RefObject } from 'react'; import React, { useMemo } from 'react'; import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; import { css } from '@emotion/css'; +import type { Datatable } from '@kbn/expressions-plugin/common'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; import type { LensEmbeddableInput, LensSuggestionsApi, Suggestion } from '@kbn/lens-plugin/public'; import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; @@ -77,6 +78,7 @@ export interface UnifiedHistogramLayoutProps extends PropsWithChildren * Context object for the hits count -- leave undefined to hide the hits count */ hits?: UnifiedHistogramHitsContext; + lensTablesAdapter?: Record; /** * Context object for the chart -- leave undefined to hide the chart */ @@ -169,6 +171,7 @@ export const UnifiedHistogramLayout = ({ columns, request, hits, + lensTablesAdapter, chart: originalChart, breakdown, resizeRef, @@ -273,6 +276,7 @@ export const UnifiedHistogramLayout = ({ onChartLoad={onChartLoad} onFilter={onFilter} onBrushEnd={onBrushEnd} + lensTablesAdapter={lensTablesAdapter} /> {children} diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx new file mode 100644 index 00000000000000..0eb71d6f6e1d7d --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.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 React, { useEffect, useState } from 'react'; +import { EuiFlyout, EuiLoadingSpinner, EuiOverlayMask } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { Provider } from 'react-redux'; +import { PreloadedState } from '@reduxjs/toolkit'; +import { css } from '@emotion/react'; +import type { CoreStart } from '@kbn/core/public'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import { + makeConfigureStore, + LensRootStore, + LensAppState, + LensState, +} from '../../../state_management'; +import { getPreloadedState } from '../../../state_management/lens_slice'; + +import type { DatasourceMap, VisualizationMap } from '../../../types'; +import { + LensEditConfigurationFlyout, + type EditConfigPanelProps, +} from './lens_configuration_flyout'; +import type { LensAppServices } from '../../types'; + +export type EditLensConfigurationProps = Omit< + EditConfigPanelProps, + 'startDependencies' | 'coreStart' | 'visualizationMap' | 'datasourceMap' +>; + +function LoadingSpinnerWithOverlay() { + return ( + + + + ); +} + +export function getEditLensConfiguration( + coreStart: CoreStart, + startDependencies: LensPluginStartDependencies, + visualizationMap?: VisualizationMap, + datasourceMap?: DatasourceMap +) { + return ({ + attributes, + dataView, + updateAll, + setIsFlyoutVisible, + datasourceId, + adaptersTables, + }: EditLensConfigurationProps) => { + const [lensServices, setLensServices] = useState(); + useEffect(() => { + async function loadLensService() { + const { getLensServices, getLensAttributeService } = await import( + '../../../async_services' + ); + const lensServicesT = await getLensServices( + coreStart, + startDependencies, + getLensAttributeService(coreStart, startDependencies) + ); + + setLensServices(lensServicesT); + } + loadLensService(); + }, []); + + if (!lensServices || !datasourceMap || !visualizationMap || !dataView.id) { + return ; + } + const datasourceState = attributes.state.datasourceStates[datasourceId]; + const storeDeps = { + lensServices, + datasourceMap, + visualizationMap, + initialContext: + datasourceState && 'initialContext' in datasourceState + ? datasourceState.initialContext + : undefined, + }; + const lensStore: LensRootStore = makeConfigureStore(storeDeps, { + lens: getPreloadedState(storeDeps) as LensAppState, + } as unknown as PreloadedState); + const closeFlyout = () => { + setIsFlyoutVisible?.(false); + }; + + const configPanelProps = { + attributes, + dataView, + updateAll, + setIsFlyoutVisible, + datasourceId, + adaptersTables, + coreStart, + startDependencies, + visualizationMap, + datasourceMap, + }; + + return ( + + + + + + ); + }; +} diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx new file mode 100644 index 00000000000000..dc05ff15773823 --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -0,0 +1,433 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { EuiFlyoutBody } from '@elastic/eui'; +import { mountWithProvider } from '../../../mocks'; +import type { Query, AggregateQuery } from '@kbn/es-query'; +import type { DataView } from '@kbn/data-views-plugin/public'; +import { coreMock } from '@kbn/core/public/mocks'; +import { + mockVisualizationMap, + mockDatasourceMap, + mockStoreDeps, + mockDataPlugin, +} from '../../../mocks'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import { createMockStartDependencies } from '../../../editor_frame_service/mocks'; +import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; +import { VisualizationToolbar } from '../../../editor_frame_service/editor_frame/workspace_panel'; +import { ConfigPanelWrapper } from '../../../editor_frame_service/editor_frame/config_panel/config_panel'; +import { + LensEditConfigurationFlyout, + type EditConfigPanelProps, +} from './lens_configuration_flyout'; + +let container: HTMLDivElement | undefined; + +beforeEach(() => { + container = document.createElement('div'); + container.id = 'lensContainer'; + document.body.appendChild(container); +}); + +afterEach(() => { + if (container && container.parentNode) { + container.parentNode.removeChild(container); + } + + container = undefined; +}); + +describe('LensEditConfigurationFlyout', () => { + const mockStartDependencies = + createMockStartDependencies() as unknown as LensPluginStartDependencies; + const data = mockDataPlugin(); + (data.query.timefilter.timefilter.getTime as jest.Mock).mockReturnValue({ + from: 'now-2m', + to: 'now', + }); + const startDependencies = { + ...mockStartDependencies, + data, + }; + + function prepareAndMountComponent( + props: ReturnType, + query?: Query | AggregateQuery + ) { + return mountWithProvider( + , + { + preloadedState: { + datasourceStates: { + testDatasource: { + isLoading: false, + state: 'state', + }, + }, + activeDatasourceId: 'testDatasource', + query: query as Query, + }, + storeDeps: mockStoreDeps({ + datasourceMap: props.datasourceMap, + visualizationMap: props.visualizationMap, + }), + }, + { + attachTo: container, + } + ); + } + + function getDefaultProps( + { datasourceMap = mockDatasourceMap(), visualizationMap = mockVisualizationMap() } = { + datasourceMap: mockDatasourceMap(), + visualizationMap: mockVisualizationMap(), + } + ) { + const lensAttributes = { + title: 'test', + visualizationType: 'testVis', + state: { + datasourceStates: { + testDatasource: {}, + }, + visualization: {}, + filters: [], + query: { + language: 'lucene', + query: '', + }, + }, + filters: [], + query: { + language: 'lucene', + query: '', + }, + references: [], + } as unknown as TypedLensByValueInput['attributes']; + + const dataView = { id: 'index1', isPersisted: () => true } as unknown as DataView; + return { + attributes: lensAttributes, + dataView, + updateAll: jest.fn(), + coreStart: coreMock.createStart(), + startDependencies, + visualizationMap, + datasourceMap, + setIsFlyoutVisible: jest.fn(), + datasourceId: 'testDatasource', + } as unknown as EditConfigPanelProps; + } + + it('should call the setIsFlyout callback if collapse button is clicked', async () => { + const setIsFlyoutVisibleSpy = jest.fn(); + const props = getDefaultProps(); + const newProps = { + ...props, + setIsFlyoutVisible: setIsFlyoutVisibleSpy, + }; + const { instance } = await prepareAndMountComponent(newProps); + expect(instance.find(EuiFlyoutBody).exists()).toBe(true); + instance.find('[data-test-subj="collapseFlyoutButton"]').at(1).simulate('click'); + expect(setIsFlyoutVisibleSpy).toHaveBeenCalled(); + }); + + it('should compute the frame public api correctly', async () => { + const props = getDefaultProps(); + const { instance } = await prepareAndMountComponent(props); + expect(instance.find(ConfigPanelWrapper).exists()).toBe(true); + expect(instance.find(VisualizationToolbar).exists()).toBe(true); + expect(instance.find(VisualizationToolbar).prop('framePublicAPI')).toMatchInlineSnapshot(` + Object { + "activeData": Object {}, + "dataViews": Object { + "indexPatternRefs": Array [], + "indexPatterns": Object { + "index1": Object { + "id": "index1", + "isPersisted": [Function], + }, + }, + }, + "datasourceLayers": Object { + "a": Object { + "datasourceId": "testDatasource", + "getFilters": [MockFunction], + "getMaxPossibleNumValues": [MockFunction], + "getOperationForColumnId": [MockFunction], + "getSourceId": [MockFunction], + "getTableSpec": [MockFunction], + "getVisualDefaults": [MockFunction], + "hasDefaultTimeField": [MockFunction], + "isTextBasedLanguage": [MockFunction] { + "calls": Array [ + Array [], + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": false, + }, + Object { + "type": "return", + "value": false, + }, + ], + }, + }, + }, + "dateRange": Object { + "fromDate": "2021-01-10T04:00:00.000Z", + "toDate": "2021-01-10T08:00:00.000Z", + }, + } + `); + }); + + it('should compute the activeVisualization correctly', async () => { + const props = getDefaultProps(); + const { instance } = await prepareAndMountComponent(props); + expect(instance.find(VisualizationToolbar).prop('activeVisualization')).toMatchInlineSnapshot(` + Object { + "appendLayer": [MockFunction], + "clearLayer": [MockFunction], + "getConfiguration": [MockFunction] { + "calls": Array [ + Array [ + Object { + "frame": Object { + "activeData": Object {}, + "dataViews": Object { + "indexPatternRefs": Array [], + "indexPatterns": Object { + "index1": Object { + "id": "index1", + "isPersisted": [Function], + }, + }, + }, + "datasourceLayers": Object { + "a": Object { + "datasourceId": "testDatasource", + "getFilters": [MockFunction], + "getMaxPossibleNumValues": [MockFunction], + "getOperationForColumnId": [MockFunction], + "getSourceId": [MockFunction], + "getTableSpec": [MockFunction], + "getVisualDefaults": [MockFunction], + "hasDefaultTimeField": [MockFunction], + "isTextBasedLanguage": [MockFunction] { + "calls": Array [ + Array [], + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": false, + }, + Object { + "type": "return", + "value": false, + }, + ], + }, + }, + }, + "dateRange": Object { + "fromDate": "2021-01-10T04:00:00.000Z", + "toDate": "2021-01-10T08:00:00.000Z", + }, + }, + "layerId": "layer1", + "state": Object {}, + }, + ], + Array [ + Object { + "frame": Object { + "activeData": Object {}, + "dataViews": Object { + "indexPatternRefs": Array [], + "indexPatterns": Object { + "index1": Object { + "id": "index1", + "isPersisted": [Function], + }, + }, + }, + "datasourceLayers": Object { + "a": Object { + "datasourceId": "testDatasource", + "getFilters": [MockFunction], + "getMaxPossibleNumValues": [MockFunction], + "getOperationForColumnId": [MockFunction], + "getSourceId": [MockFunction], + "getTableSpec": [MockFunction], + "getVisualDefaults": [MockFunction], + "hasDefaultTimeField": [MockFunction], + "isTextBasedLanguage": [MockFunction] { + "calls": Array [ + Array [], + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": false, + }, + Object { + "type": "return", + "value": false, + }, + ], + }, + }, + }, + "dateRange": Object { + "fromDate": "2021-01-10T04:00:00.000Z", + "toDate": "2021-01-10T08:00:00.000Z", + }, + }, + "layerId": "layer1", + "state": Object {}, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "groups": Array [ + Object { + "accessors": Array [], + "dataTestSubj": "mockVisA", + "filterOperations": [MockFunction], + "groupId": "a", + "groupLabel": "a", + "layerId": "layer1", + "supportsMoreColumns": true, + }, + ], + }, + }, + Object { + "type": "return", + "value": Object { + "groups": Array [ + Object { + "accessors": Array [], + "dataTestSubj": "mockVisA", + "filterOperations": [MockFunction], + "groupId": "a", + "groupLabel": "a", + "layerId": "layer1", + "supportsMoreColumns": true, + }, + ], + }, + }, + ], + }, + "getDescription": [MockFunction] { + "calls": Array [ + Array [ + Object {}, + ], + Array [ + Object {}, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "label": "", + }, + }, + Object { + "type": "return", + "value": Object { + "label": "", + }, + }, + ], + }, + "getLayerIds": [MockFunction] { + "calls": Array [ + Array [ + Object {}, + ], + Array [ + Object {}, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Array [ + "layer1", + ], + }, + Object { + "type": "return", + "value": Array [ + "layer1", + ], + }, + ], + }, + "getLayerType": [MockFunction] { + "calls": Array [ + Array [ + "layer1", + Object {}, + ], + Array [ + "layer1", + Object {}, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": "data", + }, + Object { + "type": "return", + "value": "data", + }, + ], + }, + "getRenderEventCounters": [MockFunction], + "getSuggestions": [MockFunction], + "getSupportedLayers": [MockFunction], + "getVisualizationTypeId": [MockFunction], + "id": "testVis", + "initialize": [MockFunction], + "removeDimension": [MockFunction], + "removeLayer": [MockFunction], + "renderDimensionEditor": [MockFunction], + "setDimension": [MockFunction], + "switchVisualizationType": [MockFunction], + "toExpression": [MockFunction], + "toPreviewExpression": [MockFunction], + "visualizationTypes": Array [ + Object { + "groupLabel": "testVisGroup", + "icon": "empty", + "id": "testVis", + "label": "TEST", + }, + ], + } + `); + }); +}); 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 new file mode 100644 index 00000000000000..9fe486c58048a9 --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -0,0 +1,174 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + EuiButtonEmpty, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + useEuiTheme, + EuiCallOut, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { css } from '@emotion/react'; +import type { CoreStart } from '@kbn/core/public'; +import type { Datatable } from '@kbn/expressions-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/public'; +import { getResolvedDateRange } from '../../../utils'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import { + DataViewsState, + useLensDispatch, + updateStateFromSuggestion, +} from '../../../state_management'; +import { VisualizationToolbar } from '../../../editor_frame_service/editor_frame/workspace_panel'; + +import type { DatasourceMap, VisualizationMap, DatasourceLayers } from '../../../types'; +import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; +import { ConfigPanelWrapper } from '../../../editor_frame_service/editor_frame/config_panel/config_panel'; + +export interface EditConfigPanelProps { + attributes: TypedLensByValueInput['attributes']; + dataView: DataView; + updateAll: (datasourceState: unknown, visualizationState: unknown) => void; + coreStart: CoreStart; + startDependencies: LensPluginStartDependencies; + visualizationMap: VisualizationMap; + datasourceMap: DatasourceMap; + setIsFlyoutVisible?: (flag: boolean) => void; + datasourceId: 'formBased' | 'textBased'; + adaptersTables?: Record; +} + +export function LensEditConfigurationFlyout({ + attributes, + dataView, + coreStart, + startDependencies, + visualizationMap, + datasourceMap, + datasourceId, + updateAll, + setIsFlyoutVisible, + adaptersTables, +}: EditConfigPanelProps) { + const currentDataViewId = dataView.id ?? ''; + const datasourceState = attributes.state.datasourceStates[datasourceId]; + const activeVisualization = visualizationMap[attributes.visualizationType]; + const activeDatasource = datasourceMap[datasourceId]; + const dispatchLens = useLensDispatch(); + const { euiTheme } = useEuiTheme(); + const dataViews = useMemo(() => { + return { + indexPatterns: { + [currentDataViewId]: dataView, + }, + indexPatternRefs: [], + } as unknown as DataViewsState; + }, [currentDataViewId, dataView]); + dispatchLens( + updateStateFromSuggestion({ + newDatasourceId: datasourceId, + visualizationId: activeVisualization.id, + visualizationState: attributes.state.visualization, + datasourceState, + dataViews, + }) + ); + + const datasourceLayers: DatasourceLayers = useMemo(() => { + return {}; + }, []); + const activeData: Record = useMemo(() => { + return {}; + }, []); + const layers = activeDatasource.getLayers(datasourceState); + layers.forEach((layer) => { + datasourceLayers[layer] = datasourceMap[datasourceId].getPublicAPI({ + state: datasourceState, + layerId: layer, + indexPatterns: dataViews.indexPatterns, + }); + if (adaptersTables) { + activeData[layer] = Object.values(adaptersTables)[0]; + } + }); + + const dateRange = getResolvedDateRange(startDependencies.data.query.timefilter.timefilter); + const framePublicAPI = useMemo(() => { + return { + activeData, + dataViews, + datasourceLayers, + dateRange, + }; + }, [activeData, dataViews, datasourceLayers, dateRange]); + + const closeFlyout = () => { + setIsFlyoutVisible?.(false); + }; + + const layerPanelsProps = { + framePublicAPI, + datasourceMap, + visualizationMap, + core: coreStart, + dataViews: startDependencies.dataViews, + uiActions: startDependencies.uiActions, + hideLayerHeader: true, + onUpdateStateCb: updateAll, + }; + return ( + <> + + + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/lens/public/async_services.ts b/x-pack/plugins/lens/public/async_services.ts index 38a904c5617c99..d4c6fe5be8dcdd 100644 --- a/x-pack/plugins/lens/public/async_services.ts +++ b/x-pack/plugins/lens/public/async_services.ts @@ -30,6 +30,7 @@ export * from './visualizations/gauge/gauge_visualization'; export * from './visualizations/gauge'; export * from './visualizations/tagcloud/tagcloud_visualization'; export * from './visualizations/tagcloud'; +export { getEditLensConfiguration } from './app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration'; export * from './datasources/form_based/form_based'; export { getTextBasedDatasource } from './datasources/text_based/text_based_languages'; diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts index 42b405c939d3c0..d12505e93f07ad 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts @@ -410,6 +410,22 @@ describe('Textbased Data Source', () => { ); expect(suggestions[0].state).toEqual({ ...state, + fieldList: [ + { + id: 'newid', + meta: { + type: 'number', + }, + name: 'bytes', + }, + { + id: 'newid', + meta: { + type: 'string', + }, + name: 'dest', + }, + ], layers: { newid: { allColumns: [ diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index 573137da1ebc2d..653a3f30e1b447 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -122,6 +122,14 @@ export function getTextBasedDatasource({ const query = context.query; const updatedState = { ...state, + fieldList: + newColumns?.map((c) => { + return { + id: c.columnId, + name: c.fieldName, + meta: c.meta, + }; + }) ?? [], layers: { ...state.layers, [newLayerId]: { diff --git a/x-pack/plugins/lens/public/datasources/text_based/types.ts b/x-pack/plugins/lens/public/datasources/text_based/types.ts index 0594fdcf2fbc24..544996c904b77a 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/types.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/types.ts @@ -31,12 +31,12 @@ export interface TextBasedLayer { export interface TextBasedPersistedState { layers: Record; + initialContext?: VisualizeFieldContext | VisualizeEditorContext; } export type TextBasedPrivateState = TextBasedPersistedState & { indexPatternRefs: IndexPatternRef[]; fieldList: DatatableColumn[]; - initialContext?: VisualizeFieldContext | VisualizeEditorContext; }; export interface IndexPatternRef { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx index 78f7246c52e6d8..f9e09143d3e43c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx @@ -170,13 +170,19 @@ describe('ConfigPanel', () => { it('allow datasources and visualizations to use setters', async () => { const props = getDefaultProps(); - const { instance, lensStore } = await prepareAndMountComponent(props); + const onUpdateCbSpy = jest.fn(); + const newProps = { + ...props, + onUpdateStateCb: onUpdateCbSpy, + }; + const { instance, lensStore } = await prepareAndMountComponent(newProps); const { updateDatasource, updateAll } = instance.find(LayerPanel).props(); const updater = () => 'updated'; updateDatasource('testDatasource', updater); await waitMs(0); expect(lensStore.dispatch).toHaveBeenCalledTimes(1); + expect(onUpdateCbSpy).toHaveBeenCalled(); expect( (lensStore.dispatch as jest.Mock).mock.calls[0][0].payload.updater( props.datasourceStates.testDatasource.state @@ -184,6 +190,7 @@ describe('ConfigPanel', () => { ).toEqual('updated'); updateAll('testDatasource', updater, props.visualizationState); + expect(onUpdateCbSpy).toHaveBeenCalled(); // wait for one tick so async updater has a chance to trigger await waitMs(0); expect(lensStore.dispatch).toHaveBeenCalledTimes(2); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index af1549e00cc30e..571fc5194d5e3c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -6,6 +6,7 @@ */ import React, { useMemo, memo, useCallback } from 'react'; +import { useStore } from 'react-redux'; import { EuiForm } from '@elastic/eui'; import { ActionExecutionContext } from '@kbn/ui-actions-plugin/public'; import { isOfAggregateQueryType } from '@kbn/es-query'; @@ -52,7 +53,8 @@ export function LayerPanels( activeVisualization: Visualization; } ) { - const { activeVisualization, datasourceMap, indexPatternService } = props; + const lensStore = useStore(); + const { activeVisualization, datasourceMap, indexPatternService, onUpdateStateCb } = props; const { activeDatasourceId, visualization, datasourceStates, query } = useLensSelector( (state) => state.lens ); @@ -74,8 +76,12 @@ export function LayerPanels( newState, }) ); + if (onUpdateStateCb && activeDatasourceId) { + const dsState = datasourceStates[activeDatasourceId].state; + onUpdateStateCb?.(dsState, newState); + } }, - [activeVisualization, dispatchLens] + [activeDatasourceId, activeVisualization.id, datasourceStates, dispatchLens, onUpdateStateCb] ); const updateDatasource = useMemo( () => @@ -90,9 +96,10 @@ export function LayerPanels( dontSyncLinkedDimensions, }) ); + onUpdateStateCb?.(newState, visualization.state); } }, - [dispatchLens] + [dispatchLens, onUpdateStateCb, visualization.state] ); const updateDatasourceAsync = useMemo( () => (datasourceId: string | undefined, newState: unknown) => { @@ -147,9 +154,10 @@ export function LayerPanels( }, }) ); + onUpdateStateCb?.(newDatasourceState, newVisualizationState); }, 0); }, - [dispatchLens] + [dispatchLens, onUpdateStateCb] ); const toggleFullscreen = useMemo( @@ -213,20 +221,21 @@ export function LayerPanels( visualizationId?: string; layerId?: string; }) => { - const indexPatterns = await props.indexPatternService.ensureIndexPattern({ + const indexPatterns = await props.indexPatternService?.ensureIndexPattern({ id: indexPatternId, cache: props.framePublicAPI.dataViews.indexPatterns, }); - - dispatchLens( - changeIndexPattern({ - indexPatternId, - datasourceIds: datasourceId ? [datasourceId] : [], - visualizationIds: visualizationId ? [visualizationId] : [], - layerId, - dataViews: { indexPatterns }, - }) - ); + if (indexPatterns) { + dispatchLens( + changeIndexPattern({ + indexPatternId, + datasourceIds: datasourceId ? [datasourceId] : [], + visualizationIds: visualizationId ? [visualizationId] : [], + layerId, + dataViews: { indexPatterns }, + }) + ); + } }, [dispatchLens, props.framePublicAPI.dataViews.indexPatterns, props.indexPatternService] ); @@ -262,6 +271,7 @@ export function LayerPanels( updateVisualization={setVisualizationState} updateDatasource={updateDatasource} updateDatasourceAsync={updateDatasourceAsync} + displayLayerSettings={!props.hideLayerHeader} onChangeIndexPattern={(args) => { onChangeIndexPattern(args); const layersToRemove = @@ -307,6 +317,13 @@ export function LayerPanels( const datasourcePublicAPI = props.framePublicAPI.datasourceLayers?.[layerId]; const datasourceId = datasourcePublicAPI?.datasourceId; dispatchLens(removeDimension({ ...dimensionProps, datasourceId })); + if (datasourceId && onUpdateStateCb) { + const newState = lensStore.getState().lens; + onUpdateStateCb( + newState.datasourceStates[datasourceId].state, + newState.visualization.state + ); + } }} toggleFullscreen={toggleFullscreen} indexPatternService={indexPatternService} @@ -336,19 +353,21 @@ export function LayerPanels( indexPatternId = dataView.id; } - const newIndexPatterns = await indexPatternService.ensureIndexPattern({ + const newIndexPatterns = await indexPatternService?.ensureIndexPattern({ id: indexPatternId, cache: props.framePublicAPI.dataViews.indexPatterns, }); - dispatchLens( - changeIndexPattern({ - dataViews: { indexPatterns: newIndexPatterns }, - datasourceIds: Object.keys(datasourceStates), - visualizationIds: visualization.activeId ? [visualization.activeId] : [], - indexPatternId, - }) - ); + if (newIndexPatterns) { + dispatchLens( + changeIndexPattern({ + dataViews: { indexPatterns: newIndexPatterns }, + datasourceIds: Object.keys(datasourceStates), + visualizationIds: visualization.activeId ? [visualization.activeId] : [], + indexPatternId, + }) + ); + } }, registerLibraryAnnotationGroup: (groupInfo) => dispatchLens(registerLibraryAnnotationGroup(groupInfo)), diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index 248681717b0823..2b8568bd129089 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -11,6 +11,7 @@ import { EuiFormRow } from '@elastic/eui'; import { ChildDragDropProvider, DragDrop } from '@kbn/dom-drag-drop'; import { FramePublicAPI, Visualization, VisualizationConfigProps } from '../../../types'; import { LayerPanel } from './layer_panel'; +import { LayerActions } from './layer_actions'; import { coreMock } from '@kbn/core/public/mocks'; import { generateId } from '../../../id_generator'; import { @@ -116,6 +117,7 @@ describe('LayerPanel', () => { onChangeIndexPattern: jest.fn(), indexPatternService: createIndexPatternServiceMock(), getUserMessages: () => [], + displayLayerSettings: true, }; } @@ -203,6 +205,13 @@ describe('LayerPanel', () => { expect(optionalLabel.text()).toEqual('Optional'); }); + it('should hide the layer actions if displayLayerSettings is set to false', async () => { + const { instance } = await mountWithProvider( + + ); + expect(instance.find(LayerActions).exists()).toBe(false); + }); + it('should render the group with a way to add a new column', async () => { mockVisualization.getConfiguration.mockReturnValue({ groups: [ diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index bb90c82b235e6b..84c0b18d30c5a6 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -87,8 +87,9 @@ export function LayerPanel( datasourceId?: string; visualizationId?: string; }) => void; - indexPatternService: IndexPatternServiceAPI; - getUserMessages: UserMessagesGetter; + indexPatternService?: IndexPatternServiceAPI; + getUserMessages?: UserMessagesGetter; + displayLayerSettings: boolean; } ) { const [activeDimension, setActiveDimension] = useState( @@ -418,17 +419,20 @@ export function LayerPanel( activeVisualization={activeVisualization} /> - - -

- + {props.displayLayerSettings && ( + + +
+ + )} - {(layerDatasource || activeVisualization.renderLayerPanel) && } - {layerDatasource && ( + {props.indexPatternService && + (layerDatasource || activeVisualization.renderLayerPanel) && } + {layerDatasource && props.indexPatternService && ( { const { columnId } = accessorConfig; - const messages = props.getUserMessages('dimensionButton', { - dimensionId: columnId, - }); + const messages = + props?.getUserMessages?.('dimensionButton', { + dimensionId: columnId, + }) ?? []; return ( void; } export interface LayerPanelProps { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts index c3ba019ca68ade..9f51ea611e9b8c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts @@ -6,3 +6,4 @@ */ export { WorkspacePanel } from './workspace_panel'; +export { VisualizationToolbar } from './workspace_panel_wrapper'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx index 42735bde405c41..700fe7f96bf84c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx @@ -65,7 +65,13 @@ describe('workspace_panel_wrapper', () => { isFullscreen={false} lensInspector={{} as unknown as LensInspector} getUserMessages={() => []} - /> + />, + { + preloadedState: { + visualization: { activeId: 'myVis', state: visState }, + datasourceStates: {}, + }, + } ); expect(renderToolbarMock).toHaveBeenCalledWith(expect.any(Element), { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index 6b61e4dd374c50..064b268209aeac 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -16,6 +16,7 @@ import { FramePublicAPI, UserMessagesGetter, VisualizationMap, + Visualization, } from '../../../types'; import { DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS } from '../../../utils'; import { NativeRenderer } from '../../../native_renderer'; @@ -49,6 +50,52 @@ export interface WorkspacePanelWrapperProps { getUserMessages: UserMessagesGetter; } +export function VisualizationToolbar(props: { + activeVisualization: Visualization | null; + framePublicAPI: FramePublicAPI; + onUpdateStateCb?: (datasourceState: unknown, visualizationState: unknown) => void; +}) { + const dispatchLens = useLensDispatch(); + const { activeDatasourceId, visualization, datasourceStates } = useLensSelector( + (state) => state.lens + ); + const setVisualizationState = useCallback( + (newState: unknown) => { + if (!props.activeVisualization) { + return; + } + dispatchLens( + updateVisualizationState({ + visualizationId: props.activeVisualization.id, + newState, + }) + ); + if (activeDatasourceId && props.onUpdateStateCb) { + const dsState = datasourceStates[activeDatasourceId].state; + props.onUpdateStateCb?.(dsState, newState); + } + }, + [activeDatasourceId, datasourceStates, dispatchLens, props] + ); + + return ( + <> + {props.activeVisualization && props.activeVisualization.renderToolbar && ( + + + + )} + + ); +} + export function WorkspacePanelWrapper({ children, framePublicAPI, @@ -65,21 +112,6 @@ export function WorkspacePanelWrapper({ const autoApplyEnabled = useLensSelector(selectAutoApplyEnabled); const activeVisualization = visualizationId ? visualizationMap[visualizationId] : null; - const setVisualizationState = useCallback( - (newState: unknown) => { - if (!activeVisualization) { - return; - } - dispatchLens( - updateVisualizationState({ - visualizationId: activeVisualization.id, - newState, - }) - ); - }, - [dispatchLens, activeVisualization] - ); - const userMessages = getUserMessages('toolbar'); return ( @@ -116,19 +148,10 @@ export function WorkspacePanelWrapper({ framePublicAPI={framePublicAPI} /> - - {activeVisualization && activeVisualization.renderToolbar && ( - - - - )} + )} diff --git a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx index edccc071a57d1a..4513e0f4bffd4b 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/mocks.tsx @@ -10,6 +10,8 @@ import { ExpressionsSetup, ExpressionsStart } from '@kbn/expressions-plugin/publ import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks'; import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { EditorFrameSetupPlugins, EditorFrameStartPlugins } from './service'; @@ -57,5 +59,7 @@ export function createMockStartDependencies() { embeddable: embeddablePluginMock.createStartContract(), expressions: expressionsPluginMock.createStartContract(), charts: chartPluginMock.createStartContract(), + uiActions: uiActionsPluginMock.createStartContract(), + dataViews: dataViewPluginMocks.createStartContract(), } as unknown as MockedStartDependencies; } diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx index 943e87c9c00c24..67076fb9c9200a 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx @@ -23,6 +23,7 @@ import { import type { LensByReferenceInput, LensByValueInput } from './embeddable'; import type { Document } from '../persistence'; import type { FormBasedPersistedState } from '../datasources/form_based/types'; +import type { TextBasedPersistedState } from '../datasources/text_based/types'; import type { XYState } from '../visualizations/xy/types'; import type { PieVisualizationState, @@ -45,6 +46,7 @@ type LensAttributes = Omit< state: Omit & { datasourceStates: { formBased: FormBasedPersistedState; + textBased?: TextBasedPersistedState; }; visualization: TVisState; }; diff --git a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx index cbf310cb2f50a9..f526e46d8f5ec3 100644 --- a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx +++ b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx @@ -21,6 +21,7 @@ export const lensPluginMock = { SaveModalComponent: jest.fn(() => { return Lens Save Modal Component; }), + EditLensConfigPanelApi: jest.fn().mockResolvedValue(Lens Config Panel Component), canUseEditor: jest.fn(() => true), navigateToPrefilledEditor: jest.fn(), getXyVisTypes: jest diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index b207f07266ae82..1a195183142c3f 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -126,6 +126,7 @@ import { type LensAppLocator, LensAppLocatorDefinition } from '../common/locator import { downloadCsvShareProvider } from './app_plugin/csv_download_provider/csv_download_provider'; import { CONTENT_ID, LATEST_VERSION } from '../common/content_management'; +import type { EditLensConfigurationProps } from './app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration'; export interface LensPluginSetupDependencies { urlForwarding: UrlForwardingSetup; @@ -215,6 +216,14 @@ export interface LensPublicStart { * @experimental */ SaveModalComponent: React.ComponentType>; + /** + * React component which can be used to embed a Lens Visualization Config Panel Component. + * + * This API might undergo breaking changes even in minor versions. + * + * @experimental + */ + EditLensConfigPanelApi: () => Promise; /** * Method which navigates to the Lens editor, loading the state specified by the `input` parameter. * See `x-pack/examples/embedded_lens_example` for exemplary usage. @@ -252,6 +261,8 @@ export interface LensPublicStart { }>; } +export type EditLensConfigPanelComponent = React.ComponentType; + export type LensSuggestionsApi = ( context: VisualizeFieldContext | VisualizeEditorContext, dataViews: DataView, @@ -649,6 +660,17 @@ export class LensPlugin { }, }; }, + EditLensConfigPanelApi: async () => { + const { getEditLensConfiguration } = await import('./async_services'); + if (!this.editorFrameService) { + this.initDependenciesForApi(); + } + const [visualizationMap, datasourceMap] = await Promise.all([ + this.editorFrameService!.loadVisualizations(), + this.editorFrameService!.loadDatasources(), + ]); + return getEditLensConfiguration(core, startDependencies, visualizationMap, datasourceMap); + }, }; } diff --git a/x-pack/plugins/lens/public/state_management/index.ts b/x-pack/plugins/lens/public/state_management/index.ts index 9a9a4005714aa1..f4b333e25c8150 100644 --- a/x-pack/plugins/lens/public/state_management/index.ts +++ b/x-pack/plugins/lens/public/state_management/index.ts @@ -35,6 +35,7 @@ export const { submitSuggestion, switchDatasource, switchAndCleanDatasource, + updateStateFromSuggestion, updateIndexPatterns, setToggleFullscreen, initEmpty, diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.test.ts b/x-pack/plugins/lens/public/state_management/lens_slice.test.ts index c69931837b3aaf..0371d5564d5034 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.test.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.test.ts @@ -10,6 +10,7 @@ import type { Query } from '@kbn/es-query'; import { switchDatasource, switchAndCleanDatasource, + updateStateFromSuggestion, switchVisualization, setState, updateState, @@ -271,6 +272,28 @@ describe('lensSlice', () => { }); }); + describe('update the state from the suggestion', () => { + it('should switch active datasource and initialize new state', () => { + store.dispatch( + updateStateFromSuggestion({ + newDatasourceId: 'testDatasource2', + visualizationId: 'testVis', + visualizationState: ['col1', 'col2'], + datasourceState: {}, + dataViews: { indexPatterns: {} } as DataViewsState, + }) + ); + expect(store.getState().lens.activeDatasourceId).toEqual('testDatasource2'); + expect(store.getState().lens.datasourceStates.testDatasource2.isLoading).toEqual(false); + expect(store.getState().lens.datasourceStates.testDatasource2.state).toStrictEqual({}); + expect(store.getState().lens.visualization).toStrictEqual({ + activeId: 'testVis', + state: ['col1', 'col2'], + }); + expect(store.getState().lens.dataViews).toEqual({ indexPatterns: {} }); + }); + }); + describe('adding or removing layer', () => { const testDatasource = (datasourceId: string) => { return { diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.ts b/x-pack/plugins/lens/public/state_management/lens_slice.ts index e7829361ca5f97..cb35f16f0e8c50 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.ts @@ -173,6 +173,13 @@ export const switchAndCleanDatasource = createAction<{ visualizationId: string | null; currentIndexPatternId?: string; }>('lens/switchAndCleanDatasource'); +export const updateStateFromSuggestion = createAction<{ + newDatasourceId: string; + visualizationId: string | null; + visualizationState: unknown; + datasourceState: unknown; + dataViews: DataViewsState; +}>('lens/updateStateFromSuggestion'); export const navigateAway = createAction('lens/navigateAway'); export const loadInitial = createAction<{ initialInput?: LensEmbeddableInput; @@ -267,6 +274,7 @@ export const lensActions = { submitSuggestion, switchDatasource, switchAndCleanDatasource, + updateStateFromSuggestion, navigateAway, loadInitial, initEmpty, @@ -848,6 +856,42 @@ export const makeLensReducer = (storeDeps: LensStoreDeps) => { }, }; }, + [updateStateFromSuggestion.type]: ( + state, + { + payload, + }: { + payload: { + newDatasourceId: string; + visualizationId: string; + visualizationState: unknown; + datasourceState: unknown; + dataViews: DataViewsState; + }; + } + ) => { + const visualization = { + activeId: payload.visualizationId, + state: payload.visualizationState, + }; + + const datasourceState = payload.datasourceState; + + return { + ...state, + datasourceStates: { + [payload.newDatasourceId]: { + state: datasourceState, + isLoading: false, + }, + }, + activeDatasourceId: payload.newDatasourceId, + visualization: { + ...visualization, + }, + dataViews: payload.dataViews, + }; + }, [navigateAway.type]: (state) => state, [loadInitial.type]: ( state, diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index d28554d63bbc32..121e0dce922c9e 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -5673,7 +5673,6 @@ "unifiedHistogram.lensTitle": "Modifier la visualisation", "unifiedHistogram.resetChartHeight": "Réinitialiser à la hauteur par défaut", "unifiedHistogram.showChart": "Afficher le graphique", - "unifiedHistogram.suggestionSelectorLabel": "Visualisation", "unifiedHistogram.suggestionSelectorPlaceholder": "Sélectionner la visualisation", "unifiedHistogram.timeIntervals": "Intervalles de temps", "unifiedHistogram.timeIntervalWithValueWarning": "Avertissement", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d8763e4030c788..2789358b1e0f2c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5674,7 +5674,6 @@ "unifiedHistogram.lensTitle": "ビジュアライゼーションを編集", "unifiedHistogram.resetChartHeight": "デフォルトの高さにリセット", "unifiedHistogram.showChart": "グラフを表示", - "unifiedHistogram.suggestionSelectorLabel": "ビジュアライゼーション", "unifiedHistogram.suggestionSelectorPlaceholder": "ビジュアライゼーションを選択", "unifiedHistogram.timeIntervals": "時間間隔", "unifiedHistogram.timeIntervalWithValueWarning": "警告", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 59d89ca3145511..fd0126b228758b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5673,7 +5673,6 @@ "unifiedHistogram.lensTitle": "编辑可视化", "unifiedHistogram.resetChartHeight": "重置为默认高度", "unifiedHistogram.showChart": "显示图表", - "unifiedHistogram.suggestionSelectorLabel": "可视化", "unifiedHistogram.suggestionSelectorPlaceholder": "选择可视化", "unifiedHistogram.timeIntervals": "时间间隔", "unifiedHistogram.timeIntervalWithValueWarning": "警告", diff --git a/x-pack/test/functional/apps/discover/visualize_field.ts b/x-pack/test/functional/apps/discover/visualize_field.ts index bb914c45fa2b75..22049dc351caa5 100644 --- a/x-pack/test/functional/apps/discover/visualize_field.ts +++ b/x-pack/test/functional/apps/discover/visualize_field.ts @@ -156,11 +156,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.click('querySubmitButton'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.click('TextBasedLangEditor-expand'); - await testSubjects.click('unifiedHistogramEditVisualization'); + await testSubjects.click('unifiedHistogramEditFlyoutVisualization'); await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.waitFor('lens visualization', async () => { + await retry.waitFor('lens flyout', async () => { const dimensions = await testSubjects.findAll('lns-dimensionTrigger-textBased'); return dimensions.length === 2 && (await dimensions[1].getVisibleText()) === 'average'; }); @@ -175,11 +175,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.click('querySubmitButton'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.click('TextBasedLangEditor-expand'); - await testSubjects.click('unifiedHistogramEditVisualization'); + await testSubjects.click('unifiedHistogramEditFlyoutVisualization'); await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.waitFor('lens visualization', async () => { + await retry.waitFor('lens flyout', async () => { const dimensions = await testSubjects.findAll('lns-dimensionTrigger-textBased'); return dimensions.length === 2 && (await dimensions[1].getVisibleText()) === 'average'; }); From 66fd6eb0effad25c290e90e376addec0738339dd Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Mon, 3 Jul 2023 09:00:36 -0400 Subject: [PATCH 23/98] [Fleet] Update fleet file storage indices to the new Datastream names (#160998) ## Summary - Updates fleet file storage indexes to the new Datastream names: | Old Name | New Name | |-----------|-------------------| | `.fleet-file-data-*` | `.fleet-fileds-fromhost-data-*` | | `.fleet-files-*` | `.fleet-fileds-fromhost-meta-*` | | `.fleet-filedelivery-data-*` | `.fleet-fileds-tohost-data-*` | | `.fleet-filedelivery-meta-*` | `.fleet-fileds-tohost-meta-*` | - Removes code that was initializing the old backing indexes - Updates the `fleet:check-deleted-files-task` to ensure it correctly parses the index name/alias from the underlying chunk backing index - Update Security Solution dev scripts, types and mocks to include the `@timestamp` property and ensure any mocks indexed use `op_type:create` --- .../fleet/common/constants/file_storage.ts | 14 +-- .../common/services/file_storage.test.ts | 25 +++- .../fleet/common/services/file_storage.ts | 28 ++--- .../epm/elasticsearch/template/install.ts | 66 ----------- .../services/epm/packages/_install_package.ts | 10 -- .../services/files/client_from_host.test.ts | 10 +- .../services/files/client_to_host.test.ts | 4 +- .../fleet/server/services/files/index.ts | 111 ++++++++++-------- .../fleet/server/services/files/mocks.ts | 2 +- .../fleet/server/services/setup.test.ts | 14 +-- x-pack/plugins/fleet/server/services/setup.ts | 39 +----- .../server/tasks/check_deleted_files_task.ts | 28 ++++- .../common/endpoint/types/actions.ts | 1 + .../endpoint/common/response_actions.ts | 5 +- .../scripts/endpoint/common/stack_services.ts | 2 +- .../server/endpoint/services/actions/mocks.ts | 1 + .../apis/agents/uploads.ts | 73 ++++++++---- .../apis/file_upload_index.ts | 34 ------ .../apis/index.ts | 1 - 19 files changed, 187 insertions(+), 281 deletions(-) delete mode 100644 x-pack/test/security_solution_endpoint_api_int/apis/file_upload_index.ts diff --git a/x-pack/plugins/fleet/common/constants/file_storage.ts b/x-pack/plugins/fleet/common/constants/file_storage.ts index 554176f40e263b..0d796d691b97bf 100644 --- a/x-pack/plugins/fleet/common/constants/file_storage.ts +++ b/x-pack/plugins/fleet/common/constants/file_storage.ts @@ -8,26 +8,26 @@ // File storage indexes supporting file upload from the host to Elastic/Kibana // If needing to get an integration specific index name, use the utility functions // found in `common/services/file_storage` -export const FILE_STORAGE_METADATA_INDEX_PATTERN = '.fleet-files-*'; -export const FILE_STORAGE_DATA_INDEX_PATTERN = '.fleet-file-data-*'; +export const FILE_STORAGE_METADATA_INDEX_PATTERN = '.fleet-fileds-fromhost-meta-*'; +export const FILE_STORAGE_DATA_INDEX_PATTERN = '.fleet-fileds-fromhost-data-*'; -// File storage indexes supporting user uplaoded files (via kibana) that will be +// File storage indexes supporting user uploaded files (via kibana) that will be // delivered to the host agent/endpoint -export const FILE_STORAGE_TO_HOST_METADATA_INDEX_PATTERN = '.fleet-filedelivery-meta-*'; -export const FILE_STORAGE_TO_HOST_DATA_INDEX_PATTERN = '.fleet-filedelivery-data-*'; +export const FILE_STORAGE_TO_HOST_METADATA_INDEX_PATTERN = '.fleet-fileds-tohost-meta-*'; +export const FILE_STORAGE_TO_HOST_DATA_INDEX_PATTERN = '.fleet-fileds-tohost-data-*'; // which integrations support file upload and the name to use for the file upload index export const FILE_STORAGE_INTEGRATION_INDEX_NAMES: Readonly< Record< string, - { + Readonly<{ /** name to be used for the index */ name: string; /** If integration supports files sent from host to ES/Kibana */ fromHost: boolean; /** If integration supports files to be sent to host from kibana */ toHost: boolean; - } + }> > > = { elastic_agent: { name: 'agent', fromHost: true, toHost: false }, diff --git a/x-pack/plugins/fleet/common/services/file_storage.test.ts b/x-pack/plugins/fleet/common/services/file_storage.test.ts index 0360d7311eb6ae..dbf5da61dba1db 100644 --- a/x-pack/plugins/fleet/common/services/file_storage.test.ts +++ b/x-pack/plugins/fleet/common/services/file_storage.test.ts @@ -5,24 +5,41 @@ * 2.0. */ +import { FILE_STORAGE_METADATA_INDEX_PATTERN } from '../constants'; + import { getFileDataIndexName, getFileMetadataIndexName } from '..'; +import { getIntegrationNameFromIndexName } from './file_storage'; + describe('File Storage services', () => { describe('File Index Names', () => { it('should generate file metadata index name for files received from host', () => { - expect(getFileMetadataIndexName('foo')).toEqual('.fleet-files-foo'); + expect(getFileMetadataIndexName('foo')).toEqual('.fleet-fileds-fromhost-meta-foo'); }); it('should generate file data index name for files received from host', () => { - expect(getFileDataIndexName('foo')).toEqual('.fleet-file-data-foo'); + expect(getFileDataIndexName('foo')).toEqual('.fleet-fileds-fromhost-data-foo'); }); it('should generate file metadata index name for files to be delivered to host', () => { - expect(getFileMetadataIndexName('foo', true)).toEqual('.fleet-filedelivery-meta-foo'); + expect(getFileMetadataIndexName('foo', true)).toEqual('.fleet-fileds-tohost-meta-foo'); }); it('should generate file data index name for files to be delivered to host', () => { - expect(getFileDataIndexName('foo', true)).toEqual('.fleet-filedelivery-data-foo'); + expect(getFileDataIndexName('foo', true)).toEqual('.fleet-fileds-tohost-data-foo'); + }); + }); + + describe('getIntegrationNameFromIndexName()', () => { + it.each([ + ['regular index names', '.fleet-fileds-fromhost-meta-agent'], + ['datastream index names', '.ds-.fleet-fileds-fromhost-data-agent-2023.06.30-00001'], + ])('should handle %s', (_, index) => { + expect(getIntegrationNameFromIndexName(index, FILE_STORAGE_METADATA_INDEX_PATTERN)).toEqual( + 'agent' + ); }); + + it.todo('should error if index pattern does not include `*`'); }); }); diff --git a/x-pack/plugins/fleet/common/services/file_storage.ts b/x-pack/plugins/fleet/common/services/file_storage.ts index 6581f671df6634..af909a22aa9461 100644 --- a/x-pack/plugins/fleet/common/services/file_storage.ts +++ b/x-pack/plugins/fleet/common/services/file_storage.ts @@ -56,21 +56,19 @@ export const getFileDataIndexName = ( ); }; -/** - * Returns the write index name for a given file upload alias name, this is the same for metadata and chunks - * @param aliasName - */ -export const getFileWriteIndexName = (aliasName: string) => aliasName + '-000001'; /** * Returns back the integration name for a given File Data (chunks) index name. * * @example - * // Given a File data index pattern of `.fleet-file-data-*`: + * // Given a File data index pattern of `.fleet-fileds-fromhost-data-*`: * - * getIntegrationNameFromFileDataIndexName('.fleet-file-data-agent'); + * getIntegrationNameFromFileDataIndexName('.fleet-fileds-fromhost-data-agent'); * // return 'agent' * - * getIntegrationNameFromFileDataIndexName('.fleet-file-data-agent-00001'); + * getIntegrationNameFromFileDataIndexName('.ds-.fleet-fileds-fromhost-data-agent'); + * // return 'agent' + * + * getIntegrationNameFromFileDataIndexName('.ds-.fleet-fileds-fromhost-data-agent-2023.06.30-00001'); * // return 'agent' */ export const getIntegrationNameFromFileDataIndexName = (indexName: string): string => { @@ -87,7 +85,7 @@ export const getIntegrationNameFromIndexName = ( throw new Error(`Unable to parse index name. No '*' in index pattern: ${indexPattern}`); } - const indexPieces = indexName.split('-'); + const indexPieces = indexName.replace(/^\.ds-/, '').split('-'); if (indexPieces[integrationNameIndexPosition]) { return indexPieces[integrationNameIndexPosition]; @@ -95,15 +93,3 @@ export const getIntegrationNameFromIndexName = ( throw new Error(`Index name ${indexName} does not seem to be a File storage index`); }; - -export const getFileStorageWriteIndexBody = (aliasName: string) => ({ - aliases: { - [aliasName]: { - is_write_index: true, - }, - }, - settings: { - 'index.lifecycle.rollover_alias': aliasName, - 'index.hidden': true, - }, -}); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index f5ef34d28b5c43..1780d3e55169a3 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -11,18 +11,9 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { IndicesCreateRequest } from '@elastic/elasticsearch/lib/api/types'; -import { - FILE_STORAGE_INTEGRATION_INDEX_NAMES, - FILE_STORAGE_INTEGRATION_NAMES, -} from '../../../../../common/constants'; - import { ElasticsearchAssetType } from '../../../../types'; import { - getFileWriteIndexName, - getFileStorageWriteIndexBody, getPipelineNameForDatastream, - getFileDataIndexName, - getFileMetadataIndexName, getRegistryDataStreamAssetBaseName, } from '../../../../../common/services'; import type { @@ -440,63 +431,6 @@ export async function ensureDefaultComponentTemplates( ); } -/* - * Given a list of integration names, if the integrations support file upload - * then ensure that the alias has a matching write index, as we use "plain" indices - * not data streams. - * e.g .fleet-file-data-agent must have .fleet-file-data-agent-00001 as the write index - * before files can be uploaded. - */ -export async function ensureFileUploadWriteIndices(opts: { - esClient: ElasticsearchClient; - logger: Logger; - integrationNames: string[]; -}) { - const { esClient, logger, integrationNames } = opts; - - const integrationsWithFileUpload = integrationNames.filter((integration) => - FILE_STORAGE_INTEGRATION_NAMES.includes(integration as any) - ); - - if (!integrationsWithFileUpload.length) return []; - - const ensure = (aliasName: string) => - ensureAliasHasWriteIndex({ - esClient, - logger, - aliasName, - writeIndexName: getFileWriteIndexName(aliasName), - body: getFileStorageWriteIndexBody(aliasName), - }); - - return Promise.all( - integrationsWithFileUpload.flatMap((integrationName) => { - const { - name: indexName, - fromHost, - toHost, - } = FILE_STORAGE_INTEGRATION_INDEX_NAMES[integrationName]; - const indexCreateRequests: Array> = []; - - if (fromHost) { - indexCreateRequests.push( - ensure(getFileDataIndexName(indexName)), - ensure(getFileMetadataIndexName(indexName)) - ); - } - - if (toHost) { - indexCreateRequests.push( - ensure(getFileDataIndexName(indexName, true)), - ensure(getFileMetadataIndexName(indexName, true)) - ); - } - - return indexCreateRequests; - }) - ); -} - export async function ensureComponentTemplate( esClient: ElasticsearchClient, logger: Logger, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index b884e8c893de84..a5b4ad6f4e00b5 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -37,7 +37,6 @@ import type { PackageVerificationResult, IndexTemplateEntry, } from '../../../types'; -import { ensureFileUploadWriteIndices } from '../elasticsearch/template/install'; import { removeLegacyTemplates } from '../elasticsearch/template/remove_legacy'; import { isTopLevelPipeline, deletePreviousPipelines } from '../elasticsearch/ingest_pipeline'; import { installILMPolicy } from '../elasticsearch/ilm/install'; @@ -236,15 +235,6 @@ export async function _installPackage({ logger.warn(`Error removing legacy templates: ${e.message}`); } - const { diagnosticFileUploadEnabled } = appContextService.getExperimentalFeatures(); - if (diagnosticFileUploadEnabled) { - await ensureFileUploadWriteIndices({ - integrationNames: [packageInfo.name], - esClient, - logger, - }); - } - // update current backing indices of each data stream await withPackageSpan('Update write indices', () => updateCurrentWriteIndices(esClient, logger, indexTemplates) diff --git a/x-pack/plugins/fleet/server/services/files/client_from_host.test.ts b/x-pack/plugins/fleet/server/services/files/client_from_host.test.ts index 068bad018b5e8f..0051418b1c00d3 100644 --- a/x-pack/plugins/fleet/server/services/files/client_from_host.test.ts +++ b/x-pack/plugins/fleet/server/services/files/client_from_host.test.ts @@ -91,11 +91,11 @@ describe('FleetFromHostFilesClient', () => { esClientMock.search.mockImplementation(async (searchRequest = {}) => { // File metadata - if ((searchRequest.index as string).startsWith('.fleet-files-')) { + if ((searchRequest.index as string).startsWith('.fleet-fileds-fromhost-meta-')) { return fleetFilesIndexSearchResponse; } - if ((searchRequest.index as string).startsWith('.fleet-file-data-')) { + if ((searchRequest.index as string).startsWith('.fleet-fileds-fromhost-data-')) { return fleetFileDataIndexSearchResponse; } @@ -111,8 +111,8 @@ describe('FleetFromHostFilesClient', () => { expect(createEsFileClientMock).toHaveBeenCalledWith({ elasticsearchClient: esClientMock, logger: loggerMock, - metadataIndex: '.fleet-files-foo', - blobStorageIndex: '.fleet-file-data-foo', + metadataIndex: '.fleet-fileds-fromhost-meta-foo', + blobStorageIndex: '.fleet-fileds-fromhost-data-foo', indexIsAlias: true, }); }); @@ -159,7 +159,7 @@ describe('FleetFromHostFilesClient', () => { }, }, }, - index: '.fleet-file-data-foo', + index: '.fleet-fileds-fromhost-data-foo', size: 0, }); }); diff --git a/x-pack/plugins/fleet/server/services/files/client_to_host.test.ts b/x-pack/plugins/fleet/server/services/files/client_to_host.test.ts index a4820f256da955..1068f34366970d 100644 --- a/x-pack/plugins/fleet/server/services/files/client_to_host.test.ts +++ b/x-pack/plugins/fleet/server/services/files/client_to_host.test.ts @@ -130,8 +130,8 @@ describe('FleetToHostFilesClient', () => { expect(createEsFileClientMock).toHaveBeenCalledWith({ elasticsearchClient: esClientMock, logger: loggerMock, - metadataIndex: '.fleet-filedelivery-meta-foo', - blobStorageIndex: '.fleet-filedelivery-data-foo', + metadataIndex: '.fleet-fileds-tohost-meta-foo', + blobStorageIndex: '.fleet-fileds-tohost-data-foo', maxSizeBytes: 12345, indexIsAlias: true, }); diff --git a/x-pack/plugins/fleet/server/services/files/index.ts b/x-pack/plugins/fleet/server/services/files/index.ts index 5790164b81d074..8d6cbdb9fd5a43 100644 --- a/x-pack/plugins/fleet/server/services/files/index.ts +++ b/x-pack/plugins/fleet/server/services/files/index.ts @@ -34,22 +34,27 @@ export async function getFilesByStatus( abortController: AbortController, status: FileStatus = 'READY' ): Promise { - const result = await esClient.search( - { - index: FILE_STORAGE_METADATA_INDEX_PATTERN, - body: { - size: ES_SEARCH_LIMIT, - query: { - term: { - 'file.Status': status, + const result = await esClient + .search( + { + index: FILE_STORAGE_METADATA_INDEX_PATTERN, + body: { + size: ES_SEARCH_LIMIT, + query: { + term: { + 'file.Status': status, + }, }, + _source: false, }, - _source: false, + ignore_unavailable: true, }, - ignore_unavailable: true, - }, - { signal: abortController.signal } - ); + { signal: abortController.signal } + ) + .catch((err) => { + Error.captureStackTrace(err); + throw err; + }); return result.hits.hits; } @@ -84,32 +89,37 @@ export async function fileIdsWithoutChunksByIndex( return acc; }, {} as FileIdsByIndex); - const chunks = await esClient.search<{ bid: string }>( - { - index: FILE_STORAGE_DATA_INDEX_PATTERN, - body: { - size: ES_SEARCH_LIMIT, - query: { - bool: { - must: [ - { - terms: { - bid: Array.from(allFileIds), + const chunks = await esClient + .search<{ bid: string }>( + { + index: FILE_STORAGE_DATA_INDEX_PATTERN, + body: { + size: ES_SEARCH_LIMIT, + query: { + bool: { + must: [ + { + terms: { + bid: Array.from(allFileIds), + }, }, - }, - { - term: { - last: true, + { + term: { + last: true, + }, }, - }, - ], + ], + }, }, + _source: ['bid'], }, - _source: ['bid'], }, - }, - { signal: abortController.signal } - ); + { signal: abortController.signal } + ) + .catch((err) => { + Error.captureStackTrace(err); + throw err; + }); chunks.hits.hits.forEach((hit) => { const fileId = hit._source?.bid; @@ -140,22 +150,27 @@ export function updateFilesStatus( ): Promise { return Promise.all( Object.entries(fileIdsByIndex).map(([index, fileIds]) => { - return esClient.updateByQuery( - { - index, - refresh: true, - query: { - ids: { - values: Array.from(fileIds), + return esClient + .updateByQuery( + { + index, + refresh: true, + query: { + ids: { + values: Array.from(fileIds), + }, + }, + script: { + source: `ctx._source.file.Status = '${status}'`, + lang: 'painless', }, }, - script: { - source: `ctx._source.file.Status = '${status}'`, - lang: 'painless', - }, - }, - { signal: abortController.signal } - ); + { signal: abortController.signal } + ) + .catch((err) => { + Error.captureStackTrace(err); + throw err; + }); }) ); } diff --git a/x-pack/plugins/fleet/server/services/files/mocks.ts b/x-pack/plugins/fleet/server/services/files/mocks.ts index 35c276bf5cae76..23c0482b7e1110 100644 --- a/x-pack/plugins/fleet/server/services/files/mocks.ts +++ b/x-pack/plugins/fleet/server/services/files/mocks.ts @@ -86,7 +86,7 @@ export const createFromHostEsSearchResponseMock = max_score: 0, hits: [ { - _index: '.fleet-files-foo-000001', + _index: '.fleet-fileds-fromhost-meta-foo-000001', _id: '123', _score: 1.0, _source: { diff --git a/x-pack/plugins/fleet/server/services/setup.test.ts b/x-pack/plugins/fleet/server/services/setup.test.ts index 7d98db879910b2..15dccb15053ab2 100644 --- a/x-pack/plugins/fleet/server/services/setup.test.ts +++ b/x-pack/plugins/fleet/server/services/setup.test.ts @@ -15,9 +15,7 @@ import { ensurePreconfiguredPackagesAndPolicies } from '.'; import { appContextService } from './app_context'; import { getInstallations } from './epm/packages'; import { upgradeManagedPackagePolicies } from './managed_package_policies'; -import { setupFleet, ensureFleetFileUploadIndices } from './setup'; - -import { ensureFileUploadWriteIndices } from './epm/elasticsearch/template/install'; +import { setupFleet } from './setup'; jest.mock('./preconfiguration'); jest.mock('./preconfiguration/outputs'); @@ -70,8 +68,6 @@ describe('setupFleet', () => { soClient.find.mockResolvedValue({ saved_objects: [] } as any); soClient.bulkGet.mockResolvedValue({ saved_objects: [] } as any); - - (ensureFileUploadWriteIndices as jest.Mock).mockResolvedValue({}); }); afterEach(async () => { @@ -138,12 +134,4 @@ describe('setupFleet', () => { ], }); }); - - it('should create agent file upload write indices', async () => { - await ensureFleetFileUploadIndices(soClient, esClient); - - expect((ensureFileUploadWriteIndices as jest.Mock).mock.calls[0][0].integrationNames).toEqual([ - 'elastic_agent', - ]); - }); }); diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 90b76b8495e398..92d8f8fb37ddaa 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -12,11 +12,7 @@ import pMap from 'p-map'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants'; -import { - AUTO_UPDATE_PACKAGES, - FILE_STORAGE_INTEGRATION_NAMES, - FLEET_ELASTIC_AGENT_PACKAGE, -} from '../../common/constants'; +import { AUTO_UPDATE_PACKAGES } from '../../common/constants'; import type { PreconfigurationError } from '../../common/constants'; import type { DefaultPackagesInstallationError, @@ -44,10 +40,7 @@ import { ensureDefaultEnrollmentAPIKeyForAgentPolicy } from './api_keys'; import { getRegistryUrl, settingsService } from '.'; import { awaitIfPending } from './setup_utils'; import { ensureFleetFinalPipelineIsInstalled } from './epm/elasticsearch/ingest_pipeline/install'; -import { - ensureDefaultComponentTemplates, - ensureFileUploadWriteIndices, -} from './epm/elasticsearch/template/install'; +import { ensureDefaultComponentTemplates } from './epm/elasticsearch/template/install'; import { getInstallations, reinstallPackageForInstallation } from './epm/packages'; import { isPackageInstalled } from './epm/packages/install'; import type { UpgradeManagedPackagePoliciesResult } from './managed_package_policies'; @@ -60,7 +53,6 @@ import { ensurePreconfiguredFleetServerHosts, getPreconfiguredFleetServerHostFromConfig, } from './preconfiguration/fleet_server_host'; -import { getInstallationsByName } from './epm/packages/get'; export interface SetupStatus { isInitialized: boolean; @@ -125,7 +117,6 @@ async function createSetupSideEffects( logger.debug('Setting up Fleet Elasticsearch assets'); await ensureFleetGlobalEsAssets(soClient, esClient); - await ensureFleetFileUploadIndices(soClient, esClient); // Ensure that required packages are always installed even if they're left out of the config const preconfiguredPackageNames = new Set(packages.map((pkg) => pkg.name)); @@ -207,32 +198,6 @@ async function createSetupSideEffects( }; } -/** - * Ensure ES assets shared by all Fleet index template are installed - */ -export async function ensureFleetFileUploadIndices( - soClient: SavedObjectsClientContract, - esClient: ElasticsearchClient -) { - const { diagnosticFileUploadEnabled } = appContextService.getExperimentalFeatures(); - if (!diagnosticFileUploadEnabled) return; - const logger = appContextService.getLogger(); - const installedFileUploadIntegrations = await getInstallationsByName({ - savedObjectsClient: soClient, - pkgNames: [...FILE_STORAGE_INTEGRATION_NAMES], - }); - - const integrationNames = installedFileUploadIntegrations.map(({ name }) => name); - if (!integrationNames.includes(FLEET_ELASTIC_AGENT_PACKAGE)) { - integrationNames.push(FLEET_ELASTIC_AGENT_PACKAGE); - } - logger.debug(`Ensuring file upload write indices for ${integrationNames}`); - return ensureFileUploadWriteIndices({ - esClient, - logger, - integrationNames, - }); -} /** * Ensure ES assets shared by all Fleet index template are installed */ diff --git a/x-pack/plugins/fleet/server/tasks/check_deleted_files_task.ts b/x-pack/plugins/fleet/server/tasks/check_deleted_files_task.ts index b7ebdd0748e9de..a7611d73cd313b 100644 --- a/x-pack/plugins/fleet/server/tasks/check_deleted_files_task.ts +++ b/x-pack/plugins/fleet/server/tasks/check_deleted_files_task.ts @@ -72,6 +72,7 @@ export class CheckDeletedFilesTask { } this.wasStarted = true; + this.logger.info(`Started with interval of [${INTERVAL}] and timeout of [${TIMEOUT}]`); try { await taskManager.ensureScheduled({ @@ -85,7 +86,7 @@ export class CheckDeletedFilesTask { params: { version: VERSION }, }); } catch (e) { - this.logger.error(`Error scheduling task, received error: ${e}`); + this.logger.error(`Error scheduling task, received error: ${e.message}`, e); } }; @@ -104,19 +105,34 @@ export class CheckDeletedFilesTask { throwUnrecoverableError(new Error('Outdated task version')); } + this.logger.info(`[runTask()] started`); + + const endRun = (msg: string = '') => { + this.logger.info(`[runTask()] ended${msg ? ': ' + msg : ''}`); + }; + const [{ elasticsearch }] = await core.getStartServices(); const esClient = elasticsearch.client.asInternalUser; try { const readyFiles = await getFilesByStatus(esClient, this.abortController); - if (!readyFiles.length) return; + + if (!readyFiles.length) { + endRun('no files to process'); + return; + } const { fileIdsByIndex: deletedFileIdsByIndex, allFileIds: allDeletedFileIds } = await fileIdsWithoutChunksByIndex(esClient, this.abortController, readyFiles); - if (!allDeletedFileIds.size) return; + + if (!allDeletedFileIds.size) { + endRun('No files with deleted chunks'); + return; + } this.logger.info(`Attempting to update ${allDeletedFileIds.size} files to DELETED status`); - this.logger.debug(`Attempting to file ids: ${deletedFileIdsByIndex}`); + this.logger.debug(`Attempting to update file ids: ${deletedFileIdsByIndex}`); + const updatedFilesResponses = await updateFilesStatus( esClient, this.abortController, @@ -130,12 +146,16 @@ export class CheckDeletedFilesTask { this.logger.warn(`Failed to update ${failures.length} files to DELETED status`); this.logger.debug(`Failed to update files to DELETED status: ${failures}`); } + + endRun('success'); } catch (err) { if (err instanceof errors.RequestAbortedError) { this.logger.warn(`request aborted due to timeout: ${err}`); + endRun(); return; } this.logger.error(err); + endRun('error'); } }; } diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index fe1b22644d8e11..1d7a69186421fb 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -466,6 +466,7 @@ export interface FileUploadMetadata { transithash: { sha256: string; }; + '@timestamp': string; } export type UploadedFileInfo = Pick< diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/response_actions.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/response_actions.ts index f8c3aad63f4e2d..8a5c77c2a61b06 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/response_actions.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/response_actions.ts @@ -209,8 +209,9 @@ export const sendEndpointActionResponse = async ( const fileMeta = await esClient.index({ index: FILE_STORAGE_METADATA_INDEX, id: getFileDownloadId(action, action.agents[0]), - body: fileMetaDoc, + op_type: 'create', refresh: 'wait_for', + body: fileMetaDoc, }); // Index the file content (just one chunk) @@ -224,12 +225,14 @@ export const sendEndpointActionResponse = async ( document: cborx.encode({ bid: fileMeta._id, last: true, + '@timestamp': new Date().toISOString(), data: Buffer.from( 'UEsDBAoACQAAAFZeRFWpAsDLHwAAABMAAAAMABwAYmFkX2ZpbGUudHh0VVQJAANTVjxjU1Y8Y3V4CwABBPUBAAAEFAAAAMOcoyEq/Q4VyG02U9O0LRbGlwP/y5SOCfRKqLz1rsBQSwcIqQLAyx8AAAATAAAAUEsBAh4DCgAJAAAAVl5EVakCwMsfAAAAEwAAAAwAGAAAAAAAAQAAAKSBAAAAAGJhZF9maWxlLnR4dFVUBQADU1Y8Y3V4CwABBPUBAAAEFAAAAFBLBQYAAAAAAQABAFIAAAB1AAAAAAA=', 'base64' ), }), refresh: 'wait_for', + op_type: 'create', }, { headers: { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts index 434df1b209a199..e38725e5d5e6e5 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts @@ -44,7 +44,7 @@ export interface RuntimeServices { interface CreateRuntimeServicesOptions { kibanaUrl: string; elasticsearchUrl: string; - fleetServerUrl: string | undefined; + fleetServerUrl?: string; username: string; password: string; log?: ToolingLog; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/mocks.ts index d1818b9b494e79..a4536f54b92d73 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/mocks.ts @@ -214,6 +214,7 @@ export const generateFileMetadataDocumentMock = ( transithash: { sha256: 'a0d6d6a2bb73340d4a0ed32b2a46272a19dd111427770c072918aed7a8565010', }, + '@timestamp': new Date().toISOString(), ...overrides, }; diff --git a/x-pack/test/fleet_api_integration/apis/agents/uploads.ts b/x-pack/test/fleet_api_integration/apis/agents/uploads.ts index 6f548d3d955d06..174d511674ef68 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/uploads.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/uploads.ts @@ -23,6 +23,25 @@ export default function (providerContext: FtrProviderContext) { const ES_INDEX_OPTIONS = { headers: { 'X-elastic-product-origin': 'fleet' } }; + const cleanupFiles = async () => { + await esClient.deleteByQuery({ + index: `${FILE_STORAGE_DATA_AGENT_INDEX},${FILE_STORAGE_METADATA_AGENT_INDEX}`, + refresh: true, + ignore_unavailable: true, + query: { + bool: { + filter: [ + { + ids: { + values: ['file1', 'file1.0'], + }, + }, + ], + }, + }, + }); + }; + describe('fleet_uploads', () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); @@ -30,6 +49,7 @@ export default function (providerContext: FtrProviderContext) { before(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); await getService('supertest').post(`/api/fleet/setup`).set('kbn-xsrf', 'xxx').send(); + await cleanupFiles(); await esClient.create({ index: AGENT_ACTIONS_INDEX, @@ -60,34 +80,36 @@ export default function (providerContext: FtrProviderContext) { ES_INDEX_OPTIONS ); - await esClient.update({ + await esClient.index({ index: FILE_STORAGE_METADATA_AGENT_INDEX, id: 'file1', refresh: true, + op_type: 'create', body: { - doc_as_upsert: true, - doc: { - upload_id: 'file1', - action_id: 'action1', - agent_id: 'agent1', - file: { - ChunkSize: 4194304, - extension: 'zip', - hash: {}, - mime_type: 'application/zip', - mode: '0644', - name: 'elastic-agent-diagnostics-2022-10-07T12-00-00Z-00.zip', - path: '/agent/elastic-agent-diagnostics-2022-10-07T12-00-00Z-00.zip', - size: 24917, - Status: 'READY', - type: 'file', - }, + '@timestamp': new Date().toISOString(), + upload_id: 'file1', + action_id: 'action1', + agent_id: 'agent1', + file: { + ChunkSize: 4194304, + extension: 'zip', + hash: {}, + mime_type: 'application/zip', + mode: '0644', + name: 'elastic-agent-diagnostics-2022-10-07T12-00-00Z-00.zip', + path: '/agent/elastic-agent-diagnostics-2022-10-07T12-00-00Z-00.zip', + size: 24917, + Status: 'READY', + type: 'file', }, }, }); }); after(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); + await Promise.all([ + esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server'), + cleanupFiles(), + ]); }); it('should get agent uploads', async () => { @@ -108,17 +130,16 @@ export default function (providerContext: FtrProviderContext) { }); it('should get agent uploaded file', async () => { - await esClient.update({ + await esClient.index({ index: FILE_STORAGE_DATA_AGENT_INDEX, id: 'file1.0', + op_type: 'create', refresh: true, body: { - doc_as_upsert: true, - doc: { - last: true, - bid: 'file1', - data: 'test', - }, + '@timestamp': new Date().toISOString(), + last: true, + bid: 'file1', + data: 'test', }, }); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/file_upload_index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/file_upload_index.ts deleted file mode 100644 index ce8179a050c47d..00000000000000 --- a/x-pack/test/security_solution_endpoint_api_int/apis/file_upload_index.ts +++ /dev/null @@ -1,34 +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 expect from '@kbn/expect'; -import { - FILE_STORAGE_DATA_INDEX, - FILE_STORAGE_METADATA_INDEX, -} from '@kbn/security-solution-plugin/common/endpoint/constants'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService }: FtrProviderContext) { - const esClient = getService('es'); - - describe('File upload indices', () => { - it('should have created the file data index on install', async () => { - const endpointFileUploadIndexExists = await esClient.indices.exists({ - index: FILE_STORAGE_METADATA_INDEX, - }); - - expect(endpointFileUploadIndexExists).equal(true); - }); - it('should have created the files index on install', async () => { - const endpointFileUploadIndexExists = await esClient.indices.exists({ - index: FILE_STORAGE_DATA_INDEX, - }); - - expect(endpointFileUploadIndexExists).equal(true); - }); - }); -} diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts index fbd33d38d1a945..e68db8182da208 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts @@ -48,7 +48,6 @@ export default function endpointAPIIntegrationTests(providerContext: FtrProvider loadTestFile(require.resolve('./package')); loadTestFile(require.resolve('./endpoint_authz')); loadTestFile(require.resolve('./endpoint_response_actions/execute')); - loadTestFile(require.resolve('./file_upload_index')); loadTestFile(require.resolve('./endpoint_artifacts/trusted_apps')); loadTestFile(require.resolve('./endpoint_artifacts/event_filters')); loadTestFile(require.resolve('./endpoint_artifacts/host_isolation_exceptions')); From b697c1d6519848994186df332dc2c7392b27d01a Mon Sep 17 00:00:00 2001 From: Dmitrii Shevchenko Date: Mon, 3 Jul 2023 16:15:08 +0200 Subject: [PATCH 24/98] [Security Solution] Added changelog links to the rules install and update pages (#161015) ## Summary Added links to documentation with the prebuilt rules package changelog from the Add and Update rules pages. **Add rules page:** ![image](https://github.com/elastic/kibana/assets/1938181/bbe89be9-277a-4047-8981-2261cd4ee9a1) **Update rules page:** ![image](https://github.com/elastic/kibana/assets/1938181/3d369efa-98d9-476d-9964-349c47482385) **The link leads to the following documentation page:** ![image](https://github.com/elastic/kibana/assets/1938181/0db7f188-2947-494e-96f0-07cf4d5e60b9) --- .../add_prebuilt_rules_table.tsx | 12 ++++++++- .../rules_table/rules_changelog_link.tsx | 27 +++++++++++++++++++ .../upgrade_prebuilt_rules_table.tsx | 21 ++++++++++++--- .../detection_engine/rules/translations.ts | 7 +++++ 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_changelog_link.tsx 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.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.tsx index 7c8b397f1baddf..d956b2167bc8ba 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.tsx @@ -11,10 +11,13 @@ import { EuiProgress, EuiSkeletonTitle, EuiSkeletonText, + EuiFlexGroup, + EuiFlexItem, } from '@elastic/eui'; import React from 'react'; import { RULES_TABLE_INITIAL_PAGE_SIZE, RULES_TABLE_PAGE_SIZE_OPTIONS } from '../constants'; +import { RulesChangelogLink } from '../rules_changelog_link'; import { AddPrebuiltRulesTableNoItemsMessage } from './add_prebuilt_rules_no_items_message'; import { useAddPrebuiltRulesTableContext } from './add_prebuilt_rules_table_context'; import { AddPrebuiltRulesTableFilters } from './add_prebuilt_rules_table_filters'; @@ -67,7 +70,14 @@ export const AddPrebuiltRulesTable = React.memo(() => { ) : ( <> - + + + + + + + + { + const { docLinks } = useKibana().services; + + return ( + + {i18n.RULE_UPDATES_DOCUMENTATION_LINK} + + ); +}); + +RulesChangelogLink.displayName = 'RulesChangelogLink'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx index b7848eb5379e71..2c1eee1bf08b2b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx @@ -18,6 +18,7 @@ import { import React from 'react'; import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; import { RULES_TABLE_INITIAL_PAGE_SIZE, RULES_TABLE_PAGE_SIZE_OPTIONS } from '../constants'; +import { RulesChangelogLink } from '../rules_changelog_link'; import { UpgradePrebuiltRulesTableButtons } from './upgrade_prebuilt_rules_table_buttons'; import { useUpgradePrebuiltRulesTableContext } from './upgrade_prebuilt_rules_table_context'; import { UpgradePrebuiltRulesTableFilters } from './upgrade_prebuilt_rules_table_filters'; @@ -78,12 +79,24 @@ export const UpgradePrebuiltRulesTable = React.memo(() => { NO_ITEMS_MESSAGE ) : ( <> - - - + + + - + + + + + + + + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts index 9bce60e23ae795..cbe9390b510eed 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts @@ -1218,3 +1218,10 @@ export const GO_BACK_TO_RULES_TABLE_BUTTON = i18n.translate( defaultMessage: 'Go back to installed Elastic rules', } ); + +export const RULE_UPDATES_DOCUMENTATION_LINK = i18n.translate( + 'xpack.securitySolution.ruleUpdates.documentationLink', + { + defaultMessage: "See what's new in Prebuilt Security Detection Rules", + } +); From 1d82d2cb612483e96793d3b53669e19438bce28f Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Mon, 3 Jul 2023 09:16:47 -0500 Subject: [PATCH 25/98] [Event annotations] Lens design improvements (#159057) --- .../common/content_management/v1/types.ts | 5 +- ...t_annotation_group_saved_object_finder.tsx | 56 ++-- .../event_annotation_service/service.tsx | 39 ++- .../public/event_annotation_service/types.ts | 1 + .../event_annotation_group_storage.ts | 2 + .../saved_object_save_modal.test.tsx.snap | 288 +++++++++--------- .../save_modal/saved_object_save_modal.tsx | 45 ++- .../layer_actions/layer_actions.tsx | 6 +- .../layer_actions/remove_layer_action.tsx | 55 ++-- .../editor_frame/config_panel/layer_panel.tsx | 5 +- .../shared_components/static_header.tsx | 10 +- x-pack/plugins/lens/public/types.ts | 9 + .../annotations/actions/save_action.test.tsx | 80 ++++- .../xy/annotations/actions/save_action.tsx | 85 ++++-- .../visualizations/xy/annotations/helpers.tsx | 11 - .../xy/load_annotation_library_flyout.tsx | 1 + .../visualizations/xy/visualization.test.tsx | 50 ++- .../visualizations/xy/visualization.tsx | 9 + .../xy/visualization_helpers.tsx | 2 +- .../xy/xy_config_panel/layer_header.tsx | 22 +- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 23 files changed, 501 insertions(+), 286 deletions(-) diff --git a/src/plugins/event_annotation/common/content_management/v1/types.ts b/src/plugins/event_annotation/common/content_management/v1/types.ts index a5c23061008215..d3370b9ff28bf9 100644 --- a/src/plugins/event_annotation/common/content_management/v1/types.ts +++ b/src/plugins/event_annotation/common/content_management/v1/types.ts @@ -120,6 +120,9 @@ export interface EventAnnotationGroupSearchQuery { searchFields?: string[]; } -export type EventAnnotationGroupSearchIn = SearchIn; +export type EventAnnotationGroupSearchIn = SearchIn< + EventAnnotationGroupContentType, + EventAnnotationGroupSearchQuery +>; export type EventAnnotationGroupSearchOut = SearchResult; diff --git a/src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx b/src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx index 34b1ce7eb06945..72f931797d3c4f 100644 --- a/src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx +++ b/src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx @@ -67,35 +67,37 @@ export const EventAnnotationGroupSavedObjectFinder = ({ direction="column" justifyContent="center" > - - - - } - body={ - -

+ + -

-
- } - actions={ - onCreateNew()} size="s"> - - - } - /> + + } + body={ + +

+ +

+
+ } + actions={ + onCreateNew()} size="s"> + + + } + /> +
) : ( => { const savedObject = await client.get({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, id: savedObjectId, }); @@ -117,6 +118,29 @@ export function getEventAnnotationService( return mapSavedObjectToGroupConfig(savedObject.item); }; + const groupExistsWithTitle = async (title: string): Promise => { + const { hits } = await client.search< + EventAnnotationGroupSearchIn, + EventAnnotationGroupSearchOut + >({ + contentTypeId: CONTENT_ID, + query: { + text: title, + }, + options: { + searchFields: ['title'], + }, + }); + + for (const hit of hits) { + if (hit.attributes.title.toLowerCase() === title.toLowerCase()) { + return true; + } + } + + return false; + }; + const findAnnotationGroupContent = async ( searchTerm: string, pageSize: number, @@ -138,7 +162,7 @@ export function getEventAnnotationService( EventAnnotationGroupSearchIn, EventAnnotationGroupSearchOut >({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, query: { text: searchOptions.search, }, @@ -153,7 +177,7 @@ export function getEventAnnotationService( const deleteAnnotationGroups = async (ids: string[]): Promise => { for (const id of ids) { await client.delete({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, id, }); } @@ -223,7 +247,7 @@ export function getEventAnnotationService( const groupSavedObjectId = ( await client.create({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, data: { ...attributes, }, @@ -243,7 +267,7 @@ export function getEventAnnotationService( const { attributes, references } = getAnnotationGroupAttributesAndReferences(group); await client.update({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, id: annotationGroupId, data: { ...attributes, @@ -259,7 +283,7 @@ export function getEventAnnotationService( EventAnnotationGroupSearchIn, EventAnnotationGroupSearchOut >({ - contentTypeId: EVENT_ANNOTATION_GROUP_TYPE, + contentTypeId: CONTENT_ID, query: { text: '*', }, @@ -270,6 +294,7 @@ export function getEventAnnotationService( return { loadAnnotationGroup, + groupExistsWithTitle, updateAnnotationGroup, createAnnotationGroup, deleteAnnotationGroups, diff --git a/src/plugins/event_annotation/public/event_annotation_service/types.ts b/src/plugins/event_annotation/public/event_annotation_service/types.ts index 8742ea86afff8c..8837792954b512 100644 --- a/src/plugins/event_annotation/public/event_annotation_service/types.ts +++ b/src/plugins/event_annotation/public/event_annotation_service/types.ts @@ -14,6 +14,7 @@ import { EventAnnotationConfig, EventAnnotationGroupConfig } from '../../common' export interface EventAnnotationServiceType { loadAnnotationGroup: (savedObjectId: string) => Promise; + groupExistsWithTitle: (title: string) => Promise; findAnnotationGroupContent: ( searchTerm: string, pageSize: number, diff --git a/src/plugins/event_annotation/server/content_management/event_annotation_group_storage.ts b/src/plugins/event_annotation/server/content_management/event_annotation_group_storage.ts index ce032374e7b535..5755a7efe998f6 100644 --- a/src/plugins/event_annotation/server/content_management/event_annotation_group_storage.ts +++ b/src/plugins/event_annotation/server/content_management/event_annotation_group_storage.ts @@ -268,9 +268,11 @@ export class EventAnnotationGroupStorage EventAnnotationGroupSearchQuery, EventAnnotationGroupSearchQuery >(options); + if (optionsError) { throw Boom.badRequest(`Invalid payload. ${optionsError.message}`); } + const { searchFields = ['title^3', 'description'], types = [SO_TYPE] } = optionsToLatest; const { included, excluded } = query.tags ?? {}; diff --git a/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap b/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap index 70ba2d5619d032..e42ac60f9ba895 100644 --- a/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap +++ b/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap @@ -28,9 +28,11 @@ exports[`SavedObjectSaveModal should render matching snapshot 1`] = ` - - - + - - - - Save - + + + + + + + + Save + + + `; @@ -154,9 +154,11 @@ exports[`SavedObjectSaveModal should render matching snapshot when custom isVali - - - + - - - - Save - + + + + + + + + Save + + + `; @@ -280,9 +280,11 @@ exports[`SavedObjectSaveModal should render matching snapshot when custom isVali - - - + - - - - Save - + + + + + + + + Save + + + `; @@ -410,9 +410,11 @@ exports[`SavedObjectSaveModal should render matching snapshot when given options - - - + - - - - Save - + + + + + + + + Save + + + `; diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx index c471271ead7edc..b9bd5e5d7fe362 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx @@ -30,7 +30,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { css } from '@emotion/react'; export interface OnSaveProps { newTitle: string; @@ -93,11 +92,19 @@ export class SavedObjectSaveModal extends React.Component const hasColumns = !!this.props.rightOptions; + const titleInputValid = + hasAttemptedSubmit && + ((!isTitleDuplicateConfirmed && hasTitleDuplicate) || title.length === 0); + const formBodyContent = ( <> } + isInvalid={titleInputValid} + error={i18n.translate('savedObjects.saveModal.titleRequired', { + defaultMessage: 'A title is required', + })} > data-test-subj="savedObjectTitle" value={title} onChange={this.onTitleChange} - isInvalid={ - hasAttemptedSubmit && - ((!isTitleDuplicateConfirmed && hasTitleDuplicate) || title.length === 0) - } + isInvalid={titleInputValid} aria-describedby={this.state.hasTitleDuplicate ? duplicateWarningId : undefined} /> @@ -167,20 +171,19 @@ export class SavedObjectSaveModal extends React.Component - - {this.renderCopyOnSave()} - - - - - {this.renderConfirmButton()} + + + {this.props.showCopyOnSave && {this.renderCopyOnSave()}} + + + + + + {this.renderConfirmButton()} + ); @@ -351,10 +354,6 @@ export class SavedObjectSaveModal extends React.Component }; private renderCopyOnSave = () => { - if (!this.props.showCopyOnSave) { - return; - } - return ( void; onCloneLayer: () => void; @@ -54,12 +55,12 @@ export const getSharedActions = ({ layerId: string; isOnlyLayer: boolean; activeVisualization: Visualization; - visualizationState: unknown; layerType?: LayerType; isTextBasedLanguage?: boolean; hasLayerSettings: boolean; openLayerSettings: () => void; core: Pick; + customRemoveModalText?: { title?: string; description?: string }; }) => [ getOpenLayerSettingsAction({ hasLayerSettings, @@ -77,6 +78,7 @@ export const getSharedActions = ({ layerType, isOnlyLayer, core, + customModalText: customRemoveModalText, }), ]; @@ -189,7 +191,7 @@ export const LayerActions = (props: LayerActionsProps) => { ; + customModalText?: { title?: string; description?: string }; } const SKIP_DELETE_MODAL_KEY = 'skipDeleteModal'; const getCopy = ( layerType: LayerType, - isOnlyLayer?: boolean + isOnlyLayer?: boolean, + customModalText: { title?: string; description?: string } | undefined = undefined ): { buttonLabel: string; modalTitle: string; modalBody: string } => { if (isOnlyLayer && layerType === 'data') { return { @@ -64,34 +66,46 @@ const getCopy = ( case 'data': return { buttonLabel, - modalTitle: i18n.translate('xpack.lens.modalTitle.title.deleteVis', { - defaultMessage: 'Delete visualization layer?', - }), - modalBody: i18n.translate('xpack.lens.layer.confirmModal.deleteVis', { - defaultMessage: `Deleting this layer removes the visualization and its configurations. `, - }), + modalTitle: + customModalText?.title ?? + i18n.translate('xpack.lens.modalTitle.title.deleteVis', { + defaultMessage: 'Delete visualization layer?', + }), + modalBody: + customModalText?.description ?? + i18n.translate('xpack.lens.layer.confirmModal.deleteVis', { + defaultMessage: `Deleting this layer removes the visualization and its configurations. `, + }), }; case 'annotations': return { buttonLabel, - modalTitle: i18n.translate('xpack.lens.modalTitle.title.deleteAnnotations', { - defaultMessage: 'Delete annotations layer?', - }), - modalBody: i18n.translate('xpack.lens.layer.confirmModal.deleteAnnotation', { - defaultMessage: `Deleting this layer removes the annotations and their configurations. `, - }), + modalTitle: + customModalText?.title ?? + i18n.translate('xpack.lens.modalTitle.title.deleteAnnotations', { + defaultMessage: 'Delete annotation group?', + }), + modalBody: + customModalText?.description ?? + i18n.translate('xpack.lens.layer.confirmModal.deleteAnnotation', { + defaultMessage: `Deleting this layer removes the annotations and their configurations. `, + }), }; case 'referenceLine': return { buttonLabel, - modalTitle: i18n.translate('xpack.lens.modalTitle.title.deleteReferenceLines', { - defaultMessage: 'Delete reference lines layer?', - }), - modalBody: i18n.translate('xpack.lens.layer.confirmModal.deleteRefLine', { - defaultMessage: `Deleting this layer removes the reference lines and their configurations. `, - }), + modalTitle: + customModalText?.title ?? + i18n.translate('xpack.lens.modalTitle.title.deleteReferenceLines', { + defaultMessage: 'Delete reference lines layer?', + }), + modalBody: + customModalText?.description ?? + i18n.translate('xpack.lens.layer.confirmModal.deleteRefLine', { + defaultMessage: `Deleting this layer removes the reference lines and their configurations. `, + }), }; default: @@ -193,7 +207,8 @@ const RemoveConfirmModal = ({ export const getRemoveLayerAction = (props: RemoveLayerAction): LayerAction => { const { buttonLabel, modalTitle, modalBody } = getCopy( props.layerType || LayerTypes.DATA, - props.isOnlyLayer + props.isOnlyLayer, + props.customModalText ); return { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 84c0b18d30c5a6..4a69695df3489f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -364,7 +364,6 @@ export function LayerPanel( ...getSharedActions({ layerId, activeVisualization, - visualizationState, core, layerIndex, layerType: activeVisualization.getLayerType(layerId, visualizationState), @@ -378,6 +377,10 @@ export function LayerPanel( openLayerSettings: () => setPanelSettingsOpen(true), onCloneLayer, onRemoveLayer: () => onRemoveLayer(layerId), + customRemoveModalText: activeVisualization.getCustomRemoveLayerText?.( + layerId, + visualizationState + ), }), ].filter((i) => i.isCompatible), [ diff --git a/x-pack/plugins/lens/public/shared_components/static_header.tsx b/x-pack/plugins/lens/public/shared_components/static_header.tsx index 8069a2d2c98498..b4c5d8931065e9 100644 --- a/x-pack/plugins/lens/public/shared_components/static_header.tsx +++ b/x-pack/plugins/lens/public/shared_components/static_header.tsx @@ -40,15 +40,7 @@ export const StaticHeader = ({
{label}
- {indicator && ( -
- {indicator} -
- )} + {indicator}
); diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 005c016d0580e8..99cf847508133e 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -1118,6 +1118,15 @@ export interface Visualization LayerAction[]; + /** + * This method is a clunky solution to the problem, but I'm banking on the confirm modal being removed + * with undo/redo anyways + */ + getCustomRemoveLayerText?: ( + layerId: string, + state: T + ) => { title?: string; description?: string } | undefined; + /** returns the type string of the given layer */ getLayerType: (layerId: string, state?: T) => LayerType | undefined; diff --git a/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.test.tsx b/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.test.tsx index 8505f9811749a1..cf389614a50b44 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.test.tsx @@ -113,7 +113,7 @@ describe('annotation group save action', () => { describe('save routine', () => { const layerId = 'mylayerid'; - const layer: XYByValueAnnotationLayerConfig = { + const byValueLayer: XYByValueAnnotationLayerConfig = { layerId, layerType: 'annotations', indexPatternId: 'some-index-pattern', @@ -144,10 +144,11 @@ describe('annotation group save action', () => { legend: { isVisible: true, position: 'bottom' }, layers: [{ layerId } as XYAnnotationLayerConfig], } as XYState, - layer, + layer: byValueLayer, setState: jest.fn(), eventAnnotationService: { createAnnotationGroup: jest.fn(() => Promise.resolve({ id: savedId })), + groupExistsWithTitle: jest.fn(() => Promise.resolve(false)), updateAnnotationGroup: jest.fn(), loadAnnotationGroup: jest.fn(), toExpression: jest.fn(), @@ -162,7 +163,7 @@ describe('annotation group save action', () => { newTags: ['my-tag'], newCopyOnSave: false, isTitleDuplicateConfirmed: false, - onTitleDuplicate: () => {}, + onTitleDuplicate: jest.fn(), }, dataViews, goToAnnotationLibrary: () => Promise.resolve(), @@ -321,5 +322,78 @@ describe('annotation group save action', () => { expect(props.toasts.addSuccess).toHaveBeenCalledTimes(1); }); + + it.each` + existingGroup | newCopyOnSave | titleChanged | isTitleDuplicateConfirmed | expectPreventSave + ${false} | ${false} | ${false} | ${false} | ${true} + ${false} | ${false} | ${false} | ${true} | ${false} + ${true} | ${false} | ${false} | ${false} | ${false} + ${true} | ${true} | ${false} | ${false} | ${true} + ${true} | ${true} | ${false} | ${true} | ${false} + `( + 'checks duplicate title when saving group', + async ({ + existingGroup, + newCopyOnSave, + titleChanged, + isTitleDuplicateConfirmed, + expectPreventSave, + }) => { + (props.eventAnnotationService.groupExistsWithTitle as jest.Mock).mockResolvedValueOnce( + true + ); + + const oldTitle = 'old title'; + let layer: XYAnnotationLayerConfig = byValueLayer; + if (existingGroup) { + const byReferenceLayer: XYByReferenceAnnotationLayerConfig = { + ...props.layer, + annotationGroupId: 'my-group-id', + __lastSaved: { + ...props.layer, + title: oldTitle, + description: 'description', + tags: [], + }, + }; + layer = byReferenceLayer; + } + + const newTitle = titleChanged ? 'my changed title' : oldTitle; + + await onSave({ + ...props, + layer, + modalOnSaveProps: { + ...props.modalOnSaveProps, + newTitle, + isTitleDuplicateConfirmed, + newCopyOnSave, + }, + }); + + if (expectPreventSave) { + expect(props.eventAnnotationService.updateAnnotationGroup).not.toHaveBeenCalled(); + + expect(props.eventAnnotationService.createAnnotationGroup).not.toHaveBeenCalled(); + + expect(props.modalOnSaveProps.closeModal).not.toHaveBeenCalled(); + + expect(props.setState).not.toHaveBeenCalled(); + + expect(props.toasts.addSuccess).not.toHaveBeenCalled(); + + expect(props.modalOnSaveProps.onTitleDuplicate).toHaveBeenCalled(); + } else { + expect(props.modalOnSaveProps.onTitleDuplicate).not.toHaveBeenCalled(); + + expect(props.modalOnSaveProps.closeModal).toHaveBeenCalled(); + + expect(props.setState).toHaveBeenCalled(); + + expect(props.toasts.addSuccess).toHaveBeenCalledTimes(1); + } + } + ); }); }); diff --git a/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx b/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx index d0888189b85927..803dc3e41e87d1 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx @@ -133,6 +133,28 @@ const saveAnnotationGroupToLibrary = async ( return { id: savedId, config: groupConfig }; }; +const shouldStopBecauseDuplicateTitle = async ( + newTitle: string, + existingTitle: string, + newCopyOnSave: ModalOnSaveProps['newCopyOnSave'], + onTitleDuplicate: ModalOnSaveProps['onTitleDuplicate'], + isTitleDuplicateConfirmed: ModalOnSaveProps['isTitleDuplicateConfirmed'], + eventAnnotationService: EventAnnotationServiceType +) => { + if (isTitleDuplicateConfirmed || (newTitle === existingTitle && !newCopyOnSave)) { + return false; + } + + const duplicateExists = await eventAnnotationService.groupExistsWithTitle(newTitle); + + if (duplicateExists) { + onTitleDuplicate(); + return true; + } else { + return false; + } +}; + /** @internal exported for testing only */ export const onSave = async ({ state, @@ -140,7 +162,15 @@ export const onSave = async ({ setState, eventAnnotationService, toasts, - modalOnSaveProps: { newTitle, newDescription, newTags, closeModal, newCopyOnSave }, + modalOnSaveProps: { + newTitle, + newDescription, + newTags, + closeModal, + newCopyOnSave, + onTitleDuplicate, + isTitleDuplicateConfirmed, + }, dataViews, goToAnnotationLibrary, }: { @@ -153,6 +183,17 @@ export const onSave = async ({ dataViews: DataViewsContract; goToAnnotationLibrary: () => Promise; }) => { + const shouldStop = await shouldStopBecauseDuplicateTitle( + newTitle, + isByReferenceAnnotationsLayer(layer) ? layer.__lastSaved.title : '', + newCopyOnSave, + onTitleDuplicate, + isTitleDuplicateConfirmed, + eventAnnotationService + ); + + if (shouldStop) return; + let savedInfo: Awaited>; try { savedInfo = await saveAnnotationGroupToLibrary( @@ -205,27 +246,25 @@ export const onSave = async ({ text: ((element) => render( -

- goToAnnotationLibrary()} - > - {i18n.translate( - 'xpack.lens.xyChart.annotations.saveAnnotationGroupToLibrary.annotationLibrary', - { - defaultMessage: 'annotation library', - } - )} - - ), - }} - /> -

+ goToAnnotationLibrary()} + > + {i18n.translate( + 'xpack.lens.xyChart.annotations.saveAnnotationGroupToLibrary.annotationLibrary', + { + defaultMessage: 'annotation library', + } + )} + + ), + }} + />
, element )) as MountPoint, @@ -258,7 +297,7 @@ export const getSaveLayerAction = ({ const displayName = i18n.translate( 'xpack.lens.xyChart.annotations.saveAnnotationGroupToLibrary', { - defaultMessage: 'Save annotation group', + defaultMessage: 'Save to library', } ); diff --git a/x-pack/plugins/lens/public/visualizations/xy/annotations/helpers.tsx b/x-pack/plugins/lens/public/visualizations/xy/annotations/helpers.tsx index ec89021686c6d9..b9b29a981c2daa 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/annotations/helpers.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/annotations/helpers.tsx @@ -416,16 +416,6 @@ export const getAnnotationsConfiguration = ({ }) => { const groupLabel = getAxisName('x', { isHorizontal: isHorizontalChart(state.layers) }); - const emptyButtonLabels = { - buttonAriaLabel: i18n.translate('xpack.lens.indexPattern.addColumnAriaLabelClick', { - defaultMessage: 'Add an annotation to {groupLabel}', - values: { groupLabel }, - }), - buttonLabel: i18n.translate('xpack.lens.configure.emptyConfigClick', { - defaultMessage: 'Add an annotation', - }), - }; - return { groups: [ { @@ -445,7 +435,6 @@ export const getAnnotationsConfiguration = ({ supportFieldFormat: false, enableDimensionEditor: true, filterOperations: () => false, - labels: emptyButtonLabels, }, ], }; diff --git a/x-pack/plugins/lens/public/visualizations/xy/load_annotation_library_flyout.tsx b/x-pack/plugins/lens/public/visualizations/xy/load_annotation_library_flyout.tsx index ba22b00ccd3626..cb9521b42e0a64 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/load_annotation_library_flyout.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/load_annotation_library_flyout.tsx @@ -70,6 +70,7 @@ export function LoadAnnotationLibraryFlyout({
{ Object { "data-test-subj": "lnsXY_annotationLayer_saveToLibrary", "description": "Saves annotation group as separate saved object", - "displayName": "Save annotation group", + "displayName": "Save to library", "execute": [Function], "icon": "save", "isCompatible": true, @@ -3899,4 +3899,52 @@ describe('xy_visualization', () => { ).not.toThrowError(); }); }); + + describe('#getCustomRemoveLayerText', () => { + it('should NOT return custom text for the remove layer button if not by-reference', () => { + expect(xyVisualization.getCustomRemoveLayerText!('first', exampleState())).toBeUndefined(); + }); + + it('should return custom text for the remove layer button if by-reference', () => { + const layerId = 'layer-id'; + + const commonProps = { + layerId, + layerType: 'annotations' as const, + indexPatternId: 'some-index-pattern', + ignoreGlobalFilters: false, + annotations: [ + { + id: 'some-annotation-id', + type: 'manual', + key: { + type: 'point_in_time', + timestamp: 'timestamp', + }, + } as PointInTimeEventAnnotationConfig, + ], + }; + + const layer: XYByReferenceAnnotationLayerConfig = { + ...commonProps, + annotationGroupId: 'some-group-id', + __lastSaved: { + ...commonProps, + title: 'My saved object title', + description: 'some description', + tags: [], + }, + }; + expect( + xyVisualization.getCustomRemoveLayerText!(layerId, { + ...exampleState(), + layers: [layer], + }) + ).toMatchInlineSnapshot(` + Object { + "title": "Delete \\"My saved object title\\"", + } + `); + }); + }); }); diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index 1a3d002d3baea8..7f236b69f44714 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -97,6 +97,7 @@ import { getVisualizationType, isAnnotationsLayer, isBucketed, + isByReferenceAnnotationsLayer, isDataLayer, isNumericDynamicMetric, isReferenceLayer, @@ -304,6 +305,14 @@ export const getXyVisualization = ({ return actions; }, + getCustomRemoveLayerText(layerId, state) { + const layerIndex = state.layers.findIndex((l) => l.layerId === layerId); + const layer = state.layers[layerIndex]; + if (layer && isByReferenceAnnotationsLayer(layer)) { + return { title: `Delete "${layer.__lastSaved.title}"` }; + } + }, + hasLayerSettings({ state, layerId: currentLayerId }) { const layer = state.layers?.find(({ layerId }) => layerId === currentLayerId); return { data: Boolean(layer && isAnnotationsLayer(layer)), appearance: false }; diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization_helpers.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization_helpers.tsx index a549ac42d94485..c9bd4423015961 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization_helpers.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization_helpers.tsx @@ -161,7 +161,7 @@ export const isPersistedByValueAnnotationsLayer = ( (layer.persistanceType === 'byValue' || !layer.persistanceType); export const isByReferenceAnnotationsLayer = ( - layer: XYAnnotationLayerConfig + layer: XYLayerConfig ): layer is XYByReferenceAnnotationLayerConfig => 'annotationGroupId' in layer && '__lastSaved' in layer; diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx index eab7da089e07d6..cb37fcbf5edfcf 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx @@ -19,6 +19,7 @@ import { import { ToolbarButton } from '@kbn/kibana-react-plugin/public'; import { IconChartBarReferenceLine, IconChartBarAnnotations } from '@kbn/chart-icons'; import { euiThemeVars } from '@kbn/ui-theme'; +import { css } from '@emotion/react'; import { getIgnoreGlobalFilterIcon } from '../../../shared_components/ignore_global_filter/data_view_picker_icon'; import type { VisualizationLayerHeaderContentProps, @@ -96,13 +97,20 @@ function AnnotationsLayerHeader({ } indicator={ hasUnsavedChanges && ( - +
+ +
) } /> diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 121e0dce922c9e..1f9d308c783fbf 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -20070,7 +20070,6 @@ "xpack.lens.functions.timeScale.dateColumnMissingMessage": "L'ID de colonne de date spécifié {columnId} n'existe pas.", "xpack.lens.heatmapVisualization.arrayValuesWarningMessage": "{label} contient des valeurs de tableau. Le rendu de votre visualisation peut ne pas se présenter comme attendu.", "xpack.lens.indexPattern.addColumnAriaLabel": "Ajouter ou faire glisser un champ vers {groupLabel}", - "xpack.lens.indexPattern.addColumnAriaLabelClick": "Ajouter une annotation à {groupLabel}", "xpack.lens.indexPattern.annotationsDimensionEditorLabel": "Annotation {groupLabel}", "xpack.lens.indexPattern.ascendingCountPrecisionErrorWarning": "{name} pour cette visualisation peut être approximatif en raison de la manière dont les données sont indexées. Essayez de trier par rareté plutôt que par nombre ascendant d’enregistrements. Pour en savoir plus sur cette limitation, {link}.", "xpack.lens.indexPattern.autoIntervalLabel": "Auto ({interval})", @@ -20305,7 +20304,6 @@ "xpack.lens.configPanel.selectVisualization": "Sélectionner une visualisation", "xpack.lens.configPanel.visualizationType": "Type de visualisation", "xpack.lens.configure.emptyConfig": "Ajouter ou glisser-déposer un champ", - "xpack.lens.configure.emptyConfigClick": "Ajouter une annotation", "xpack.lens.configure.invalidBottomReferenceLineDimension": "La ligne de référence est affectée à un axe qui n’existe plus ou qui n’est plus valide. Vous pouvez déplacer cette ligne de référence vers un autre axe disponible ou la supprimer.", "xpack.lens.configure.invalidConfigTooltip": "Configuration non valide.", "xpack.lens.configure.invalidConfigTooltipClick": "Cliquez pour en savoir plus.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2789358b1e0f2c..602616c9ffacce 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20069,7 +20069,6 @@ "xpack.lens.functions.timeScale.dateColumnMissingMessage": "指定したdateColumnId {columnId}は存在しません。", "xpack.lens.heatmapVisualization.arrayValuesWarningMessage": "{label}には配列値が含まれます。可視化が想定通りに表示されない場合があります。", "xpack.lens.indexPattern.addColumnAriaLabel": "フィールドを追加するか、{groupLabel}にドラッグアンドドロップします", - "xpack.lens.indexPattern.addColumnAriaLabelClick": "注釈を{groupLabel}に追加", "xpack.lens.indexPattern.annotationsDimensionEditorLabel": "{groupLabel}注釈", "xpack.lens.indexPattern.ascendingCountPrecisionErrorWarning": "データのインデックス方法のため、このビジュアライゼーションの{name}は近似される場合があります。レコード数の昇順ではなく希少性で並べ替えてください。この制限の詳細については、{link}。", "xpack.lens.indexPattern.autoIntervalLabel": "自動({interval})", @@ -20305,7 +20304,6 @@ "xpack.lens.configPanel.selectVisualization": "ビジュアライゼーションを選択してください", "xpack.lens.configPanel.visualizationType": "ビジュアライゼーションタイプ", "xpack.lens.configure.emptyConfig": "フィールドを追加するか、ドラッグアンドドロップします", - "xpack.lens.configure.emptyConfigClick": "注釈の追加", "xpack.lens.configure.invalidBottomReferenceLineDimension": "この基準線は存在しないか有効ではない軸に割り当てられています。この基準線を別の使用可能な軸に移動するか、削除することができます。", "xpack.lens.configure.invalidConfigTooltip": "無効な構成です。", "xpack.lens.configure.invalidConfigTooltipClick": "詳細はクリックしてください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index fd0126b228758b..9c38c99996e8f4 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20069,7 +20069,6 @@ "xpack.lens.functions.timeScale.dateColumnMissingMessage": "指定的 dateColumnId {columnId} 不存在。", "xpack.lens.heatmapVisualization.arrayValuesWarningMessage": "{label} 包含数组值。您的可视化可能无法正常渲染。", "xpack.lens.indexPattern.addColumnAriaLabel": "将字段添加或拖放到 {groupLabel}", - "xpack.lens.indexPattern.addColumnAriaLabelClick": "添加标注到 {groupLabel}", "xpack.lens.indexPattern.annotationsDimensionEditorLabel": "{groupLabel} 标注", "xpack.lens.indexPattern.ascendingCountPrecisionErrorWarning": "由于数据的索引方式,此可视化的 {name} 可能为近似值。尝试按稀有度排序,而不是采用升序记录计数。有关此限制的详情,{link}。", "xpack.lens.indexPattern.autoIntervalLabel": "自动 ({interval})", @@ -20305,7 +20304,6 @@ "xpack.lens.configPanel.selectVisualization": "选择可视化", "xpack.lens.configPanel.visualizationType": "可视化类型", "xpack.lens.configure.emptyConfig": "添加或拖放字段", - "xpack.lens.configure.emptyConfigClick": "添加标注", "xpack.lens.configure.invalidBottomReferenceLineDimension": "此参考线分配给了不再存在或不再有效的轴。您可以将此参考线移到其他可用的轴,或将其移除。", "xpack.lens.configure.invalidConfigTooltip": "配置无效。", "xpack.lens.configure.invalidConfigTooltipClick": "单击了解更多详情。", From f00664b23e43e9d99823495cdcb1b3f798bcde21 Mon Sep 17 00:00:00 2001 From: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:41:57 +0200 Subject: [PATCH 26/98] [Enterprise Search] Copyedits and typo fixes (#161097) Some minor copy fixes --- x-pack/plugins/enterprise_search/common/constants.ts | 2 +- .../esre/components/esre_guide/esre_docs_section.tsx | 2 +- .../components/esre_guide/measure_performance_section.tsx | 2 +- .../esre/components/esre_guide/rrf_ranking_panel.tsx | 2 +- .../vector_search_guide/vector_search_guide.tsx | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index 38d9f256d0d4f3..c2af49bb9e9519 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -150,7 +150,7 @@ export const APPLICATIONS_PLUGIN = { export const VECTOR_SEARCH_PLUGIN = { DESCRIPTION: i18n.translate('xpack.enterpriseSearch.vectorSearch.description', { defaultMessage: - 'Elasticsearch can be used as a vector database and search along with other semantic search methods.', + 'Elasticsearch can be used as a vector database, which enables vector search and semantic search use cases.', }), ID: 'enterpriseSearchVectorSearch', LOGO: 'logoEnterpriseSearch', diff --git a/x-pack/plugins/enterprise_search/public/applications/esre/components/esre_guide/esre_docs_section.tsx b/x-pack/plugins/enterprise_search/public/applications/esre/components/esre_guide/esre_docs_section.tsx index df2bebd9fbfcc7..279d707555cdea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/esre/components/esre_guide/esre_docs_section.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/esre/components/esre_guide/esre_docs_section.tsx @@ -77,7 +77,7 @@ export const EsreDocsSection: React.FC = () => (

{i18n.translate('xpack.enterpriseSearch.esre.rrfRankingPanel.step1.rrfDocsLinkText', { - defaultMessage: 'Reciprocal Rank Fusion documentations', + defaultMessage: 'Reciprocal Rank Fusion documentation', })} ), diff --git a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/vector_search_guide/vector_search_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/vector_search_guide/vector_search_guide.tsx index 82b067962e4483..1c14178b1583bf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/vector_search_guide/vector_search_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/vector_search_guide/vector_search_guide.tsx @@ -87,12 +87,12 @@ export const VectorSearchGuide: React.FC = () => {

{' '}

@@ -216,7 +216,7 @@ export const VectorSearchGuide: React.FC = () => { description={ } /> @@ -235,7 +235,7 @@ export const VectorSearchGuide: React.FC = () => { description={ } /> From e9a9f0396558581f29e34479917c991e81bc49af Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Mon, 3 Jul 2023 16:50:18 +0200 Subject: [PATCH 27/98] Fix publicUrlWarning message related to server.publicBaseUrl (#161091) Fixes #160909 ## Summary This PR fixes the publicUrlWarning. Some of the URLs such as `context.alertDetailsUrl` and `rule.url` are empty strings if `server.publicBaseUrl` is not configured. This is where you can see the message if `server.publicBaseUrl` is not configured: |Before|After| |---|---| |![image](https://github.com/elastic/kibana/assets/12370520/4d56d2fb-af2e-46f1-a3cf-91dd4cf9aaf2)|![image](https://github.com/elastic/kibana/assets/12370520/87c8bdb7-6d0b-4685-822e-c989f0013f42)| --- .../application/lib/validate_params_for_warnings.test.ts | 3 ++- .../public/application/lib/validate_params_for_warnings.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.test.ts index 9de5749fbc2b31..fc0469c56cf509 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.test.ts @@ -22,7 +22,8 @@ describe('validateParamsForWarnings', () => { ]; test('returns warnings when publicUrl is not set and there are publicUrl variables used', () => { - const warning = 'server.publicBaseUrl is not set. Actions will use relative URLs.'; + const warning = + 'server.publicBaseUrl is not set. Generated URLs will be either relative or empty.'; expect( validateParamsForWarnings('Test for {{context.url}}', undefined, actionVariables) ).toEqual(warning); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts index d361d6f739cdc6..447a751f32a3c8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts @@ -13,7 +13,8 @@ import Mustache from 'mustache'; const publicUrlWarning = i18n.translate( 'xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl', { - defaultMessage: 'server.publicBaseUrl is not set. Actions will use relative URLs.', + defaultMessage: + 'server.publicBaseUrl is not set. Generated URLs will be either relative or empty.', } ); From ca6df02289d6f9b03795cf2ab4ada9787056bcb2 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Mon, 3 Jul 2023 17:12:39 +0200 Subject: [PATCH 28/98] [Infrastructure UI] Hosts view charts fix (#160736) closes: [#160734](https://github.com/elastic/kibana/issues/160734) ## Summary This PR fixes an inconsistency between the table and charts when there is no data to be displayed image The Lens charts were not receiving the `query` property from Unified Search, causing them to run a query with incomplete filters ### How to test - Start a local Kibana instance - Navigate to `Infrastructure > Hosts` - Use the unified search using filters that won't match with any hosts - Verify the charts - Navigate from a KPI and Metrics charts to Lens --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/pages/metrics/hosts/components/kpis/tile.tsx | 7 +++++-- .../metrics/hosts/components/tabs/metrics/metric_chart.tsx | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx index cf409e878cb71e..0c1d254342b84d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx @@ -85,13 +85,14 @@ export const Tile = ({ const filters = useMemo(() => { return [ + ...searchCriteria.filters, buildCombinedHostsFilter({ field: 'host.name', values: hostNodes.map((p) => p.name), dataView, }), ]; - }, [hostNodes, dataView]); + }, [searchCriteria.filters, hostNodes, dataView]); const handleBrushEnd = useCallback( ({ range }: BrushTriggerEvent['data']) => { @@ -122,9 +123,10 @@ export const Tile = ({ () => getExtraActions({ timeRange: afterLoadedState.dateRange, + query: searchCriteria.query, filters, }), - [afterLoadedState.dateRange, filters, getExtraActions] + [afterLoadedState.dateRange, filters, getExtraActions, searchCriteria.query] ); return ( @@ -168,6 +170,7 @@ export const Tile = ({ lastReloadRequestTime={afterLoadedState.lastReloadRequestTime} dateRange={afterLoadedState.dateRange} filters={afterLoadedState.filters} + query={afterLoadedState.query} onBrushEnd={handleBrushEnd} loading={loading} /> diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx index 51a0a4ea309315..5d7e946f25e2a8 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx @@ -65,21 +65,23 @@ export const MetricChart = ({ title, type, breakdownSize }: MetricChartProps) => const filters = useMemo(() => { return [ + ...searchCriteria.filters, buildCombinedHostsFilter({ field: 'host.name', values: currentPage.map((p) => p.name), dataView, }), ]; - }, [currentPage, dataView]); + }, [currentPage, dataView, searchCriteria.filters]); const extraActions: Action[] = useMemo( () => getExtraActions({ timeRange: afterLoadedState.dateRange, + query: afterLoadedState.query, filters, }), - [afterLoadedState.dateRange, filters, getExtraActions] + [afterLoadedState.dateRange, afterLoadedState.query, filters, getExtraActions] ); const handleBrushEnd = useCallback( @@ -137,6 +139,7 @@ export const MetricChart = ({ title, type, breakdownSize }: MetricChartProps) => lastReloadRequestTime={afterLoadedState.lastReloadRequestTime} dateRange={afterLoadedState.dateRange} filters={filters} + query={afterLoadedState.query} onBrushEnd={handleBrushEnd} loading={loading} hasTitle From d7454d47334678ec06784b926f111fc0ad3aa49c Mon Sep 17 00:00:00 2001 From: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Date: Mon, 3 Jul 2023 17:18:48 +0200 Subject: [PATCH 29/98] [Enterprise Search] Minor copyedits for connector configs (#161099) Some tiny copyedits --- .../search_index/connector/connector_configuration.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 81bd97840b1904..9cd4802ed2be48 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 @@ -111,7 +111,7 @@ export const ConnectorConfiguration: React.FC = () => { @@ -180,7 +180,7 @@ service_type: "${index.connector.service_type || 'changeme'}" title: i18n.translate( 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.deployConnector.title', { - defaultMessage: 'Deploy a connector', + defaultMessage: 'Deploy connector', } ), titleSize: 'xs', @@ -325,7 +325,7 @@ service_type: "${index.connector.service_type || 'changeme'}" 'xpack.enterpriseSearch.content.indices.configurationConnector.support.description', { defaultMessage: - 'Your connector will have to be deployed to your own infrastructure.', + 'You need to deploy this connector on your own infrastructure.', } )} @@ -345,7 +345,7 @@ service_type: "${index.connector.service_type || 'changeme'}" {i18n.translate( 'xpack.enterpriseSearch.content.indices.configurationConnector.support.manageKeys.label', { - defaultMessage: 'Manage keys', + defaultMessage: 'Manage API keys', } )} From a81287f10c2bcc4ca893878e3ca8b9d141960209 Mon Sep 17 00:00:00 2001 From: Jeramy Soucy Date: Mon, 3 Jul 2023 11:25:58 -0400 Subject: [PATCH 30/98] Implements profile theme selection with KeyPadMenu (#160925) Closes #155941 ## Summary This PR changes the implementation of the theme selection component in the user profile screen from EuiButtonGroup to EuiKeyPadMenu. This better matches the original design. ### Previous Implementation Screenshot 2023-06-28 at 1 49 22 PM ### Tests - `x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx` ### Manual Testing - Start Elasricsearch, and start Kibana with an empty kibana.yml/kibana.dev.yml - Navigate to the _Edit profile_ screen via the profile/avatar button in the top right portion of the uI Screenshot 2023-06-29 at 11 47 42 AM - Verify the theme settings appear as a KeyPadMenu and function as expected Screenshot 2023-06-28 at 2 38 44 PM - Modify the kibana.yml (or kibana.dev.yml) with the line `uiSettings.overrides.theme:darkMode: true` - Refresh Kibana and verify that the dark theme is rendered and the theme settings are disabled and includes a lock icon tip explaining why the mode setting is locked Screenshot 2023-06-30 at 12 24 12 PM - Modify the kibana.yml (or kibana.dev.yml) with the line `uiSettings.overrides.theme:darkMode: false` - Refresh Kibana and verify that the light theme is rendered and the theme settings are disabled and includes a lock icon tip explaining why the mode setting is locked --- .../user_profile/user_profile.test.tsx | 59 ++++++-- .../user_profile/user_profile.tsx | 134 +++++++++++------- 2 files changed, 126 insertions(+), 67 deletions(-) diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx index 9eb1d9d17be381..87df8261d9ec64 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx @@ -256,9 +256,20 @@ describe('useUserProfileForm', () => { ); - const darkModeButton = testWrapper.find('EuiButtonGroup[data-test-subj="darkModeButton"]'); - expect(darkModeButton).toBeTruthy(); - expect(darkModeButton.getDOMNode()).not.toBeDisabled(); + + const overrideMsg = testWrapper.find('EuiText[data-test-subj="themeOverrideMessage"]'); + expect(overrideMsg).toHaveLength(0); + + const themeMenu = testWrapper.find('EuiKeyPadMenu[data-test-subj="themeMenu"]'); + expect(themeMenu).toHaveLength(1); + + const themeOptions = themeMenu.find('EuiKeyPadMenuItem'); + expect(themeOptions).toHaveLength(3); + themeOptions.forEach((option) => { + expect(option.getDOMNode().classList.contains('euiKeyPadMenuItem-isDisabled')).toEqual( + false + ); + }); }); it('should not display if the User is a cloud user', () => { @@ -281,7 +292,7 @@ describe('useUserProfileForm', () => { ); - expect(testWrapper.exists('EuiButtonGroup[data-test-subj="darkModeButton"]')).toBeFalsy(); + expect(testWrapper.exists('EuiButtonGroup[data-test-subj="themeMenu"]')).toBeFalsy(); }); it('should add special toast after submitting form successfully since darkMode requires a refresh', async () => { @@ -314,8 +325,8 @@ describe('useUserProfileForm', () => { const data: UserProfileData = {}; const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false }); - coreStart.settings.client.get.mockReturnValueOnce(true); - coreStart.settings.client.isOverridden.mockReturnValueOnce(true); + coreStart.settings.client.get.mockReturnValue(true); + coreStart.settings.client.isOverridden.mockReturnValue(true); const testWrapper = mount( { ); - const darkModeButton = testWrapper.find('EuiButtonGroup[data-test-subj="darkModeButton"]'); - expect(darkModeButton).toBeTruthy(); - expect(darkModeButton.getDOMNode()).toHaveProperty('disabled'); + const overrideMsg = testWrapper.find('EuiIconTip[data-test-subj="themeOverrideTooltip"]'); + expect(overrideMsg).toHaveLength(1); + + const themeMenu = testWrapper.find('EuiKeyPadMenu[data-test-subj="themeMenu"]'); + expect(themeMenu).toHaveLength(1); + + const themeOptions = themeMenu.find('EuiKeyPadMenuItem'); + expect(themeOptions).toHaveLength(3); + themeOptions.forEach((option) => { + expect(option.getDOMNode().classList.contains('euiKeyPadMenuItem-isDisabled')).toEqual( + true + ); + }); }); it('should be disabled if the theme has been set to `darkMode: false` in the config', () => { const data: UserProfileData = {}; const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false }); - coreStart.settings.client.get.mockReturnValueOnce(false); - coreStart.settings.client.isOverridden.mockReturnValueOnce(true); + coreStart.settings.client.get.mockReturnValue(false); + coreStart.settings.client.isOverridden.mockReturnValue(true); const testWrapper = mount( { ); - const darkModeButton = testWrapper.find('EuiButtonGroup[data-test-subj="darkModeButton"]'); - expect(darkModeButton).toBeTruthy(); - expect(darkModeButton.getDOMNode()).toHaveProperty('disabled'); + const overrideMsg = testWrapper.find('EuiIconTip[data-test-subj="themeOverrideTooltip"]'); + expect(overrideMsg).toHaveLength(1); + + const themeMenu = testWrapper.find('EuiKeyPadMenu[data-test-subj="themeMenu"]'); + expect(themeMenu).toHaveLength(1); + + const themeOptions = themeMenu.find('EuiKeyPadMenuItem'); + expect(themeOptions).toHaveLength(3); + themeOptions.forEach((option) => { + expect(option.getDOMNode().classList.contains('euiKeyPadMenuItem-isDisabled')).toEqual( + true + ); + }); }); }); }); diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx index 5114fe2f387573..0ffa627ac1a3fe 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx @@ -18,6 +18,8 @@ import { EuiFormRow, EuiIcon, EuiIconTip, + EuiKeyPadMenu, + EuiKeyPadMenuItem, EuiPageTemplate_Deprecated as EuiPageTemplate, EuiSpacer, EuiText, @@ -165,6 +167,27 @@ function UserSettingsEditor({ } } + interface ThemeKeyPadItem { + id: string; + label: string; + icon: string; + } + + const themeKeyPadMenuItem = ({ id, label, icon }: ThemeKeyPadItem) => { + return ( + formik.setFieldValue('data.userSettings.darkMode', id)} + > + + + ); + }; + return ( - - + + + + + + + {renderHelpText(isThemeOverridden)} + } fullWidth > - - ), - }, - { - id: 'light', - label: ( - - ), - iconType: 'sun', - }, - { - id: 'dark', - label: ( - - ), - iconType: 'moon', - }, - ]} - onChange={(id: string) => formik.setFieldValue('data.userSettings.darkMode', id)} - isFullWidth - /> + data-test-subj="themeMenu" + checkable={true} + > + {themeKeyPadMenuItem({ + id: '', + label: i18n.translate( + 'xpack.security.accountManagement.userProfile.defaultModeButton', + { + defaultMessage: 'Space default', + } + ), + icon: 'spaces', + })} + {themeKeyPadMenuItem({ + id: 'light', + label: i18n.translate('xpack.security.accountManagement.userProfile.lightModeButton', { + defaultMessage: 'Light', + }), + icon: 'sun', + })} + {themeKeyPadMenuItem({ + id: 'dark', + label: i18n.translate('xpack.security.accountManagement.userProfile.darkModeButton', { + defaultMessage: 'Dark', + }), + icon: 'moon', + })} + ); @@ -912,12 +929,23 @@ export const SaveChangesBottomBar: FunctionComponent = () => { function renderHelpText(isOverridden: boolean) { if (isOverridden) { return ( - - - + + } + /> ); } } From 44c70915076e4bc74817fcb8830fac9aa5b34c7e Mon Sep 17 00:00:00 2001 From: Sergi Massaneda Date: Mon, 3 Jul 2023 18:13:35 +0200 Subject: [PATCH 31/98] [SecuritySolution] Project breadcrumbs (#160784) ## Summary - Integrate new chrome project breadcrumbs API and "navigation tree" API on `serverless_plugin`. - test with: `yarn serverless-security` - Ess implementation migrated to `ess_security` plugin, everything should work the same way. Project breadcrumbs implementation https://github.com/elastic/kibana/pull/160252 ![screenshot](https://github.com/elastic/kibana/assets/17747913/d6533184-1bc8-4596-a3e1-4d815984f654) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/cases/kibana.jsonc | 3 +- .../common/lib/kibana/__mocks__/index.ts | 2 +- .../public/common/lib/kibana/services.ts | 7 +- .../components/all_cases/index.test.tsx | 1 + .../public/components/create/index.test.tsx | 1 + .../components/use_breadcrumbs/index.test.tsx | 29 + .../components/use_breadcrumbs/index.ts | 11 +- x-pack/plugins/cases/public/types.ts | 3 + x-pack/plugins/cases/tsconfig.json | 1 + .../public/breadcrumbs/breadcrumbs.test.ts | 33 ++ .../public/breadcrumbs/breadcrumbs.ts | 29 + .../ess_security/public/breadcrumbs/index.ts | 7 + .../ess_security/public/common/jest.config.js | 26 - .../public/get_started/jest.config.js | 16 - .../ess_security/public/jest.config.js | 2 +- x-pack/plugins/ess_security/public/plugin.ts | 7 +- .../cloud_security_posture/breadcrumbs.ts | 14 +- .../public/common/breadcrumbs/breadcrumbs.ts | 22 + .../public/common/breadcrumbs/index.ts | 9 + .../public/common/breadcrumbs/types.ts | 13 + .../breadcrumbs/get_breadcrumbs_for_page.ts | 33 -- .../navigation/breadcrumbs/index.test.ts | 549 ------------------ .../navigation/breadcrumbs/index.ts | 134 +---- .../breadcrumbs/trailing_breadcrumbs.ts | 48 ++ .../navigation/breadcrumbs/types.ts} | 15 +- .../breadcrumbs/use_breadcrumbs_nav.test.ts | 150 +++++ .../breadcrumbs/use_breadcrumbs_nav.ts | 87 +++ .../use_security_solution_navigation.test.tsx | 3 +- .../use_security_solution_navigation.tsx | 6 +- .../public/dashboards/pages/breadcrumbs.ts | 22 + .../pages/alert_details/utils/breadcrumbs.ts | 15 +- .../detection_engine/rules/breadcrumbs.ts | 92 +++ .../pages/detection_engine/rules/utils.ts | 85 +-- .../utils/{pages.utils.ts => breadcrumbs.ts} | 13 +- .../details/{utils.ts => breadcrumbs.ts} | 18 +- .../hosts/pages/details/details_tabs.test.tsx | 5 +- .../hosts/pages/details/details_tabs.tsx | 5 +- .../explore/hosts/pages/details/index.tsx | 4 +- .../details/{utils.ts => breadcrumbs.ts} | 18 +- .../explore/network/pages/details/index.tsx | 2 - .../details/{utils.ts => breadcrumbs.ts} | 18 +- .../explore/users/pages/details/index.tsx | 3 +- .../plugins/security_solution/public/index.ts | 2 + .../kubernetes/pages/utils/breadcrumbs.ts | 13 +- .../plugins/security_solution/public/mocks.ts | 5 + .../security_solution/public/plugin.tsx | 45 +- .../public/plugin_contract.ts | 67 +++ .../plugins/security_solution/public/types.ts | 16 +- .../plugins/security_solution/tsconfig.json | 1 - .../public/common/jest.config.js | 28 + .../public/common/navigation/breadcrumbs.ts | 15 + .../public/common/navigation/links/index.ts | 8 + .../common/navigation/links/nav_links.ts | 18 + .../public/common/navigation/links/types.ts | 16 + .../common/navigation/navigation_tree.test.ts | 286 +++++++++ .../common/navigation/navigation_tree.ts | 86 +++ .../public/{ => common}/services.mock.tsx | 8 +- .../public/{ => common}/services.tsx | 23 +- .../public/components/get_started/index.tsx | 10 +- .../get_started/toggle_panel.test.tsx | 8 - .../components/side_navigation/index.tsx | 18 +- .../side_navigation/side_navigation.test.tsx | 2 +- .../public/hooks/use_link_props.test.tsx | 6 +- .../public/hooks/use_link_props.ts | 2 +- .../public/hooks/use_nav_links.ts | 9 +- .../public/hooks/use_side_nav_items.test.tsx | 21 +- .../public/hooks/use_side_nav_items.ts | 7 +- .../serverless_security/public/plugin.ts | 16 +- 68 files changed, 1266 insertions(+), 1031 deletions(-) create mode 100644 x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts create mode 100644 x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts create mode 100644 x-pack/plugins/ess_security/public/breadcrumbs/index.ts delete mode 100644 x-pack/plugins/ess_security/public/common/jest.config.js delete mode 100644 x-pack/plugins/ess_security/public/get_started/jest.config.js create mode 100644 x-pack/plugins/security_solution/public/common/breadcrumbs/breadcrumbs.ts create mode 100644 x-pack/plugins/security_solution/public/common/breadcrumbs/index.ts create mode 100644 x-pack/plugins/security_solution/public/common/breadcrumbs/types.ts delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/get_breadcrumbs_for_page.ts delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/trailing_breadcrumbs.ts rename x-pack/plugins/security_solution/public/{dashboards/pages/utils.ts => common/components/navigation/breadcrumbs/types.ts} (51%) create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.ts create mode 100644 x-pack/plugins/security_solution/public/dashboards/pages/breadcrumbs.ts create mode 100644 x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/breadcrumbs.ts rename x-pack/plugins/security_solution/public/exceptions/utils/{pages.utils.ts => breadcrumbs.ts} (61%) rename x-pack/plugins/security_solution/public/explore/hosts/pages/details/{utils.ts => breadcrumbs.ts} (78%) rename x-pack/plugins/security_solution/public/explore/network/pages/details/{utils.ts => breadcrumbs.ts} (79%) rename x-pack/plugins/security_solution/public/explore/users/pages/details/{utils.ts => breadcrumbs.ts} (77%) create mode 100644 x-pack/plugins/security_solution/public/plugin_contract.ts create mode 100644 x-pack/plugins/serverless_security/public/common/jest.config.js create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/links/index.ts create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/links/types.ts create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts create mode 100644 x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts rename x-pack/plugins/serverless_security/public/{ => common}/services.mock.tsx (74%) rename x-pack/plugins/serverless_security/public/{ => common}/services.tsx (56%) diff --git a/x-pack/plugins/cases/kibana.jsonc b/x-pack/plugins/cases/kibana.jsonc index 6604dc63402ef6..b0a03ad753e971 100644 --- a/x-pack/plugins/cases/kibana.jsonc +++ b/x-pack/plugins/cases/kibana.jsonc @@ -35,7 +35,8 @@ "home", "taskManager", "usageCollection", - "spaces" + "spaces", + "serverless", ], "requiredBundles": [], "extraPublicDirs": [ diff --git a/x-pack/plugins/cases/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/cases/public/common/lib/kibana/__mocks__/index.ts index 5062d73dd9b2f2..3aa4c02457ef78 100644 --- a/x-pack/plugins/cases/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/cases/public/common/lib/kibana/__mocks__/index.ts @@ -13,7 +13,7 @@ import { } from '../kibana_react.mock'; export const KibanaServices = { - get: jest.fn(), + get: jest.fn(() => ({})), getKibanaVersion: jest.fn(() => '8.0.0'), getConfig: jest.fn(() => null), }; diff --git a/x-pack/plugins/cases/public/common/lib/kibana/services.ts b/x-pack/plugins/cases/public/common/lib/kibana/services.ts index b1248488e5286b..1846548c5b2b4f 100644 --- a/x-pack/plugins/cases/public/common/lib/kibana/services.ts +++ b/x-pack/plugins/cases/public/common/lib/kibana/services.ts @@ -7,8 +7,10 @@ import type { CoreStart } from '@kbn/core/public'; import type { CasesUiConfigType } from '../../../../common/ui/types'; +import type { CasesPluginStart } from '../../../types'; -type GlobalServices = Pick; +type GlobalServices = Pick & + Pick; export class KibanaServices { private static kibanaVersion?: string; @@ -19,13 +21,14 @@ export class KibanaServices { application, config, http, + serverless, kibanaVersion, theme, }: GlobalServices & { kibanaVersion: string; config: CasesUiConfigType; }) { - this.services = { application, http, theme }; + this.services = { application, http, theme, serverless }; this.kibanaVersion = kibanaVersion; this.config = config; } diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 7ce32a2f123a58..7661242fe9153f 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -20,6 +20,7 @@ import { useGetCurrentUserProfile } from '../../containers/user_profiles/use_get import { userProfiles, userProfilesMap } from '../../containers/user_profiles/api.mock'; import { useBulkGetUserProfiles } from '../../containers/user_profiles/use_bulk_get_user_profiles'; +jest.mock('../../common/lib/kibana'); jest.mock('../../containers/use_get_tags'); jest.mock('../../containers/use_get_action_license', () => { return { diff --git a/x-pack/plugins/cases/public/components/create/index.test.tsx b/x-pack/plugins/cases/public/components/create/index.test.tsx index 29f89226c61af1..cb4b135212e0c0 100644 --- a/x-pack/plugins/cases/public/components/create/index.test.tsx +++ b/x-pack/plugins/cases/public/components/create/index.test.tsx @@ -33,6 +33,7 @@ import { CreateCase } from '.'; import { useGetSupportedActionConnectors } from '../../containers/configure/use_get_supported_action_connectors'; import { useGetTags } from '../../containers/use_get_tags'; +jest.mock('../../common/lib/kibana'); jest.mock('../../containers/api'); jest.mock('../../containers/user_profiles/api'); jest.mock('../../containers/use_get_tags'); diff --git a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx index 7a52686e64378c..bdb726701adf6e 100644 --- a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.test.tsx @@ -14,11 +14,19 @@ import { CasesDeepLinkId } from '../../common/navigation'; const mockSetBreadcrumbs = jest.fn(); const mockSetTitle = jest.fn(); +const mockSetServerlessBreadcrumbs = jest.fn(); +const mockGetKibanaServices = jest.fn((): unknown => ({ + serverless: { setBreadcrumbs: mockSetServerlessBreadcrumbs }, +})); jest.mock('../../common/lib/kibana', () => { const originalModule = jest.requireActual('../../common/lib/kibana'); return { ...originalModule, + KibanaServices: { + ...originalModule.KibanaServices, + get: () => mockGetKibanaServices(), + }, useNavigation: jest.fn().mockReturnValue({ getAppUrl: jest.fn((params?: { deepLinkId: string }) => params?.deepLinkId ?? '/test'), }), @@ -50,12 +58,19 @@ describe('useCasesBreadcrumbs', () => { { href: '/test', onClick: expect.any(Function), text: 'Test' }, { text: 'Cases' }, ]); + expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([]); }); it('should sets the cases title', () => { renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.cases), { wrapper }); expect(mockSetTitle).toHaveBeenCalledWith(['Cases', 'Test']); }); + + it('should not set serverless breadcrumbs in ess', () => { + mockGetKibanaServices.mockReturnValueOnce({ serverless: undefined }); + renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.cases), { wrapper }); + expect(mockSetServerlessBreadcrumbs).not.toHaveBeenCalled(); + }); }); describe('set create_case breadcrumbs', () => { @@ -66,12 +81,19 @@ describe('useCasesBreadcrumbs', () => { { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, { text: 'Create' }, ]); + expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([]); }); it('should sets the cases title', () => { renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.casesCreate), { wrapper }); expect(mockSetTitle).toHaveBeenCalledWith(['Create', 'Cases', 'Test']); }); + + it('should not set serverless breadcrumbs in ess', () => { + mockGetKibanaServices.mockReturnValueOnce({ serverless: undefined }); + renderHook(() => useCasesBreadcrumbs(CasesDeepLinkId.casesCreate), { wrapper }); + expect(mockSetServerlessBreadcrumbs).not.toHaveBeenCalled(); + }); }); describe('set case_view breadcrumbs', () => { @@ -83,11 +105,18 @@ describe('useCasesBreadcrumbs', () => { { href: CasesDeepLinkId.cases, onClick: expect.any(Function), text: 'Cases' }, { text: title }, ]); + expect(mockSetServerlessBreadcrumbs).toHaveBeenCalledWith([{ text: title }]); }); it('should sets the cases title', () => { renderHook(() => useCasesTitleBreadcrumbs(title), { wrapper }); expect(mockSetTitle).toHaveBeenCalledWith([title, 'Cases', 'Test']); }); + + it('should not set serverless breadcrumbs in ess', () => { + mockGetKibanaServices.mockReturnValueOnce({ serverless: undefined }); + renderHook(() => useCasesTitleBreadcrumbs(title), { wrapper }); + expect(mockSetServerlessBreadcrumbs).not.toHaveBeenCalled(); + }); }); }); diff --git a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts index 68a37f8252f050..24d1fa79e0d147 100644 --- a/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts +++ b/x-pack/plugins/cases/public/components/use_breadcrumbs/index.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import type { ChromeBreadcrumb } from '@kbn/core/public'; import { useCallback, useEffect } from 'react'; -import { useKibana, useNavigation } from '../../common/lib/kibana'; +import { KibanaServices, useKibana, useNavigation } from '../../common/lib/kibana'; import type { ICasesDeepLinkId } from '../../common/navigation'; import { CasesDeepLinkId } from '../../common/navigation'; import { useCasesContext } from '../cases_context/use_cases_context'; @@ -84,6 +84,7 @@ export const useCasesBreadcrumbs = (pageDeepLink: ICasesDeepLinkId) => { ] : []), ]); + KibanaServices.get().serverless?.setBreadcrumbs([]); }, [pageDeepLink, appTitle, getAppUrl, applyBreadcrumbs]); }; @@ -93,16 +94,18 @@ export const useCasesTitleBreadcrumbs = (caseTitle: string) => { const applyBreadcrumbs = useApplyBreadcrumbs(); useEffect(() => { + const titleBreadcrumb: ChromeBreadcrumb = { + text: caseTitle, + }; const casesBreadcrumbs: ChromeBreadcrumb[] = [ { text: appTitle, href: getAppUrl() }, { text: casesBreadcrumbTitle[CasesDeepLinkId.cases], href: getAppUrl({ deepLinkId: CasesDeepLinkId.cases }), }, - { - text: caseTitle, - }, + titleBreadcrumb, ]; applyBreadcrumbs(casesBreadcrumbs); + KibanaServices.get().serverless?.setBreadcrumbs([titleBreadcrumb]); }, [caseTitle, appTitle, getAppUrl, applyBreadcrumbs]); }; diff --git a/x-pack/plugins/cases/public/types.ts b/x-pack/plugins/cases/public/types.ts index 6206a3304c88d4..c5a1fd8c73a690 100644 --- a/x-pack/plugins/cases/public/types.ts +++ b/x-pack/plugins/cases/public/types.ts @@ -25,6 +25,7 @@ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { FilesSetup, FilesStart } from '@kbn/files-plugin/public'; import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public'; import type { CasesBulkGetRequest, @@ -58,6 +59,7 @@ import type { PersistableStateAttachmentTypeRegistry } from './client/attachment export interface CasesPluginSetup { files: FilesSetup; security: SecurityPluginSetup; + serverless?: ServerlessPluginSetup; management: ManagementSetup; home?: HomePublicPluginSetup; } @@ -72,6 +74,7 @@ export interface CasesPluginStart { licensing?: LicensingPluginStart; savedObjectsManagement: SavedObjectsManagementPluginStart; security: SecurityPluginStart; + serverless?: ServerlessPluginStart; spaces?: SpacesPluginStart; storage: Storage; triggersActionsUi: TriggersActionsStart; diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index 4314e82ce6ba76..26e61c5c923aab 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -67,6 +67,7 @@ "@kbn/core-lifecycle-browser", "@kbn/core-saved-objects-api-server-mocks", "@kbn/core-theme-browser", + "@kbn/serverless", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts b/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts new file mode 100644 index 00000000000000..3b4c340488572e --- /dev/null +++ b/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import { emptyLastBreadcrumbUrl } from './breadcrumbs'; + +describe('emptyLastBreadcrumbUrl', () => { + it('should empty the URL and onClick function of the last breadcrumb', () => { + const breadcrumbs: ChromeBreadcrumb[] = [ + { text: 'Home', href: '/home', onClick: () => {} }, + { text: 'Breadcrumb 1', href: '/bc1', onClick: () => {} }, + { text: 'Last Breadcrumbs', href: '/last_bc', onClick: () => {} }, + ]; + + const expectedBreadcrumbs = [ + { text: 'Home', href: '/home', onClick: breadcrumbs[0].onClick }, + { text: 'Breadcrumb 1', href: '/bc1', onClick: breadcrumbs[1].onClick }, + { text: 'Last Breadcrumbs', href: '', onClick: undefined }, + ]; + + expect(emptyLastBreadcrumbUrl(breadcrumbs)).toEqual(expectedBreadcrumbs); + }); + + it('should return the original breadcrumbs if the input is empty', () => { + const emptyBreadcrumbs: ChromeBreadcrumb[] = []; + + expect(emptyLastBreadcrumbUrl(emptyBreadcrumbs)).toEqual(emptyBreadcrumbs); + }); +}); diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts b/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts new file mode 100644 index 00000000000000..8fa8107226f4cc --- /dev/null +++ b/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.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 type { PluginStart as SecuritySolutionPluginStart } from '@kbn/security-solution-plugin/public'; +import { ChromeBreadcrumb, CoreStart } from '@kbn/core/public'; + +export const subscribeBreadcrumbs = ( + securitySolution: SecuritySolutionPluginStart, + core: CoreStart +) => { + securitySolution.getBreadcrumbsNav$().subscribe((breadcrumbsNav) => { + const breadcrumbs = [...breadcrumbsNav.leading, ...breadcrumbsNav.trailing]; + if (breadcrumbs.length > 0) { + core.chrome.setBreadcrumbs(emptyLastBreadcrumbUrl(breadcrumbs)); + } + }); +}; + +export const emptyLastBreadcrumbUrl = (breadcrumbs: ChromeBreadcrumb[]) => { + const lastBreadcrumb = breadcrumbs[breadcrumbs.length - 1]; + if (lastBreadcrumb) { + return [...breadcrumbs.slice(0, -1), { ...lastBreadcrumb, href: '', onClick: undefined }]; + } + return breadcrumbs; +}; diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/index.ts b/x-pack/plugins/ess_security/public/breadcrumbs/index.ts new file mode 100644 index 00000000000000..e1ed7fcff09867 --- /dev/null +++ b/x-pack/plugins/ess_security/public/breadcrumbs/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { subscribeBreadcrumbs } from './breadcrumbs'; diff --git a/x-pack/plugins/ess_security/public/common/jest.config.js b/x-pack/plugins/ess_security/public/common/jest.config.js deleted file mode 100644 index ae6cd807e4cc15..00000000000000 --- a/x-pack/plugins/ess_security/public/common/jest.config.js +++ /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. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../../../..', - roots: ['/x-pack/plugins/ess_security/public/common'], - testMatch: ['/x-pack/plugins/ess_security/public/common/**/*.test.{js,mjs,ts,tsx}'], - coverageDirectory: - '/target/kibana-coverage/jest/x-pack/plugins/ess_security/public/common', - coverageReporters: ['text', 'html'], - collectCoverageFrom: [ - '/x-pack/plugins/ess_security/public/common/**/*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/common/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/common/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', - '!/x-pack/plugins/ess_security/public/common/*mock*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/common/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/common/*.d.ts', - '!/x-pack/plugins/ess_security/public/common/*.config.ts', - '!/x-pack/plugins/ess_security/public/common/index.{js,ts,tsx}', - ], -}; diff --git a/x-pack/plugins/ess_security/public/get_started/jest.config.js b/x-pack/plugins/ess_security/public/get_started/jest.config.js deleted file mode 100644 index 3dc5ab6b07f084..00000000000000 --- a/x-pack/plugins/ess_security/public/get_started/jest.config.js +++ /dev/null @@ -1,16 +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. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../../../..', - roots: ['/x-pack/plugins/ess_security/public/get_started'], - coverageDirectory: - '/target/kibana-coverage/jest/x-pack/plugins/ess_security/public/get_started', - coverageReporters: ['text', 'html'], - collectCoverageFrom: ['/x-pack/plugins/ess_security/public/get_started/**/*.{ts,tsx}'], -}; diff --git a/x-pack/plugins/ess_security/public/jest.config.js b/x-pack/plugins/ess_security/public/jest.config.js index 2bdbadf77ba18c..ffee6062ec59ba 100644 --- a/x-pack/plugins/ess_security/public/jest.config.js +++ b/x-pack/plugins/ess_security/public/jest.config.js @@ -8,7 +8,7 @@ module.exports = { preset: '@kbn/test', rootDir: '../../../..', /** all nested directories have their own Jest config file */ - testMatch: ['/x-pack/plugins/ess_security/public/*.test.{js,mjs,ts,tsx}'], + testMatch: ['/x-pack/plugins/ess_security/public/**/*.test.{js,mjs,ts,tsx}'], roots: ['/x-pack/plugins/ess_security/public'], coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/ess_security/public', coverageReporters: ['text', 'html'], diff --git a/x-pack/plugins/ess_security/public/plugin.ts b/x-pack/plugins/ess_security/public/plugin.ts index a87744e00ffcd2..52d75c01f81198 100644 --- a/x-pack/plugins/ess_security/public/plugin.ts +++ b/x-pack/plugins/ess_security/public/plugin.ts @@ -6,6 +6,7 @@ */ import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { subscribeBreadcrumbs } from './breadcrumbs'; import { getSecurityGetStartedComponent } from './get_started'; import { EssSecurityPluginSetup, @@ -26,8 +27,8 @@ export class EssSecurityPlugin constructor() {} public setup( - core: CoreSetup, - setupDeps: EssSecurityPluginSetupDependencies + _core: CoreSetup, + _setupDeps: EssSecurityPluginSetupDependencies ): EssSecurityPluginSetup { return {}; } @@ -37,6 +38,8 @@ export class EssSecurityPlugin startDeps: EssSecurityPluginStartDependencies ): EssSecurityPluginStart { const { securitySolution } = startDeps; + + subscribeBreadcrumbs(securitySolution, core); securitySolution.setGetStartedPage(getSecurityGetStartedComponent(core, startDeps)); return {}; diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/breadcrumbs.ts b/x-pack/plugins/security_solution/public/cloud_security_posture/breadcrumbs.ts index 16bd30db6680d3..f02bc6f4ac32c5 100644 --- a/x-pack/plugins/security_solution/public/cloud_security_posture/breadcrumbs.ts +++ b/x-pack/plugins/security_solution/public/cloud_security_posture/breadcrumbs.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { ChromeBreadcrumb } from '@kbn/core-chrome-browser'; -import type { GetSecuritySolutionUrl } from '../common/components/link_to'; -import type { RouteSpyState } from '../common/utils/route/types'; +import type { GetTrailingBreadcrumbs } from '../common/components/navigation/breadcrumbs/types'; -export const getTrailingBreadcrumbs = ( - params: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = (params, getSecuritySolutionUrl) => { const breadcrumbs = []; if (params.state?.ruleName) { diff --git a/x-pack/plugins/security_solution/public/common/breadcrumbs/breadcrumbs.ts b/x-pack/plugins/security_solution/public/common/breadcrumbs/breadcrumbs.ts new file mode 100644 index 00000000000000..8b61c7c2be10ae --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/breadcrumbs/breadcrumbs.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 { BehaviorSubject } from 'rxjs'; +import type { BreadcrumbsNav } from './types'; + +// Used to update the breadcrumbsNav$ observable internally. +const breadcrumbsNavUpdater$ = new BehaviorSubject({ + leading: [], + trailing: [], +}); + +// The observable can be exposed by the plugin contract. +export const breadcrumbsNav$ = breadcrumbsNavUpdater$.asObservable(); + +export const updateBreadcrumbsNav = (breadcrumbsNav: BreadcrumbsNav) => { + breadcrumbsNavUpdater$.next(breadcrumbsNav); +}; diff --git a/x-pack/plugins/security_solution/public/common/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/breadcrumbs/index.ts new file mode 100644 index 00000000000000..7caff042398605 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/breadcrumbs/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { BreadcrumbsNav } from './types'; +export { updateBreadcrumbsNav, breadcrumbsNav$ } from './breadcrumbs'; diff --git a/x-pack/plugins/security_solution/public/common/breadcrumbs/types.ts b/x-pack/plugins/security_solution/public/common/breadcrumbs/types.ts new file mode 100644 index 00000000000000..ab3aff52ec60c9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/breadcrumbs/types.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. + */ + +import type { ChromeBreadcrumb } from '@kbn/core/public'; + +export interface BreadcrumbsNav { + trailing: ChromeBreadcrumb[]; + leading: ChromeBreadcrumb[]; +} diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/get_breadcrumbs_for_page.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/get_breadcrumbs_for_page.ts deleted file mode 100644 index 325f490a351b1a..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/get_breadcrumbs_for_page.ts +++ /dev/null @@ -1,33 +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 { ChromeBreadcrumb } from '@kbn/core/public'; -import { SecurityPageName } from '../../../../app/types'; -import { APP_NAME } from '../../../../../common/constants'; -import { getAppLandingUrl } from '../../link_to/redirect_to_landing'; - -import type { GetSecuritySolutionUrl } from '../../link_to'; -import { getAncestorLinksInfo } from '../../../links'; - -export const getLeadingBreadcrumbsForSecurityPage = ( - pageName: SecurityPageName, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): [ChromeBreadcrumb, ...ChromeBreadcrumb[]] => { - const landingPath = getSecuritySolutionUrl({ deepLinkId: SecurityPageName.landing }); - - const siemRootBreadcrumb: ChromeBreadcrumb = { - text: APP_NAME, - href: getAppLandingUrl(landingPath), - }; - - const breadcrumbs: ChromeBreadcrumb[] = getAncestorLinksInfo(pageName).map(({ title, id }) => ({ - text: title, - href: getSecuritySolutionUrl({ deepLinkId: id }), - })); - - return [siemRootBreadcrumb, ...breadcrumbs]; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts deleted file mode 100644 index 3d683bccd1b760..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ /dev/null @@ -1,549 +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 '../../../mock/match_media'; -import { encodeIpv6 } from '../../../lib/helpers'; -import { getBreadcrumbsForRoute, useBreadcrumbs } from '.'; -import { HostsTableType } from '../../../../explore/hosts/store/model'; -import type { RouteSpyState } from '../../../utils/route/types'; -import { NetworkRouteType } from '../../../../explore/network/pages/navigation/types'; -import { AdministrationSubTab } from '../../../../management/types'; -import { renderHook } from '@testing-library/react-hooks'; -import { TestProviders } from '../../../mock'; -import type { GetSecuritySolutionUrl } from '../../link_to'; -import { APP_UI_ID, SecurityPageName } from '../../../../../common/constants'; -import { links } from '../../../links/app_links'; -import { updateAppLinks } from '../../../links'; -import { allowedExperimentalValues } from '../../../../../common/experimental_features'; -import { AlertDetailRouteType } from '../../../../detections/pages/alert_details/types'; -import { UsersTableType } from '../../../../explore/users/store/model'; -import { UpsellingService } from '../../../lib/upsellings'; - -const mockUseRouteSpy = jest.fn(); -jest.mock('../../../utils/route/use_route_spy', () => ({ - useRouteSpy: () => mockUseRouteSpy(), -})); - -const getMockObject = ( - pageName: SecurityPageName, - pathName: string, - detailName: string | undefined -): RouteSpyState => { - switch (pageName) { - case SecurityPageName.hosts: - return { - detailName, - pageName, - pathName, - search: '', - tabName: HostsTableType.authentications, - }; - - case SecurityPageName.users: - return { - detailName, - pageName, - pathName, - search: '', - tabName: UsersTableType.allUsers, - }; - - case SecurityPageName.network: - return { - detailName, - pageName, - pathName, - search: '', - tabName: NetworkRouteType.flows, - }; - - case SecurityPageName.administration: - return { - detailName, - pageName, - pathName, - search: '', - tabName: AdministrationSubTab.endpoints, - }; - - case SecurityPageName.alerts: - return { - detailName, - pageName, - pathName, - search: '', - tabName: AlertDetailRouteType.summary, - }; - - default: - return { - detailName, - pageName, - pathName, - search: '', - } as RouteSpyState; - } -}; - -// The string returned is different from what getSecuritySolutionUrl returns, but does not matter for the purposes of this test. -const getSecuritySolutionUrl: GetSecuritySolutionUrl = ({ - deepLinkId, - path, -}: { - deepLinkId?: string; - path?: string; - absolute?: boolean; -}) => `${APP_UI_ID}${deepLinkId ? `/${deepLinkId}` : ''}${path ?? ''}`; - -const mockSetBreadcrumbs = jest.fn(); -jest.mock('../../../lib/kibana/kibana_react', () => { - return { - useKibana: () => ({ - services: { - chrome: { - setBreadcrumbs: mockSetBreadcrumbs, - }, - application: { - navigateToApp: jest.fn(), - getUrlForApp: (appId: string, options?: { path?: string; deepLinkId?: boolean }) => - `${appId}/${options?.deepLinkId ?? ''}${options?.path ?? ''}`, - }, - }, - }), - }; -}); - -const hostName = 'siem-kibana'; - -const ipv4 = '192.0.2.255'; -const ipv6 = '2001:db8:ffff:ffff:ffff:ffff:ffff:ffff'; -const ipv6Encoded = encodeIpv6(ipv6); - -const securityBreadcrumb = { - href: 'securitySolutionUI/get_started', - text: 'Security', -}; - -const hostsBreadcrumb = { - href: 'securitySolutionUI/hosts', - text: 'Hosts', -}; - -const networkBreadcrumb = { - text: 'Network', - href: 'securitySolutionUI/network', -}; - -const exploreBreadcrumb = { - href: 'securitySolutionUI/explore', - text: 'Explore', -}; - -const rulesLandingBreadcrumb = { - text: 'Rules', - href: 'securitySolutionUI/rules-landing', -}; - -const rulesBreadcrumb = { - text: 'SIEM Rules', - href: 'securitySolutionUI/rules', -}; - -const exceptionsBreadcrumb = { - text: 'Shared Exception Lists', - href: 'securitySolutionUI/exceptions', -}; - -const settingsBreadcrumb = { - text: 'Settings', - href: 'securitySolutionUI/administration', -}; - -describe('Navigation Breadcrumbs', () => { - beforeAll(() => { - updateAppLinks(links, { - experimentalFeatures: allowedExperimentalValues, - capabilities: { - navLinks: {}, - management: {}, - catalogue: {}, - actions: { show: true, crud: true }, - siem: { - show: true, - crud: true, - }, - }, - upselling: new UpsellingService(), - }); - }); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('getBreadcrumbsForRoute', () => { - it('should return Overview breadcrumbs when supplied overview pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.overview, '/', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - { - href: 'securitySolutionUI/dashboards', - text: 'Dashboards', - }, - { - href: '', - text: 'Overview', - }, - ]); - }); - - it('should return Host breadcrumbs when supplied hosts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - exploreBreadcrumb, - hostsBreadcrumb, - { - href: '', - text: 'Authentications', - }, - ]); - }); - - it('should return Network breadcrumbs when supplied network pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - exploreBreadcrumb, - networkBreadcrumb, - { - text: 'Flows', - href: '', - }, - ]); - }); - - it('should return Timelines breadcrumbs when supplied timelines pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.timelines, '/', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - { - text: 'Timelines', - href: '', - }, - ]); - }); - - it('should return Host Details breadcrumbs when supplied a pathname with hostName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', hostName), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - exploreBreadcrumb, - hostsBreadcrumb, - { - text: 'siem-kibana', - href: 'securitySolutionUI/hosts/name/siem-kibana', - }, - { text: 'Authentications', href: '' }, - ]); - }); - - it('should return IP Details breadcrumbs when supplied pathname with ipv4', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv4), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - exploreBreadcrumb, - networkBreadcrumb, - { - text: ipv4, - href: `securitySolutionUI/network/ip/${ipv4}/source/flows`, - }, - { text: 'Flows', href: '' }, - ]); - }); - - it('should return IP Details breadcrumbs when supplied pathname with ipv6', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv6Encoded), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - exploreBreadcrumb, - networkBreadcrumb, - { - text: ipv6, - href: `securitySolutionUI/network/ip/${ipv6Encoded}/source/flows`, - }, - { text: 'Flows', href: '' }, - ]); - }); - - it('should return Alerts breadcrumbs when supplied alerts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.alerts, '/alerts', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - { - text: 'Alerts', - href: 'securitySolutionUI/alerts', - }, - { - text: 'Summary', - href: '', - }, - ]); - }); - - it('should return Exceptions breadcrumbs when supplied exceptions pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.exceptions, '/exceptions', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - { - text: 'Shared Exception Lists', - href: '', - }, - ]); - }); - - it('should return Rules breadcrumbs when supplied rules pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - { - ...rulesBreadcrumb, - href: '', - }, - ]); - }); - - it('should return Rules breadcrumbs when supplied rules Creation pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules/create', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - rulesBreadcrumb, - { - text: 'Create', - href: '', - }, - ]); - }); - - it('should return Rules breadcrumbs when supplied rules Details pageName', () => { - const mockDetailName = '5a4a0460-d822-11eb-8962-bfd4aff0a9b3'; - const mockRuleName = 'ALERT_RULE_NAME'; - const breadcrumbs = getBreadcrumbsForRoute( - { - ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}`, undefined), - detailName: mockDetailName, - state: { - ruleName: mockRuleName, - }, - }, - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - rulesBreadcrumb, - { - text: mockRuleName, - href: `securitySolutionUI/rules/id/${mockDetailName}`, - }, - { - text: 'Deleted rule', - href: '', - }, - ]); - }); - - it('should return Rules breadcrumbs when supplied rules Edit pageName', () => { - const mockDetailName = '5a4a0460-d822-11eb-8962-bfd4aff0a9b3'; - const mockRuleName = 'ALERT_RULE_NAME'; - const breadcrumbs = getBreadcrumbsForRoute( - { - ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}/edit`, undefined), - detailName: mockDetailName, - state: { - ruleName: mockRuleName, - }, - }, - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - rulesBreadcrumb, - { - text: 'ALERT_RULE_NAME', - href: `securitySolutionUI/rules/id/${mockDetailName}`, - }, - { - text: 'Edit', - href: '', - }, - ]); - }); - - it('should return null breadcrumbs when supplied Cases pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.case, '/', undefined), - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual(null); - }); - - it('should return null breadcrumbs when supplied Cases details pageName', () => { - const sampleCase = { - id: 'my-case-id', - name: 'Case name', - }; - const breadcrumbs = getBreadcrumbsForRoute( - { - ...getMockObject(SecurityPageName.case, `/${sampleCase.id}`, sampleCase.id), - state: { caseTitle: sampleCase.name }, - }, - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual(null); - }); - - it('should return Endpoints breadcrumbs when supplied endpoints pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.endpoints, '/', undefined), - getSecuritySolutionUrl - ); - - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - settingsBreadcrumb, - { - text: 'Endpoints', - href: '', - }, - ]); - }); - - it('should return Admin breadcrumbs when supplied admin pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.administration, '/', undefined), - getSecuritySolutionUrl - ); - - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - { - ...settingsBreadcrumb, - href: '', - }, - ]); - }); - it('should return Exceptions breadcrumbs when supplied exception Details pageName', () => { - const mockListName = 'new shared list'; - const breadcrumbs = getBreadcrumbsForRoute( - { - ...getMockObject( - SecurityPageName.exceptions, - `/exceptions/details/${mockListName}`, - undefined - ), - state: { - listName: mockListName, - }, - }, - getSecuritySolutionUrl - ); - expect(breadcrumbs).toEqual([ - securityBreadcrumb, - rulesLandingBreadcrumb, - exceptionsBreadcrumb, - { - text: mockListName, - href: ``, - }, - ]); - }); - }); - - describe('setBreadcrumbs()', () => { - it('should call chrome breadcrumb service with correct breadcrumbs', () => { - mockUseRouteSpy.mockReturnValueOnce([getMockObject(SecurityPageName.hosts, '/', hostName)]); - renderHook(useBreadcrumbs, { - initialProps: { isEnabled: true }, - wrapper: TestProviders, - }); - - expect(mockSetBreadcrumbs).toHaveBeenCalledWith([ - expect.objectContaining({ - text: 'Security', - href: 'securitySolutionUI/get_started', - onClick: expect.any(Function), - }), - expect.objectContaining({ - text: 'Explore', - href: 'securitySolutionUI/explore', - onClick: expect.any(Function), - }), - expect.objectContaining({ - text: 'Hosts', - href: 'securitySolutionUI/hosts', - onClick: expect.any(Function), - }), - expect.objectContaining({ - text: 'siem-kibana', - href: 'securitySolutionUI/hosts/name/siem-kibana', - onClick: expect.any(Function), - }), - { - text: 'Authentications', - href: '', - }, - ]); - }); - - it('should not call chrome breadcrumb service when not enabled', () => { - mockUseRouteSpy.mockReturnValueOnce([getMockObject(SecurityPageName.hosts, '/', hostName)]); - renderHook(useBreadcrumbs, { - initialProps: { isEnabled: false }, - wrapper: TestProviders, - }); - expect(mockSetBreadcrumbs).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts index cfbffae6ad8de4..819b50bfb48bec 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts @@ -4,136 +4,4 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import { useEffect } from 'react'; -import { last } from 'lodash/fp'; -import { useDispatch } from 'react-redux'; -import type { ChromeBreadcrumb } from '@kbn/core/public'; -import { METRIC_TYPE } from '@kbn/analytics'; -import { getTrailingBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../explore/hosts/pages/details/utils'; -import { getTrailingBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../explore/network/pages/details/utils'; -import { getTrailingBreadcrumbs as getDetectionRulesBreadcrumbs } from '../../../../detections/pages/detection_engine/rules/utils'; -import { getTrailingBreadcrumbs as geExceptionsBreadcrumbs } from '../../../../exceptions/utils/pages.utils'; -import { getTrailingBreadcrumbs as getCSPBreadcrumbs } from '../../../../cloud_security_posture/breadcrumbs'; -import { getTrailingBreadcrumbs as getUsersBreadcrumbs } from '../../../../explore/users/pages/details/utils'; -import { getTrailingBreadcrumbs as getKubernetesBreadcrumbs } from '../../../../kubernetes/pages/utils/breadcrumbs'; -import { getTrailingBreadcrumbs as getAlertDetailBreadcrumbs } from '../../../../detections/pages/alert_details/utils/breadcrumbs'; -import { getTrailingBreadcrumbs as getDashboardBreadcrumbs } from '../../../../dashboards/pages/utils'; -import { SecurityPageName } from '../../../../app/types'; -import type { RouteSpyState } from '../../../utils/route/types'; -import { timelineActions } from '../../../../timelines/store/timeline'; -import { TimelineId } from '../../../../../common/types/timeline'; -import { getLeadingBreadcrumbsForSecurityPage } from './get_breadcrumbs_for_page'; -import type { GetSecuritySolutionUrl } from '../../link_to'; -import { useGetSecuritySolutionUrl } from '../../link_to'; -import { TELEMETRY_EVENT, track } from '../../../lib/telemetry'; -import { useKibana } from '../../../lib/kibana'; -import { useRouteSpy } from '../../../utils/route/use_route_spy'; - -export const useBreadcrumbs = ({ isEnabled }: { isEnabled: boolean }) => { - const dispatch = useDispatch(); - const [routeProps] = useRouteSpy(); - const getSecuritySolutionUrl = useGetSecuritySolutionUrl(); - const { - chrome: { setBreadcrumbs }, - application: { navigateToUrl }, - } = useKibana().services; - - useEffect(() => { - if (!isEnabled) { - return; - } - const breadcrumbs = getBreadcrumbsForRoute(routeProps, getSecuritySolutionUrl); - if (!breadcrumbs) { - return; - } - setBreadcrumbs( - breadcrumbs.map((breadcrumb) => ({ - ...breadcrumb, - ...(breadcrumb.href && !breadcrumb.onClick - ? { - onClick: (ev) => { - ev.preventDefault(); - const trackedPath = breadcrumb.href?.split('?')[0] ?? 'unknown'; - track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.BREADCRUMB}${trackedPath}`); - dispatch(timelineActions.showTimeline({ id: TimelineId.active, show: false })); - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - navigateToUrl(breadcrumb.href!); - }, - } - : {}), - })) - ); - }, [routeProps, isEnabled, dispatch, getSecuritySolutionUrl, setBreadcrumbs, navigateToUrl]); -}; - -export const getBreadcrumbsForRoute = ( - spyState: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] | null => { - if ( - !spyState?.pageName || - // cases manages its own breadcrumbs, return null - spyState.pageName === SecurityPageName.case - ) { - return null; - } - - const leadingBreadcrumbs = getLeadingBreadcrumbsForSecurityPage( - spyState.pageName, - getSecuritySolutionUrl - ); - - return emptyLastBreadcrumbUrl([ - ...leadingBreadcrumbs, - ...getTrailingBreadcrumbsForRoutes(spyState, getSecuritySolutionUrl), - ]); -}; - -const getTrailingBreadcrumbsForRoutes = ( - spyState: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { - switch (spyState.pageName) { - case SecurityPageName.hosts: - return getHostDetailsBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.network: - return getIPDetailsBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.users: - return getUsersBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.rules: - case SecurityPageName.rulesAdd: - case SecurityPageName.rulesCreate: - return getDetectionRulesBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.exceptions: - return geExceptionsBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.kubernetes: - return getKubernetesBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.alerts: - return getAlertDetailBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.cloudSecurityPostureBenchmarks: - return getCSPBreadcrumbs(spyState, getSecuritySolutionUrl); - case SecurityPageName.dashboards: - return getDashboardBreadcrumbs(spyState); - } - - return []; -}; - -const emptyLastBreadcrumbUrl = (breadcrumbs: ChromeBreadcrumb[]) => { - const leadingBreadCrumbs = breadcrumbs.slice(0, -1); - const lastBreadcrumb = last(breadcrumbs); - - if (lastBreadcrumb) { - return [ - ...leadingBreadCrumbs, - { - ...lastBreadcrumb, - href: '', - }, - ]; - } - - return breadcrumbs; -}; +export { useBreadcrumbsNav } from './use_breadcrumbs_nav'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/trailing_breadcrumbs.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/trailing_breadcrumbs.ts new file mode 100644 index 00000000000000..5c45da1bb1ff23 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/trailing_breadcrumbs.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 { SecurityPageName } from '../../../../../common'; +import type { GetTrailingBreadcrumbs } from './types'; + +import { getTrailingBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../explore/hosts/pages/details/breadcrumbs'; +import { getTrailingBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../explore/network/pages/details/breadcrumbs'; +import { getTrailingBreadcrumbs as getDetectionRulesBreadcrumbs } from '../../../../detections/pages/detection_engine/rules/breadcrumbs'; +import { getTrailingBreadcrumbs as geExceptionsBreadcrumbs } from '../../../../exceptions/utils/breadcrumbs'; +import { getTrailingBreadcrumbs as getCSPBreadcrumbs } from '../../../../cloud_security_posture/breadcrumbs'; +import { getTrailingBreadcrumbs as getUsersBreadcrumbs } from '../../../../explore/users/pages/details/breadcrumbs'; +import { getTrailingBreadcrumbs as getKubernetesBreadcrumbs } from '../../../../kubernetes/pages/utils/breadcrumbs'; +import { getTrailingBreadcrumbs as getAlertDetailBreadcrumbs } from '../../../../detections/pages/alert_details/utils/breadcrumbs'; +import { getTrailingBreadcrumbs as getDashboardBreadcrumbs } from '../../../../dashboards/pages/breadcrumbs'; + +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = ( + spyState, + getSecuritySolutionUrl +) => { + switch (spyState.pageName) { + case SecurityPageName.hosts: + return getHostDetailsBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.network: + return getIPDetailsBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.users: + return getUsersBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.rules: + case SecurityPageName.rulesAdd: + case SecurityPageName.rulesCreate: + return getDetectionRulesBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.exceptions: + return geExceptionsBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.kubernetes: + return getKubernetesBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.alerts: + return getAlertDetailBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.cloudSecurityPostureBenchmarks: + return getCSPBreadcrumbs(spyState, getSecuritySolutionUrl); + case SecurityPageName.dashboards: + return getDashboardBreadcrumbs(spyState, getSecuritySolutionUrl); + } + return []; +}; diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/utils.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/types.ts similarity index 51% rename from x-pack/plugins/security_solution/public/dashboards/pages/utils.ts rename to x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/types.ts index c71eedbec0264c..9efa8320b1fd70 100644 --- a/x-pack/plugins/security_solution/public/dashboards/pages/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/types.ts @@ -6,13 +6,10 @@ */ import type { ChromeBreadcrumb } from '@kbn/core/public'; -import type { RouteSpyState } from '../../common/utils/route/types'; +import type { RouteSpyState } from '../../../utils/route/types'; +import type { GetSecuritySolutionUrl } from '../../link_to'; -export const getTrailingBreadcrumbs = (params: RouteSpyState): ChromeBreadcrumb[] => { - const breadcrumbName = params?.state?.dashboardName; - if (breadcrumbName) { - return [{ text: breadcrumbName }]; - } - - return []; -}; +export type GetTrailingBreadcrumbs = ( + spyState: T, + getSecuritySolutionUrl: GetSecuritySolutionUrl +) => ChromeBreadcrumb[]; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.test.ts new file mode 100644 index 00000000000000..25c29fdb9fa2db --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.test.ts @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import type { GetSecuritySolutionUrl } from '../../link_to'; +import { SecurityPageName } from '../../../../../common/constants'; +import type { LinkInfo, LinkItem } from '../../../links'; +import { useBreadcrumbsNav } from './use_breadcrumbs_nav'; +import type { BreadcrumbsNav } from '../../../breadcrumbs'; + +jest.mock('../../../lib/kibana'); + +const mockDispatch = jest.fn(); +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: () => mockDispatch, +})); + +const link1Id = 'link-1' as SecurityPageName; +const link2Id = 'link-2' as SecurityPageName; +const link3Id = 'link-3' as SecurityPageName; +const link4Id = 'link-4' as SecurityPageName; +const link5Id = 'link-5' as SecurityPageName; + +const link1: LinkItem = { id: link1Id, title: 'link 1', path: '/link1' }; +const link2: LinkItem = { id: link2Id, title: 'link 2', path: '/link2' }; +const link3: LinkItem = { id: link3Id, title: 'link 3', path: '/link3' }; +const link4: LinkItem = { id: link4Id, title: 'link 4', path: '/link4' }; +const link5: LinkItem = { id: link5Id, title: 'link 5', path: '/link5' }; + +const ancestorsLinks = [link1, link2, link3]; +const trailingLinks = [link4, link5]; +const allLinks = [...ancestorsLinks, ...trailingLinks]; + +const mockSecuritySolutionUrl: GetSecuritySolutionUrl = jest.fn( + ({ deepLinkId }: { deepLinkId: SecurityPageName }) => + allLinks.find((link) => link.id === deepLinkId)?.path ?? deepLinkId +); +jest.mock('../../link_to', () => ({ + useGetSecuritySolutionUrl: () => mockSecuritySolutionUrl, +})); + +const mockUpdateBreadcrumbsNav = jest.fn((_param: BreadcrumbsNav) => {}); +jest.mock('../../../breadcrumbs', () => ({ + updateBreadcrumbsNav: (param: BreadcrumbsNav) => mockUpdateBreadcrumbsNav(param), +})); + +const mockUseRouteSpy = jest.fn((): [{ pageName: string }] => [{ pageName: link1Id }]); +jest.mock('../../../utils/route/use_route_spy', () => ({ + useRouteSpy: () => mockUseRouteSpy(), +})); + +const mockGetAncestorLinks = jest.fn((_id: unknown): LinkInfo[] => ancestorsLinks); +jest.mock('../../../links', () => ({ + ...jest.requireActual('../../../links'), + getAncestorLinksInfo: (id: unknown) => mockGetAncestorLinks(id), +})); + +const mockGetTrailingBreadcrumbs = jest.fn((): ChromeBreadcrumb[] => + trailingLinks.map(({ title: text, path: href }) => ({ text, href })) +); +jest.mock('./trailing_breadcrumbs', () => ({ + getTrailingBreadcrumbs: () => mockGetTrailingBreadcrumbs(), +})); + +const landingBreadcrumb = { + href: 'get_started', + text: 'Security', + onClick: expect.any(Function), +}; + +describe('useBreadcrumbsNav', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should process breadcrumbs with current pageName', () => { + renderHook(useBreadcrumbsNav); + expect(mockGetAncestorLinks).toHaveBeenCalledWith(link1Id); + expect(mockGetTrailingBreadcrumbs).toHaveBeenCalledWith(); + }); + + it('should not process breadcrumbs with empty pageName', () => { + mockUseRouteSpy.mockReturnValueOnce([{ pageName: '' }]); + renderHook(useBreadcrumbsNav); + expect(mockGetAncestorLinks).not.toHaveBeenCalled(); + expect(mockGetTrailingBreadcrumbs).not.toHaveBeenCalledWith(); + }); + + it('should not process breadcrumbs with cases pageName', () => { + mockUseRouteSpy.mockReturnValueOnce([{ pageName: SecurityPageName.case }]); + renderHook(useBreadcrumbsNav); + expect(mockGetAncestorLinks).not.toHaveBeenCalled(); + expect(mockGetTrailingBreadcrumbs).not.toHaveBeenCalledWith(); + }); + + it('should call updateBreadcrumbsNav with all breadcrumbs', () => { + renderHook(useBreadcrumbsNav); + expect(mockUpdateBreadcrumbsNav).toHaveBeenCalledWith({ + leading: [ + landingBreadcrumb, + { + href: link1.path, + text: link1.title, + onClick: expect.any(Function), + }, + { + href: link2.path, + text: link2.title, + onClick: expect.any(Function), + }, + { + href: link3.path, + text: link3.title, + onClick: expect.any(Function), + }, + ], + trailing: [ + { + href: link4.path, + text: link4.title, + onClick: expect.any(Function), + }, + { + href: link5.path, + text: link5.title, + onClick: expect.any(Function), + }, + ], + }); + }); + + it('should create breadcrumbs onClick handler', () => { + renderHook(useBreadcrumbsNav); + const event = { preventDefault: jest.fn() } as unknown as React.MouseEvent< + HTMLElement, + MouseEvent + >; + const breadcrumb = mockUpdateBreadcrumbsNav.mock.calls?.[0]?.[0]?.leading[1]; + breadcrumb?.onClick?.(event); + + expect(event.preventDefault).toHaveBeenCalled(); + expect(mockDispatch).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.ts new file mode 100644 index 00000000000000..9eeae743bffaa0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/use_breadcrumbs_nav.ts @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import { METRIC_TYPE } from '@kbn/analytics'; +import type { Dispatch } from 'redux'; +import { SecurityPageName } from '../../../../app/types'; +import type { RouteSpyState } from '../../../utils/route/types'; +import { timelineActions } from '../../../../timelines/store/timeline'; +import { TimelineId } from '../../../../../common/types/timeline'; +import type { GetSecuritySolutionUrl } from '../../link_to'; +import { useGetSecuritySolutionUrl } from '../../link_to'; +import { TELEMETRY_EVENT, track } from '../../../lib/telemetry'; +import { useNavigateTo, type NavigateTo } from '../../../lib/kibana'; +import { useRouteSpy } from '../../../utils/route/use_route_spy'; +import { updateBreadcrumbsNav } from '../../../breadcrumbs'; +import { getAncestorLinksInfo } from '../../../links'; +import { APP_NAME } from '../../../../../common/constants'; +import { getTrailingBreadcrumbs } from './trailing_breadcrumbs'; + +export const useBreadcrumbsNav = () => { + const dispatch = useDispatch(); + const [routeProps] = useRouteSpy(); + const { navigateTo } = useNavigateTo(); + const getSecuritySolutionUrl = useGetSecuritySolutionUrl(); + + useEffect(() => { + // cases manages its own breadcrumbs + if (!routeProps.pageName || routeProps.pageName === SecurityPageName.case) { + return; + } + + const leadingBreadcrumbs = getLeadingBreadcrumbs(routeProps, getSecuritySolutionUrl); + const trailingBreadcrumbs = getTrailingBreadcrumbs(routeProps, getSecuritySolutionUrl); + + updateBreadcrumbsNav({ + leading: addOnClicksHandlers(leadingBreadcrumbs, dispatch, navigateTo), + trailing: addOnClicksHandlers(trailingBreadcrumbs, dispatch, navigateTo), + }); + }, [routeProps, getSecuritySolutionUrl, dispatch, navigateTo]); +}; + +const getLeadingBreadcrumbs = ( + { pageName }: RouteSpyState, + getSecuritySolutionUrl: GetSecuritySolutionUrl +): ChromeBreadcrumb[] => { + const landingBreadcrumb: ChromeBreadcrumb = { + text: APP_NAME, + href: getSecuritySolutionUrl({ deepLinkId: SecurityPageName.landing }), + }; + + const breadcrumbs: ChromeBreadcrumb[] = getAncestorLinksInfo(pageName).map(({ title, id }) => ({ + text: title, + href: getSecuritySolutionUrl({ deepLinkId: id }), + })); + + return [landingBreadcrumb, ...breadcrumbs]; +}; + +const addOnClicksHandlers = ( + breadcrumbs: ChromeBreadcrumb[], + dispatch: Dispatch, + navigateTo: NavigateTo +): ChromeBreadcrumb[] => + breadcrumbs.map((breadcrumb) => ({ + ...breadcrumb, + ...(breadcrumb.href && + !breadcrumb.onClick && { + onClick: createOnClickHandler(breadcrumb.href, dispatch, navigateTo), + }), + })); + +const createOnClickHandler = + (href: string, dispatch: Dispatch, navigateTo: NavigateTo): ChromeBreadcrumb['onClick'] => + (ev) => { + ev.preventDefault(); + const trackedPath = href.split('?')[0]; + track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.BREADCRUMB}${trackedPath}`); + dispatch(timelineActions.showTimeline({ id: TimelineId.active, show: false })); + navigateTo({ url: href }); + }; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx index 42f46525bdbe47..f1d94adc79a1b6 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx @@ -9,9 +9,8 @@ import { renderHook } from '@testing-library/react-hooks'; import { BehaviorSubject } from 'rxjs'; import { useSecuritySolutionNavigation } from './use_security_solution_navigation'; -const mockSetBreadcrumbs = jest.fn(); jest.mock('../breadcrumbs', () => ({ - useBreadcrumbs: () => mockSetBreadcrumbs, + useBreadcrumbsNav: () => jest.fn(), })); const mockIsSidebarEnabled$ = new BehaviorSubject(true); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx index bf4e8359cb4645..315a73a950edf5 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx @@ -16,7 +16,7 @@ import useObservable from 'react-use/lib/useObservable'; import { i18n } from '@kbn/i18n'; import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import { useKibana } from '../../../lib/kibana'; -import { useBreadcrumbs } from '../breadcrumbs'; +import { useBreadcrumbsNav } from '../breadcrumbs'; import { SecuritySideNav } from '../security_side_nav'; const translatedNavTitle = i18n.translate('xpack.securitySolution.navigation.mainLabel', { @@ -27,9 +27,7 @@ export const useSecuritySolutionNavigation = (): KibanaPageTemplateProps['soluti const { isSidebarEnabled$ } = useKibana().services; const isSidebarEnabled = useObservable(isSidebarEnabled$); - useBreadcrumbs({ - isEnabled: true, // TODO: use isSidebarEnabled$ when serverless breadcrumb is ready - }); + useBreadcrumbsNav(); if (!isSidebarEnabled) { return undefined; diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/breadcrumbs.ts b/x-pack/plugins/security_solution/public/dashboards/pages/breadcrumbs.ts new file mode 100644 index 00000000000000..01e663e8abb7e8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/dashboards/pages/breadcrumbs.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 type { GetTrailingBreadcrumbs } from '../../common/components/navigation/breadcrumbs/types'; + +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = (params, getSecuritySolutionUrl) => { + const breadcrumbName = params?.state?.dashboardName; + if (breadcrumbName) { + return [{ text: breadcrumbName }]; + } + + return []; +}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/alert_details/utils/breadcrumbs.ts b/x-pack/plugins/security_solution/public/detections/pages/alert_details/utils/breadcrumbs.ts index 632c40816476b6..2b6dca72bf078e 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alert_details/utils/breadcrumbs.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/alert_details/utils/breadcrumbs.ts @@ -6,7 +6,7 @@ */ import type { ChromeBreadcrumb } from '@kbn/core/public'; -import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; +import type { GetTrailingBreadcrumbs } from '../../../../common/components/navigation/breadcrumbs/types'; import { getAlertDetailsUrl } from '../../../../common/components/link_to'; import { SecurityPageName } from '../../../../../common/constants'; import type { AlertDetailRouteSpyState } from '../../../../common/utils/route/types'; @@ -17,10 +17,15 @@ const TabNameMappedToI18nKey: Record = { [AlertDetailRouteType.summary]: i18n.SUMMARY_PAGE_TITLE, }; -export const getTrailingBreadcrumbs = ( - params: AlertDetailRouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = ( + params, + getSecuritySolutionUrl +) => { let breadcrumb: ChromeBreadcrumb[] = []; if (params.detailName != null) { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/breadcrumbs.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/breadcrumbs.ts new file mode 100644 index 00000000000000..0bd84ee4724ceb --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/breadcrumbs.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import { + getRuleDetailsTabUrl, + getRuleDetailsUrl, +} from '../../../../common/components/link_to/redirect_to_detection_engine'; +import * as i18nRules from './translations'; +import { SecurityPageName } from '../../../../app/types'; +import { RULES_PATH } from '../../../../../common/constants'; +import type { GetTrailingBreadcrumbs } from '../../../../common/components/navigation/breadcrumbs/types'; +import { + RuleDetailTabs, + RULE_DETAILS_TAB_NAME, +} from '../../../../detection_engine/rule_details_ui/pages/rule_details'; +import { DELETED_RULE } from '../../../../detection_engine/rule_details_ui/pages/rule_details/translations'; + +const getRuleDetailsTabName = (tabName: string): string => { + return RULE_DETAILS_TAB_NAME[tabName] ?? RULE_DETAILS_TAB_NAME[RuleDetailTabs.alerts]; +}; + +const isRuleCreatePage = (pathname: string) => + pathname.includes(RULES_PATH) && pathname.includes('/create'); + +const isRuleEditPage = (pathname: string) => + pathname.includes(RULES_PATH) && pathname.includes('/edit'); + +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = (params, getSecuritySolutionUrl) => { + let breadcrumb: ChromeBreadcrumb[] = []; + + if (params.detailName && params.state?.ruleName) { + breadcrumb = [ + ...breadcrumb, + { + text: params.state.ruleName, + href: getSecuritySolutionUrl({ + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsUrl(params.detailName, ''), + }), + }, + ]; + } + + if (params.detailName && params.state?.ruleName && params.tabName) { + breadcrumb = [ + ...breadcrumb, + { + text: getRuleDetailsTabName(params.tabName), + href: getSecuritySolutionUrl({ + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsTabUrl(params.detailName, params.tabName, ''), + }), + }, + ]; + } + + if (isRuleCreatePage(params.pathName)) { + breadcrumb = [ + ...breadcrumb, + { + text: i18nRules.ADD_PAGE_TITLE, + href: '', + }, + ]; + } + + if (isRuleEditPage(params.pathName) && params.detailName && params.state?.ruleName) { + breadcrumb = [ + ...breadcrumb, + { + text: i18nRules.EDIT_PAGE_TITLE, + href: '', + }, + ]; + } + + if (!isRuleEditPage(params.pathName) && params.state && !params.state.isExistingRule) { + breadcrumb = [...breadcrumb, { text: DELETED_RULE, href: '' }]; + } + + return breadcrumb; +}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index 3f8f6315f3471f..805ac2d37741ad 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -5,27 +5,13 @@ * 2.0. */ -import type { ChromeBreadcrumb } from '@kbn/core/public'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import { isThreatMatchRule } from '../../../../../common/detection_engine/utils'; import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; -import { - getRuleDetailsTabUrl, - getRuleDetailsUrl, -} from '../../../../common/components/link_to/redirect_to_detection_engine'; -import * as i18nRules from './translations'; -import type { RouteSpyState } from '../../../../common/utils/route/types'; -import { SecurityPageName } from '../../../../app/types'; -import { DEFAULT_THREAT_MATCH_QUERY, RULES_PATH } from '../../../../../common/constants'; +import { DEFAULT_THREAT_MATCH_QUERY } from '../../../../../common/constants'; import type { AboutStepRule, DefineStepRule, RuleStepsOrder, ScheduleStepRule } from './types'; import { DataSourceType, GroupByOptions, RuleStep } from './types'; -import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../common/detection_engine/rule_schema'; -import { - RuleDetailTabs, - RULE_DETAILS_TAB_NAME, -} from '../../../../detection_engine/rule_details_ui/pages/rule_details'; -import { DELETED_RULE } from '../../../../detection_engine/rule_details_ui/pages/rule_details/translations'; import { fillEmptySeverityMappings } from './helpers'; export const ruleStepsOrder: RuleStepsOrder = [ @@ -35,75 +21,6 @@ export const ruleStepsOrder: RuleStepsOrder = [ RuleStep.ruleActions, ]; -const getRuleDetailsTabName = (tabName: string): string => { - return RULE_DETAILS_TAB_NAME[tabName] ?? RULE_DETAILS_TAB_NAME[RuleDetailTabs.alerts]; -}; - -const isRuleCreatePage = (pathname: string) => - pathname.includes(RULES_PATH) && pathname.includes('/create'); - -const isRuleEditPage = (pathname: string) => - pathname.includes(RULES_PATH) && pathname.includes('/edit'); - -export const getTrailingBreadcrumbs = ( - params: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { - let breadcrumb: ChromeBreadcrumb[] = []; - - if (params.detailName && params.state?.ruleName) { - breadcrumb = [ - ...breadcrumb, - { - text: params.state.ruleName, - href: getSecuritySolutionUrl({ - deepLinkId: SecurityPageName.rules, - path: getRuleDetailsUrl(params.detailName, ''), - }), - }, - ]; - } - - if (params.detailName && params.state?.ruleName && params.tabName) { - breadcrumb = [ - ...breadcrumb, - { - text: getRuleDetailsTabName(params.tabName), - href: getSecuritySolutionUrl({ - deepLinkId: SecurityPageName.rules, - path: getRuleDetailsTabUrl(params.detailName, params.tabName, ''), - }), - }, - ]; - } - - if (isRuleCreatePage(params.pathName)) { - breadcrumb = [ - ...breadcrumb, - { - text: i18nRules.ADD_PAGE_TITLE, - href: '', - }, - ]; - } - - if (isRuleEditPage(params.pathName) && params.detailName && params.state?.ruleName) { - breadcrumb = [ - ...breadcrumb, - { - text: i18nRules.EDIT_PAGE_TITLE, - href: '', - }, - ]; - } - - if (!isRuleEditPage(params.pathName) && params.state && !params.state.isExistingRule) { - breadcrumb = [...breadcrumb, { text: DELETED_RULE, href: '' }]; - } - - return breadcrumb; -}; - export const threatDefault = [ { framework: 'MITRE ATT&CK', diff --git a/x-pack/plugins/security_solution/public/exceptions/utils/pages.utils.ts b/x-pack/plugins/security_solution/public/exceptions/utils/breadcrumbs.ts similarity index 61% rename from x-pack/plugins/security_solution/public/exceptions/utils/pages.utils.ts rename to x-pack/plugins/security_solution/public/exceptions/utils/breadcrumbs.ts index 9c1a3289aca6fe..a4f37ef18feec2 100644 --- a/x-pack/plugins/security_solution/public/exceptions/utils/pages.utils.ts +++ b/x-pack/plugins/security_solution/public/exceptions/utils/breadcrumbs.ts @@ -6,16 +6,17 @@ */ import type { ChromeBreadcrumb } from '@kbn/core/public'; import { EXCEPTIONS_PATH } from '../../../common/constants'; -import type { GetSecuritySolutionUrl } from '../../common/components/link_to'; -import type { RouteSpyState } from '../../common/utils/route/types'; +import type { GetTrailingBreadcrumbs } from '../../common/components/navigation/breadcrumbs/types'; const isListDetailPage = (pathname: string) => pathname.includes(EXCEPTIONS_PATH) && pathname.includes('/details'); -export const getTrailingBreadcrumbs = ( - params: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = (params, getSecuritySolutionUrl) => { let breadcrumb: ChromeBreadcrumb[] = []; if (isListDetailPage(params.pathName) && params.state?.listName) { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/utils.ts b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/breadcrumbs.ts similarity index 78% rename from x-pack/plugins/security_solution/public/explore/hosts/pages/details/utils.ts rename to x-pack/plugins/security_solution/public/explore/hosts/pages/details/breadcrumbs.ts index 634f4e3889cb6f..4b41229c4a1a0a 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/breadcrumbs.ts @@ -8,16 +8,13 @@ import { get } from 'lodash/fp'; import type { ChromeBreadcrumb } from '@kbn/core/public'; -import { hostsModel } from '../../store'; import { HostsTableType } from '../../store/model'; import { getHostDetailsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; import * as i18n from '../translations'; import type { HostRouteSpyState } from '../../../../common/utils/route/types'; import { SecurityPageName } from '../../../../app/types'; -import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; - -export const type = hostsModel.HostsType.details; +import type { GetTrailingBreadcrumbs } from '../../../../common/components/navigation/breadcrumbs/types'; const TabNameMappedToI18nKey: Record = { [HostsTableType.hosts]: i18n.NAVIGATION_ALL_HOSTS_TITLE, @@ -29,10 +26,15 @@ const TabNameMappedToI18nKey: Record = { [HostsTableType.sessions]: i18n.NAVIGATION_SESSIONS_TITLE, }; -export const getTrailingBreadcrumbs = ( - params: HostRouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = ( + params, + getSecuritySolutionUrl +) => { let breadcrumb: ChromeBreadcrumb[] = []; if (params.detailName != null) { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx index 611c1fb95a9952..df38f068885397 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.test.tsx @@ -20,10 +20,9 @@ import { } from '../../../../common/mock'; import { HostDetailsTabs } from './details_tabs'; import { hostDetailsPagePath } from '../types'; -import { type } from './utils'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { getHostDetailsPageFilters } from './helpers'; -import { HostsTableType } from '../../store/model'; +import { HostsType, HostsTableType } from '../../store/model'; import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; import type { State } from '../../../../common/store'; import { createStore } from '../../../../common/store'; @@ -123,7 +122,7 @@ describe('body', () => { hostDetailsPagePath={hostDetailsPagePath} indexNames={[]} indexPattern={mockIndexPattern} - type={type} + type={HostsType.details} hostDetailsFilter={mockHostDetailsPageFilters} filterQuery={filterQuery} from={'2020-07-07T08:20:18.966Z'} diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx index 13955a6e6b013d..cc21c96ac9405d 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx @@ -10,14 +10,13 @@ import { Routes, Route } from '@kbn/shared-ux-router'; import { TableId } from '@kbn/securitysolution-data-table'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { RiskDetailsTabBody } from '../../../components/risk_score/risk_details_tab_body'; -import { HostsTableType } from '../../store/model'; +import { HostsType, HostsTableType } from '../../store/model'; import { AnomaliesQueryTabBody } from '../../../../common/containers/anomalies/anomalies_query_tab_body'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { AnomaliesHostTable } from '../../../../common/components/ml/tables/anomalies_host_table'; import { EventsQueryTabBody } from '../../../../common/components/events_tab'; import type { HostDetailsTabsProps } from './types'; -import { type } from './utils'; import { AuthenticationsQueryTabBody, @@ -43,7 +42,7 @@ export const HostDetailsTabs = React.memo( skip: isInitializing || filterQuery === undefined, setQuery, startDate: from, - type, + type: HostsType.details, indexPattern, indexNames, hostName: detailName, diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx index 107cdb8af4de68..5d0ff73569bdc5 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/index.tsx @@ -49,7 +49,7 @@ import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { HostDetailsTabs } from './details_tabs'; import { navTabsHostDetails } from './nav_tabs'; import type { HostDetailsProps } from './types'; -import { type } from './utils'; +import { HostsType } from '../../store/model'; import { getHostDetailsPageFilters } from './helpers'; import { showGlobalFilters } from '../../../../timelines/components/timeline/helpers'; import { useGlobalFullScreen } from '../../../../common/containers/use_full_screen'; @@ -269,7 +269,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta to={to} from={from} detailName={detailName} - type={type} + type={HostsType.details} setQuery={setQuery} filterQuery={stringifiedAdditionalFilters} hostDetailsPagePath={hostDetailsPagePath} diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/details/utils.ts b/x-pack/plugins/security_solution/public/explore/network/pages/details/breadcrumbs.ts similarity index 79% rename from x-pack/plugins/security_solution/public/explore/network/pages/details/utils.ts rename to x-pack/plugins/security_solution/public/explore/network/pages/details/breadcrumbs.ts index ba8bb5ec7acd40..d3aaa9fba6af7c 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/explore/network/pages/details/breadcrumbs.ts @@ -10,15 +10,13 @@ import { get } from 'lodash/fp'; import type { ChromeBreadcrumb } from '@kbn/core/public'; import { decodeIpv6 } from '../../../../common/lib/helpers'; import { getNetworkDetailsUrl } from '../../../../common/components/link_to/redirect_to_network'; -import { networkModel } from '../../store'; import * as i18n from '../translations'; import { NetworkDetailsRouteType } from './types'; import type { NetworkRouteSpyState } from '../../../../common/utils/route/types'; import { SecurityPageName } from '../../../../app/types'; -import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; import { NetworkRouteType } from '../navigation/types'; +import type { GetTrailingBreadcrumbs } from '../../../../common/components/navigation/breadcrumbs/types'; -export const type = networkModel.NetworkType.details; const TabNameMappedToI18nKey: Record = { [NetworkDetailsRouteType.events]: i18n.NAVIGATION_EVENTS_TITLE, [NetworkDetailsRouteType.anomalies]: i18n.NAVIGATION_ANOMALIES_TITLE, @@ -28,11 +26,15 @@ const TabNameMappedToI18nKey: Record { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = ( + params, + getSecuritySolutionUrl +) => { let breadcrumb: ChromeBreadcrumb[] = []; if (params.detailName != null) { diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx index b3582262a691ac..70f3dc56887fee 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/pages/details/index.tsx @@ -58,8 +58,6 @@ import { SecurityCellActionsTrigger, } from '../../../../common/components/cell_actions'; -export { getTrailingBreadcrumbs } from './utils'; - const NetworkDetailsManage = manageQuery(IpOverview); const NetworkDetailsComponent: React.FC = () => { diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/details/utils.ts b/x-pack/plugins/security_solution/public/explore/users/pages/details/breadcrumbs.ts similarity index 77% rename from x-pack/plugins/security_solution/public/explore/users/pages/details/utils.ts rename to x-pack/plugins/security_solution/public/explore/users/pages/details/breadcrumbs.ts index c4ffe7c84e2a84..d2f793417fe324 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/explore/users/pages/details/breadcrumbs.ts @@ -8,16 +8,13 @@ import { get } from 'lodash/fp'; import type { ChromeBreadcrumb } from '@kbn/core/public'; -import { usersModel } from '../../store'; import { UsersTableType } from '../../store/model'; import { getUsersDetailsUrl } from '../../../../common/components/link_to/redirect_to_users'; import * as i18n from '../translations'; import type { UsersRouteSpyState } from '../../../../common/utils/route/types'; import { SecurityPageName } from '../../../../app/types'; -import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; - -export const type = usersModel.UsersType.details; +import type { GetTrailingBreadcrumbs } from '../../../../common/components/navigation/breadcrumbs/types'; const TabNameMappedToI18nKey: Record = { [UsersTableType.allUsers]: i18n.NAVIGATION_ALL_USERS_TITLE, @@ -28,10 +25,15 @@ const TabNameMappedToI18nKey: Record = { [UsersTableType.risk]: i18n.NAVIGATION_RISK_TITLE, }; -export const getTrailingBreadcrumbs = ( - params: UsersRouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = ( + params, + getSecuritySolutionUrl +) => { let breadcrumb: ChromeBreadcrumb[] = []; if (params.detailName != null) { diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx index 0046d9aa6f61f5..3612fd784d5187 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/details/index.tsx @@ -41,7 +41,6 @@ import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { UsersDetailsTabs } from './details_tabs'; import { navTabsUsersDetails } from './nav_tabs'; import type { UsersDetailsProps } from './types'; -import { type } from './utils'; import { getUsersDetailsPageFilters } from './helpers'; import { showGlobalFilters } from '../../../../timelines/components/timeline/helpers'; import { useGlobalFullScreen } from '../../../../common/containers/use_full_screen'; @@ -257,7 +256,7 @@ const UsersDetailsComponent: React.FC = ({ userDetailFilter={usersDetailsPageFilters} setQuery={setQuery} to={to} - type={type} + type={UsersType.details} usersDetailsPagePath={usersDetailsPagePath} /> diff --git a/x-pack/plugins/security_solution/public/index.ts b/x-pack/plugins/security_solution/public/index.ts index 87f2bcae2e5f37..8d0203e32fb0f1 100644 --- a/x-pack/plugins/security_solution/public/index.ts +++ b/x-pack/plugins/security_solution/public/index.ts @@ -9,6 +9,8 @@ import type { PluginInitializerContext } from '@kbn/core/public'; import { Plugin } from './plugin'; import type { PluginSetup, PluginStart } from './types'; export type { TimelineModel } from './timelines/store/timeline/model'; +export type { NavigationLink } from './common/links'; + export type { UpsellingService, PageUpsellings, diff --git a/x-pack/plugins/security_solution/public/kubernetes/pages/utils/breadcrumbs.ts b/x-pack/plugins/security_solution/public/kubernetes/pages/utils/breadcrumbs.ts index 111a0dc3be554e..9dcd76b838cace 100644 --- a/x-pack/plugins/security_solution/public/kubernetes/pages/utils/breadcrumbs.ts +++ b/x-pack/plugins/security_solution/public/kubernetes/pages/utils/breadcrumbs.ts @@ -6,15 +6,16 @@ */ import type { ChromeBreadcrumb } from '@kbn/core/public'; -import type { RouteSpyState } from '../../../common/utils/route/types'; import { SecurityPageName } from '../../../app/types'; -import type { GetSecuritySolutionUrl } from '../../../common/components/link_to'; import { getKubernetesDetailsUrl } from '../../../common/components/link_to'; +import type { GetTrailingBreadcrumbs } from '../../../common/components/navigation/breadcrumbs/types'; -export const getTrailingBreadcrumbs = ( - params: RouteSpyState, - getSecuritySolutionUrl: GetSecuritySolutionUrl -): ChromeBreadcrumb[] => { +/** + * This module should only export this function. + * All the `getTrailingBreadcrumbs` functions in Security are loaded into the main bundle. + * We should be careful to not import unnecessary modules in this file to avoid increasing the main app bundle size. + */ +export const getTrailingBreadcrumbs: GetTrailingBreadcrumbs = (params, getSecuritySolutionUrl) => { let breadcrumb: ChromeBreadcrumb[] = []; if (params.detailName != null) { diff --git a/x-pack/plugins/security_solution/public/mocks.ts b/x-pack/plugins/security_solution/public/mocks.ts index f16e81636846cc..0a1072f5fd22f1 100644 --- a/x-pack/plugins/security_solution/public/mocks.ts +++ b/x-pack/plugins/security_solution/public/mocks.ts @@ -6,6 +6,7 @@ */ import { BehaviorSubject } from 'rxjs'; +import type { BreadcrumbsNav } from './common/breadcrumbs'; import type { NavigationLink } from './common/links/types'; const setupMock = () => ({ @@ -15,6 +16,10 @@ const setupMock = () => ({ const startMock = () => ({ getNavLinks$: jest.fn(() => new BehaviorSubject([])), setIsSidebarEnabled: jest.fn(), + setGetStartedPage: jest.fn(), + getBreadcrumbsNav$: jest.fn( + () => new BehaviorSubject({ leading: [], trailing: [] }) + ), }); export const securitySolutionMock = { diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 929d38a445cd83..70c1cb7667752f 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { BehaviorSubject, Subject } from 'rxjs'; +import { Subject } from 'rxjs'; import type * as H from 'history'; import type { AppMountParameters, @@ -36,7 +36,6 @@ import { APP_ID, APP_UI_ID, APP_PATH, APP_ICON_SOLUTION } from '../common/consta import { updateAppLinks, type LinksPermissions } from './common/links'; import { registerDeepLinksUpdater } from './common/links/deep_links'; -import { navLinks$ } from './common/links/nav_links'; import { licenseService } from './common/hooks/use_license'; import type { SecuritySolutionUiConfigType } from './common/types'; import { ExperimentalFeaturesService } from './common/experimental_features_service'; @@ -49,10 +48,10 @@ import { getLazyEndpointPolicyResponseExtension } from './management/pages/polic import { getLazyEndpointGenericErrorsListExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_generic_errors_list'; import type { ExperimentalFeatures } from '../common/experimental_features'; import { parseExperimentalConfigValue } from '../common/experimental_features'; -import { UpsellingService } from './common/lib/upsellings'; import { LazyEndpointCustomAssetsExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_custom_assets_extension'; import type { SecurityAppStore } from './common/store/types'; +import { PluginContract } from './plugin_contract'; export class Plugin implements IPlugin { /** @@ -76,12 +75,10 @@ export class Plugin implements IPlugin; - private getStartedComponent$: BehaviorSubject; constructor(private readonly initializerContext: PluginInitializerContext) { this.config = this.initializerContext.config.get(); @@ -91,9 +88,7 @@ export class Plugin implements IPlugin(true); - this.getStartedComponent$ = new BehaviorSubject(null); - this.upsellingService = new UpsellingService(); + this.contract = new PluginContract(); this.telemetry = new TelemetryService(); } private appUpdater$ = new Subject(); @@ -158,6 +153,7 @@ export class Plugin implements IPlugin SecuritySolutionTemplateWrapper, }, savedObjectsManagement: startPluginsDeps.savedObjectsManagement, - isSidebarEnabled$: this.isSidebarEnabled$, - getStartedComponent$: this.getStartedComponent$, - upselling: this.upsellingService, telemetry: this.telemetry.start(), }; return services; @@ -235,19 +228,7 @@ export class Plugin implements IPlugin { - /** - * The specially formatted comment in the `import` expression causes the corresponding webpack chunk to be named. This aids us in debugging chunk size issues. - * See https://webpack.js.org/api/module-methods/#magic-comments - */ - const { resolverPluginSetup } = await import( - /* webpackChunkName: "resolver" */ './resolver' - ); - return resolverPluginSetup(); - }, - upselling: this.upsellingService, - }; + return this.contract.getSetupContract(); } public start(core: CoreStart, plugins: StartPlugins): PluginStart { @@ -310,19 +291,12 @@ export class Plugin implements IPlugin navLinks$, - setIsSidebarEnabled: (isSidebarEnabled: boolean) => - this.isSidebarEnabled$.next(isSidebarEnabled), - setGetStartedPage: (getStartedComponent) => { - this.getStartedComponent$.next(getStartedComponent); - }, - }; + return this.contract.getStartContract(); } public stop() { licenseService.stop(); - return {}; + return this.contract.getStopContract(); } private lazyHelpersForRoutes() { @@ -492,13 +466,14 @@ export class Plugin implements IPlugin { const linksPermissions: LinksPermissions = { experimentalFeatures: this.experimentalFeatures, - upselling: this.upsellingService, + upselling, capabilities: core.application.capabilities, }; diff --git a/x-pack/plugins/security_solution/public/plugin_contract.ts b/x-pack/plugins/security_solution/public/plugin_contract.ts new file mode 100644 index 00000000000000..583424509e1318 --- /dev/null +++ b/x-pack/plugins/security_solution/public/plugin_contract.ts @@ -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 { BehaviorSubject } from 'rxjs'; +import { UpsellingService } from './common/lib/upsellings'; +import type { ContractStartServices, PluginSetup, PluginStart } from './types'; +import { navLinks$ } from './common/links/nav_links'; +import { breadcrumbsNav$ } from './common/breadcrumbs'; + +export class PluginContract { + public isSidebarEnabled$: BehaviorSubject; + public getStartedComponent$: BehaviorSubject; + public upsellingService: UpsellingService; + + constructor() { + this.isSidebarEnabled$ = new BehaviorSubject(true); + this.getStartedComponent$ = new BehaviorSubject(null); + this.upsellingService = new UpsellingService(); + } + + public getStartServices(): ContractStartServices { + return { + isSidebarEnabled$: this.isSidebarEnabled$.asObservable(), + getStartedComponent$: this.getStartedComponent$.asObservable(), + upselling: this.upsellingService, + }; + } + + public getSetupContract(): PluginSetup { + return { + resolver: lazyResolver, + upselling: this.upsellingService, + }; + } + + public getStartContract(): PluginStart { + return { + getNavLinks$: () => navLinks$, + setIsSidebarEnabled: (isSidebarEnabled: boolean) => + this.isSidebarEnabled$.next(isSidebarEnabled), + setGetStartedPage: (getStartedComponent) => { + this.getStartedComponent$.next(getStartedComponent); + }, + getBreadcrumbsNav$: () => breadcrumbsNav$, + }; + } + + public getStopContract() { + return {}; + } +} + +const lazyResolver = async () => { + /** + * The specially formatted comment in the `import` expression causes the corresponding webpack chunk to be named. This aids us in debugging chunk size issues. + * See https://webpack.js.org/api/module-methods/#magic-comments + */ + const { resolverPluginSetup } = await import( + /* webpackChunkName: "resolver" */ + './resolver' + ); + return resolverPluginSetup(); +}; diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 2687c1fcab25ec..31765d23951766 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { BehaviorSubject, Observable } from 'rxjs'; +import type { Observable } from 'rxjs'; import type { AppLeaveHandler, CoreStart } from '@kbn/core/public'; import type { HomePublicPluginSetup } from '@kbn/home-plugin/public'; @@ -70,6 +70,7 @@ import type { NavigationLink } from './common/links'; import type { TelemetryClientStart } from './common/lib/telemetry'; import type { Dashboards } from './dashboards'; import type { UpsellingService } from './common/lib/upsellings'; +import type { BreadcrumbsNav } from './common/breadcrumbs/types'; export interface SetupPlugins { cloud?: CloudSetup; @@ -127,8 +128,15 @@ export interface StartPluginsDependencies extends StartPlugins { savedObjectsTaggingOss: SavedObjectTaggingOssPluginStart; } +export interface ContractStartServices { + isSidebarEnabled$: Observable; + getStartedComponent$: Observable; + upselling: UpsellingService; +} + export type StartServices = CoreStart & - StartPlugins & { + StartPlugins & + ContractStartServices & { storage: Storage; sessionStorage: Storage; apm: ApmBase; @@ -143,9 +151,6 @@ export type StartServices = CoreStart & getPluginWrapper: () => typeof SecuritySolutionTemplateWrapper; }; savedObjectsManagement: SavedObjectsManagementPluginStart; - isSidebarEnabled$: BehaviorSubject; - getStartedComponent$: BehaviorSubject; - upselling: UpsellingService; telemetry: TelemetryClientStart; }; @@ -158,6 +163,7 @@ export interface PluginStart { getNavLinks$: () => Observable; setIsSidebarEnabled: (isSidebarEnabled: boolean) => void; setGetStartedPage: (getStartedComponent: React.ComponentType) => void; + getBreadcrumbsNav$: () => Observable; } export interface AppObservableLibs { diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index bb7c6ce5ea4b6e..d272cb53f4d809 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -83,7 +83,6 @@ "@kbn/guided-onboarding-plugin", "@kbn/i18n-react", "@kbn/kibana-react-plugin", - "@kbn/core-chrome-browser", "@kbn/ecs-data-quality-dashboard", "@kbn/elastic-assistant", "@kbn/data-views-plugin", diff --git a/x-pack/plugins/serverless_security/public/common/jest.config.js b/x-pack/plugins/serverless_security/public/common/jest.config.js new file mode 100644 index 00000000000000..3ea98b51783435 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/x-pack/plugins/serverless_security/public/common'], + testMatch: [ + '/x-pack/plugins/serverless_security/public/common/**/*.test.{js,mjs,ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/serverless_security/public/common', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/serverless_security/public/common/**/*.{ts,tsx}', + '!/x-pack/plugins/serverless_security/public/common/*.test.{ts,tsx}', + '!/x-pack/plugins/serverless_security/public/common/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/serverless_security/public/common/*mock*.{ts,tsx}', + '!/x-pack/plugins/serverless_security/public/common/*.test.{ts,tsx}', + '!/x-pack/plugins/serverless_security/public/common/*.d.ts', + '!/x-pack/plugins/serverless_security/public/common/*.config.ts', + '!/x-pack/plugins/serverless_security/public/common/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts b/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts new file mode 100644 index 00000000000000..d4e9d13b37698c --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.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 { Services } from '../services'; + +export const subscribeBreadcrumbs = (services: Services) => { + const { securitySolution, serverless } = services; + securitySolution.getBreadcrumbsNav$().subscribe((breadcrumbsNav) => { + serverless.setBreadcrumbs(breadcrumbsNav.trailing); + }); +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/index.ts b/x-pack/plugins/serverless_security/public/common/navigation/links/index.ts new file mode 100644 index 00000000000000..7271c36bbdfdf4 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/links/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 { getProjectNavLinks$ } from './nav_links'; +export type { ProjectNavLinks, ProjectNavigationLink } from './types'; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts b/x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts new file mode 100644 index 00000000000000..289d0a0c557080 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.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. + */ + +import { map, type Observable } from 'rxjs'; +import type { NavigationLink } from '@kbn/security-solution-plugin/public'; +import type { ProjectNavLinks, ProjectNavigationLink } from './types'; + +export const getProjectNavLinks$ = (navLinks$: Observable): ProjectNavLinks => { + return navLinks$.pipe(map(processNavLinks)); +}; + +// TODO: This is a placeholder function that will be used to process the nav links, +// It will mix internal Security nav links with the external links to other plugins, in the correct order. +const processNavLinks = (navLinks: NavigationLink[]): ProjectNavigationLink[] => navLinks; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/types.ts b/x-pack/plugins/serverless_security/public/common/navigation/links/types.ts new file mode 100644 index 00000000000000..47930f64dd6d87 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/links/types.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Observable } from 'rxjs'; +import type { NavigationLink } from '@kbn/security-solution-plugin/public'; + +export interface ProjectNavigationLink extends NavigationLink { + // The appId for external links + appId?: string; +} + +export type ProjectNavLinks = Observable; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts b/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts new file mode 100644 index 00000000000000..91d020c3327021 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts @@ -0,0 +1,286 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ChromeNavLink } from '@kbn/core/public'; +import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; +import { servicesMocks } from '../services.mock'; +import { subscribeNavigationTree } from './navigation_tree'; +import { BehaviorSubject } from 'rxjs'; +import { mockProjectNavLinks } from '../services.mock'; +import type { ProjectNavigationLink } from './links'; + +const mockChromeNavLinks = jest.fn((): ChromeNavLink[] => []); +const mockChromeGetNavLinks = jest.fn(() => new BehaviorSubject(mockChromeNavLinks())); +const mockChromeNavLinksGet = jest.fn((id: string): ChromeNavLink | undefined => + mockChromeNavLinks().find((link) => link.id === id) +); +const mockChromeNavLinksHas = jest.fn((id: string): boolean => + mockChromeNavLinks().some((link) => link.id === id) +); + +const mockServices = { + ...servicesMocks, + chrome: { + ...servicesMocks.chrome, + navLinks: { + ...servicesMocks.chrome.navLinks, + get: mockChromeNavLinksGet, + has: mockChromeNavLinksHas, + getNavLinks$: mockChromeGetNavLinks, + }, + }, +}; + +const link1Id = 'link-1' as SecurityPageName; +const link2Id = 'link-2' as SecurityPageName; + +const link1: ProjectNavigationLink = { id: link1Id, title: 'link 1' }; +const link2: ProjectNavigationLink = { id: link2Id, title: 'link 2' }; + +const chromeNavLink1: ChromeNavLink = { + id: `${APP_UI_ID}:${link1.id}`, + title: link1.title, + href: '/link1', + url: '/link1', + baseUrl: '', +}; +const chromeNavLink2: ChromeNavLink = { + id: `${APP_UI_ID}:${link2.id}`, + title: link2.title, + href: '/link2', + url: '/link2', + baseUrl: '', +}; + +const waitForDebounce = async () => new Promise((resolve) => setTimeout(resolve, 150)); + +describe('subscribeNavigationTree', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockChromeNavLinks.mockReturnValue([chromeNavLink1, chromeNavLink2]); + }); + + it('should call serverless setNavigation', async () => { + mockProjectNavLinks.mockReturnValueOnce([link1]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLink1.id, + title: link1.title, + path: ['root', chromeNavLink1.id], + deepLink: chromeNavLink1, + }, + ], + }, + ], + }); + }); + + it('should call serverless setNavigation with external link', async () => { + const externalLink = { ...link1, appId: 'externalAppId' }; + const chromeNavLinkExpected = { + ...chromeNavLink1, + id: `${externalLink.appId}:${externalLink.id}`, + }; + mockChromeNavLinks.mockReturnValue([chromeNavLinkExpected]); + mockProjectNavLinks.mockReturnValueOnce([externalLink]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLinkExpected.id, + title: externalLink.title, + path: ['root', chromeNavLinkExpected.id], + deepLink: chromeNavLinkExpected, + }, + ], + }, + ], + }); + }); + + it('should call serverless setNavigation with nested children', async () => { + mockProjectNavLinks.mockReturnValueOnce([{ ...link1, links: [link2] }]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLink1.id, + title: link1.title, + path: ['root', chromeNavLink1.id], + deepLink: chromeNavLink1, + children: [ + { + id: chromeNavLink2.id, + title: link2.title, + path: ['root', chromeNavLink1.id, chromeNavLink2.id], + deepLink: chromeNavLink2, + }, + ], + }, + ], + }, + ], + }); + }); + + it('should not call serverless setNavigation when projectNavLinks is empty', async () => { + mockProjectNavLinks.mockReturnValueOnce([]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + }); + + it('should not call serverless setNavigation when chrome navLinks is empty', async () => { + mockChromeNavLinks.mockReturnValue([]); + mockProjectNavLinks.mockReturnValueOnce([link1]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + }); + + it('should debounce updates', async () => { + const id = 'expectedId' as SecurityPageName; + const linkExpected = { ...link1, id }; + const chromeNavLinkExpected = { ...chromeNavLink1, id: `${APP_UI_ID}:${id}` }; + + const chromeGetNavLinks$ = new BehaviorSubject([chromeNavLink1]); + mockChromeGetNavLinks.mockReturnValue(chromeGetNavLinks$); + + mockChromeNavLinks.mockReturnValue([chromeNavLink1, chromeNavLink2, chromeNavLinkExpected]); + mockProjectNavLinks.mockReturnValueOnce([linkExpected]); + + subscribeNavigationTree(mockServices); + + chromeGetNavLinks$.next([chromeNavLink1]); + chromeGetNavLinks$.next([chromeNavLink2]); + chromeGetNavLinks$.next([chromeNavLinkExpected]); + + expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledTimes(1); + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLinkExpected.id, + title: link1.title, + path: ['root', chromeNavLinkExpected.id], + deepLink: chromeNavLinkExpected, + }, + ], + }, + ], + }); + }); + + it('should not include links that are not in the chrome navLinks', async () => { + mockChromeNavLinks.mockReturnValue([chromeNavLink2]); + mockProjectNavLinks.mockReturnValueOnce([link1, link2]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLink2.id, + title: link2.title, + path: ['root', chromeNavLink2.id], + deepLink: chromeNavLink2, + }, + ], + }, + ], + }); + }); + + it('should set hidden breadcrumb for blacklisted links', async () => { + const chromeNavLinkTest = { + ...chromeNavLink1, + id: `${APP_UI_ID}:${SecurityPageName.usersEvents}`, // userEvents link is blacklisted + }; + mockChromeNavLinks.mockReturnValue([chromeNavLinkTest, chromeNavLink2]); + mockProjectNavLinks.mockReturnValueOnce([ + { ...link1, id: SecurityPageName.usersEvents }, + link2, + ]); + + subscribeNavigationTree(mockServices); + await waitForDebounce(); + + expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + navigationTree: [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: [ + { + id: chromeNavLinkTest.id, + title: link1.title, + path: ['root', chromeNavLinkTest.id], + deepLink: chromeNavLinkTest, + breadcrumbStatus: 'hidden', + }, + { + id: chromeNavLink2.id, + title: link2.title, + path: ['root', chromeNavLink2.id], + deepLink: chromeNavLink2, + }, + ], + }, + ], + }); + }); +}); diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts b/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts new file mode 100644 index 00000000000000..70464c0c53f5d8 --- /dev/null +++ b/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ChromeNavLinks, ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; +import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; +import { combineLatest, skipWhile, debounceTime } from 'rxjs'; +import type { Services } from '../services'; +import type { ProjectNavigationLink } from './links/types'; + +// We need to hide breadcrumbs for some pages (tabs) because they appear duplicated. +// These breadcrumbs are incorrectly processed as trailing breadcrumbs in SecuritySolution, because of `SpyRoute` architecture limitations. +// They are navLinks tree with a SecurityPageName, so they should be treated as leading breadcrumbs in ESS as well. +// TODO: Improve the breadcrumbs logic in `use_breadcrumbs_nav` to avoid this workaround. +const HIDDEN_BREADCRUMBS = new Set([ + SecurityPageName.networkDns, + SecurityPageName.networkHttp, + SecurityPageName.networkTls, + SecurityPageName.networkAnomalies, + SecurityPageName.networkEvents, + SecurityPageName.usersAuthentications, + SecurityPageName.usersAnomalies, + SecurityPageName.usersRisk, + SecurityPageName.usersEvents, + SecurityPageName.uncommonProcesses, + SecurityPageName.hostsAnomalies, + SecurityPageName.hostsEvents, + SecurityPageName.hostsRisk, + SecurityPageName.sessions, +]); + +export const subscribeNavigationTree = (services: Services): void => { + const { chrome, serverless, getProjectNavLinks$ } = services; + + combineLatest([ + getProjectNavLinks$().pipe(skipWhile((navLink) => navLink.length === 0)), + chrome.navLinks.getNavLinks$().pipe(skipWhile((chromeNavLinks) => chromeNavLinks.length === 0)), + ]) + .pipe(debounceTime(100)) // avoid multiple calls in a short time + .subscribe(([projectNavLinks]) => { + // The root link is temporary until the issue about having multiple links at first level is solved. + // TODO: Assign the navigationTree nodes when the issue is solved: + // const navigationTree = formatChromeProjectNavNodes(chrome.navLinks, projectNavLinks), + const navigationTree: ChromeProjectNavigationNode[] = [ + { + id: 'root', + title: 'Root', + path: ['root'], + breadcrumbStatus: 'hidden', + children: formatChromeProjectNavNodes(chrome.navLinks, projectNavLinks, ['root']), + }, + ]; + serverless.setNavigation({ navigationTree }); + }); +}; + +const formatChromeProjectNavNodes = ( + chromeNavLinks: ChromeNavLinks, + projectNavLinks: ProjectNavigationLink[], + path: string[] = [] +): ChromeProjectNavigationNode[] => + projectNavLinks.reduce((navNodes, navLink) => { + const { id: deepLinkId, appId = APP_UI_ID, links, title } = navLink; + + const id = deepLinkId ? `${appId}:${deepLinkId}` : appId; + + if (chromeNavLinks.has(id)) { + const breadcrumbHidden = appId === APP_UI_ID && HIDDEN_BREADCRUMBS.has(deepLinkId); + const link: ChromeProjectNavigationNode = { + id, + title, + path: [...path, id], + deepLink: chromeNavLinks.get(id), + ...(breadcrumbHidden && { breadcrumbStatus: 'hidden' }), + }; + + if (links?.length) { + link.children = formatChromeProjectNavNodes(chromeNavLinks, links, link.path); + } + navNodes.push(link); + } + return navNodes; + }, []); diff --git a/x-pack/plugins/serverless_security/public/services.mock.tsx b/x-pack/plugins/serverless_security/public/common/services.mock.tsx similarity index 74% rename from x-pack/plugins/serverless_security/public/services.mock.tsx rename to x-pack/plugins/serverless_security/public/common/services.mock.tsx index 142ebb2152e632..70f024842a340d 100644 --- a/x-pack/plugins/serverless_security/public/services.mock.tsx +++ b/x-pack/plugins/serverless_security/public/common/services.mock.tsx @@ -11,12 +11,18 @@ import { coreMock } from '@kbn/core/public/mocks'; import { serverlessMock } from '@kbn/serverless/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; +import { BehaviorSubject } from 'rxjs'; +import type { ProjectNavigationLink } from './navigation/links'; +import type { Services } from './services'; -export const servicesMocks = { +export const mockProjectNavLinks = jest.fn((): ProjectNavigationLink[] => []); + +export const servicesMocks: Services = { ...coreMock.createStart(), serverless: serverlessMock.createStart(), security: securityMock.createStart(), securitySolution: securitySolutionMock.createStart(), + getProjectNavLinks$: jest.fn(() => new BehaviorSubject(mockProjectNavLinks())), }; export const KibanaServicesProvider = React.memo(({ children }) => ( diff --git a/x-pack/plugins/serverless_security/public/services.tsx b/x-pack/plugins/serverless_security/public/common/services.tsx similarity index 56% rename from x-pack/plugins/serverless_security/public/services.tsx rename to x-pack/plugins/serverless_security/public/common/services.tsx index b62b91d1bbfea6..f3bfe1dbbfa1be 100644 --- a/x-pack/plugins/serverless_security/public/services.tsx +++ b/x-pack/plugins/serverless_security/public/common/services.tsx @@ -12,16 +12,27 @@ import { useKibana as useKibanaReact, } from '@kbn/kibana-react-plugin/public'; -import type { ServerlessSecurityPluginStartDependencies } from './types'; +import type { ServerlessSecurityPluginStartDependencies } from '../types'; +import { getProjectNavLinks$, type ProjectNavLinks } from './navigation/links'; -export type Services = CoreStart & ServerlessSecurityPluginStartDependencies; +interface InternalServices { + getProjectNavLinks$: () => ProjectNavLinks; +} +export type Services = CoreStart & ServerlessSecurityPluginStartDependencies & InternalServices; export const KibanaServicesProvider: React.FC<{ - core: CoreStart; - pluginsStart: ServerlessSecurityPluginStartDependencies; -}> = ({ core, pluginsStart, children }) => { - const services: Services = { ...core, ...pluginsStart }; + services: Services; +}> = ({ services, children }) => { return {children}; }; export const useKibana = () => useKibanaReact(); + +export const createServices = ( + core: CoreStart, + pluginsStart: ServerlessSecurityPluginStartDependencies +): Services => { + const { securitySolution } = pluginsStart; + const projectNavLinks$ = getProjectNavLinks$(securitySolution.getNavLinks$()); + return { ...core, ...pluginsStart, getProjectNavLinks$: () => projectNavLinks$ }; +}; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx b/x-pack/plugins/serverless_security/public/components/get_started/index.tsx index 48326496d44221..0ee8c7a1ce62d4 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/index.tsx @@ -7,21 +7,17 @@ import React from 'react'; -import { CoreStart } from '@kbn/core/public'; - +import { KibanaServicesProvider, type Services } from '../../common/services'; import type { GetStartedComponent } from './types'; import { GetStarted } from './lazy'; -import { KibanaServicesProvider } from '../../services'; -import { ServerlessSecurityPluginStartDependencies } from '../../types'; import { SecurityProductTypes } from '../../../common/config'; export const getSecurityGetStartedComponent = ( - core: CoreStart, - pluginsStart: ServerlessSecurityPluginStartDependencies, + services: Services, productTypes: SecurityProductTypes ): GetStartedComponent => { return () => ( - + ); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx index 53f51cdc09a8bf..1a924b70fc45f0 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx @@ -17,14 +17,6 @@ jest.mock('@elastic/eui', () => ({ useEuiShadow: jest.fn(), })); -jest.mock('../../services', () => ({ - useKibana: jest.fn(() => ({ - services: { - storage: {}, - }, - })), -})); - jest.mock('../../lib/get_started/storage'); jest.mock('./use_setup_cards', () => ({ diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx b/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx index db621f7fb6a02d..399d6ecab13deb 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx +++ b/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx @@ -5,22 +5,14 @@ * 2.0. */ import React from 'react'; -import { CoreStart } from '@kbn/core/public'; -import type { - SideNavComponent, - SideNavCompProps, -} from '@kbn/core-chrome-browser/src/project_navigation'; -import { ServerlessSecurityPluginStartDependencies } from '../../types'; +import type { SideNavComponent } from '@kbn/core-chrome-browser/src/project_navigation'; import { SecuritySideNavigation } from './lazy'; -import { KibanaServicesProvider } from '../../services'; +import { KibanaServicesProvider, type Services } from '../../common/services'; -export const getSecuritySideNavComponent = ( - core: CoreStart, - pluginsStart: ServerlessSecurityPluginStartDependencies -): SideNavComponent => { - return (_props: SideNavCompProps) => ( - +export const getSecuritySideNavComponent = (services: Services): SideNavComponent => { + return () => ( + ); diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx b/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx index 5309dbf3e12959..eef0ccb8da671a 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx +++ b/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx @@ -10,7 +10,7 @@ import { render } from '@testing-library/react'; import { SecuritySideNavigation } from './side_navigation'; import { useSideNavItems, useSideNavSelectedId } from '../../hooks/use_side_nav_items'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider } from '../../services.mock'; +import { KibanaServicesProvider } from '../../common/services.mock'; jest.mock('../../hooks/use_side_nav_items'); const mockUseSideNavItems = useSideNavItems as jest.Mock; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx b/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx index b04f19be75b8ff..2a20ca97ef8552 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx +++ b/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx @@ -8,13 +8,13 @@ import { MouseEvent } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider, servicesMocks } from '../services.mock'; +import { KibanaServicesProvider, servicesMocks } from '../common/services.mock'; import { useGetLinkProps, useLinkProps } from './use_link_props'; -const { getUrlForApp: mockGetUrlForApp, navigateToUrl: mockNavigateToUrl } = - servicesMocks.application; +const { getUrlForApp, navigateToUrl: mockNavigateToUrl } = servicesMocks.application; const href = '/app/security/test'; +const mockGetUrlForApp = getUrlForApp as jest.MockedFunction; mockGetUrlForApp.mockReturnValue(href); describe('useLinkProps', () => { diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts b/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts index 3a1989dbdc79a0..6644afb7fdf011 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts +++ b/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts @@ -7,7 +7,7 @@ import { APP_UI_ID, type SecurityPageName } from '@kbn/security-solution-plugin/common'; import { useMemo, useCallback, type MouseEventHandler, type MouseEvent } from 'react'; -import { useKibana, type Services } from '../services'; +import { useKibana, type Services } from '../common/services'; interface LinkProps { onClick: MouseEventHandler; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts b/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts index 7d2b16f6cc6e84..eaa643603f86df 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts +++ b/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts @@ -7,11 +7,10 @@ import { useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { useKibana } from '../services'; +import { useKibana } from '../common/services'; export const useNavLinks = () => { - const { securitySolution } = useKibana().services; - const { getNavLinks$ } = securitySolution; - const navLinks$ = useMemo(() => getNavLinks$(), [getNavLinks$]); - return useObservable(navLinks$, []); + const { getProjectNavLinks$ } = useKibana().services; + const projectNavLinks$ = useMemo(() => getProjectNavLinks$(), [getProjectNavLinks$]); + return useObservable(projectNavLinks$, []); }; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx b/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx index 38a1f4e5784279..22c0e7118ec761 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx +++ b/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx @@ -7,18 +7,15 @@ import { renderHook } from '@testing-library/react-hooks'; import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; -import { BehaviorSubject } from 'rxjs'; -import type { NavigationLink } from '@kbn/security-solution-plugin/public/common/links/types'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider, servicesMocks } from '../services.mock'; +import { + KibanaServicesProvider, + servicesMocks, + mockProjectNavLinks, +} from '../common/services.mock'; jest.mock('./use_link_props'); -const mockNavLinks = jest.fn((): NavigationLink[] => []); -servicesMocks.securitySolution.getNavLinks$.mockImplementation( - () => new BehaviorSubject(mockNavLinks()) -); - const mockUseLocation = jest.fn(() => ({ pathname: '/' })); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), @@ -36,11 +33,11 @@ describe('useSideNavItems', () => { const items = result.current; expect(items).toEqual([]); - expect(servicesMocks.securitySolution.getNavLinks$).toHaveBeenCalledTimes(1); + expect(servicesMocks.getProjectNavLinks$).toHaveBeenCalledTimes(1); }); it('should return main items', async () => { - mockNavLinks.mockReturnValueOnce([ + mockProjectNavLinks.mockReturnValueOnce([ { id: SecurityPageName.alerts, title: 'Alerts' }, { id: SecurityPageName.case, title: 'Cases' }, ]); @@ -66,7 +63,7 @@ describe('useSideNavItems', () => { }); it('should return secondary items', async () => { - mockNavLinks.mockReturnValueOnce([ + mockProjectNavLinks.mockReturnValueOnce([ { id: SecurityPageName.dashboards, title: 'Dashboards', @@ -96,7 +93,7 @@ describe('useSideNavItems', () => { }); it('should return get started link', async () => { - mockNavLinks.mockReturnValueOnce([ + mockProjectNavLinks.mockReturnValueOnce([ { id: SecurityPageName.landing, title: 'Get Started', diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts b/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts index d352a779e94445..7ec68683eb2232 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts +++ b/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts @@ -8,8 +8,11 @@ import { useMemo } from 'react'; import { matchPath, useLocation } from 'react-router-dom'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { SolutionSideNavItem, SolutionSideNavItemPosition } from '@kbn/security-solution-side-nav'; -import { useKibana } from '../services'; +import { + SolutionSideNavItemPosition, + type SolutionSideNavItem, +} from '@kbn/security-solution-side-nav'; +import { useKibana } from '../common/services'; import { type GetLinkProps, useGetLinkProps } from './use_link_props'; import { useNavLinks } from './use_nav_links'; diff --git a/x-pack/plugins/serverless_security/public/plugin.ts b/x-pack/plugins/serverless_security/public/plugin.ts index b93be1b16dcd49..356aea4f2c345e 100644 --- a/x-pack/plugins/serverless_security/public/plugin.ts +++ b/x-pack/plugins/serverless_security/public/plugin.ts @@ -17,6 +17,9 @@ import { ServerlessSecurityPublicConfig, } from './types'; import { registerUpsellings } from './components/upselling'; +import { createServices } from './common/services'; +import { subscribeNavigationTree } from './common/navigation/navigation_tree'; +import { subscribeBreadcrumbs } from './common/navigation/breadcrumbs'; export class ServerlessSecurityPlugin implements @@ -46,13 +49,18 @@ export class ServerlessSecurityPlugin startDeps: ServerlessSecurityPluginStartDependencies ): ServerlessSecurityPluginStart { const { securitySolution, serverless } = startDeps; + const { productTypes } = this.config; + + const services = createServices(core, startDeps); securitySolution.setIsSidebarEnabled(false); - securitySolution.setGetStartedPage( - getSecurityGetStartedComponent(core, startDeps, this.config.productTypes) - ); + securitySolution.setGetStartedPage(getSecurityGetStartedComponent(services, productTypes)); + serverless.setProjectHome('/app/security'); - serverless.setSideNavComponent(getSecuritySideNavComponent(core, startDeps)); + serverless.setSideNavComponent(getSecuritySideNavComponent(services)); + + subscribeNavigationTree(services); + subscribeBreadcrumbs(services); return {}; } From 0aea720fb6002f49d90e0a06bc77eb0a13bff879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Mon, 3 Jul 2023 18:24:51 +0200 Subject: [PATCH 32/98] [Enterprise Search] Change minute values to preset intervals (#161082) ## Summary https://github.com/elastic/kibana/assets/1410658/b9b7d66d-6368-4da4-90f6-2547193c07b6 Change minute values to the preset intervals 5, 10, 15 and 30 minutes presets are set. ### 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 - [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)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../connector_cron_editor.tsx | 2 +- .../__snapshots__/cron_editor.test.tsx.snap | 800 +----------------- .../shared/cron_editor/constants.ts | 24 +- .../shared/cron_editor/cron_editor.tsx | 11 +- .../shared/cron_editor/services/cron.ts | 15 - 5 files changed, 37 insertions(+), 815 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_scheduling/connector_cron_editor.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_scheduling/connector_cron_editor.tsx index 46eccba6a4f706..9c38bdea220ca5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_scheduling/connector_cron_editor.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_scheduling/connector_cron_editor.tsx @@ -135,7 +135,7 @@ function cronToFrequency(cron: string): Frequency { if (fields.length < 4) { return 'YEAR'; } - if (fields[1] === '*' || fields[1].startsWith('*/')) { + if (fields[1] === '*' || fields[1].includes(',')) { return 'MINUTE'; } if (fields[2] === '*') { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/__snapshots__/cron_editor.test.tsx.snap b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/__snapshots__/cron_editor.test.tsx.snap index 2e22e3bfe30b02..d490f4f87057d8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/__snapshots__/cron_editor.test.tsx.snap +++ b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/__snapshots__/cron_editor.test.tsx.snap @@ -3391,241 +3391,21 @@ exports[`CronEditor is rendered with a MINUTE frequency 1`] = ` minute="10" minuteOptions={ Array [ - Object { - "text": "1", - "value": "*/1", - }, - Object { - "text": "2", - "value": "*/2", - }, - Object { - "text": "3", - "value": "*/3", - }, - Object { - "text": "4", - "value": "*/4", - }, Object { "text": "5", - "value": "*/5", - }, - Object { - "text": "6", - "value": "*/6", - }, - Object { - "text": "7", - "value": "*/7", - }, - Object { - "text": "8", - "value": "*/8", - }, - Object { - "text": "9", - "value": "*/9", + "value": "0,5,10,15,20,25,30,35,40,45,50,55", }, Object { "text": "10", - "value": "*/10", - }, - Object { - "text": "11", - "value": "*/11", - }, - Object { - "text": "12", - "value": "*/12", - }, - Object { - "text": "13", - "value": "*/13", - }, - Object { - "text": "14", - "value": "*/14", + "value": "0,10,20,30,40,50", }, Object { "text": "15", - "value": "*/15", - }, - Object { - "text": "16", - "value": "*/16", - }, - Object { - "text": "17", - "value": "*/17", - }, - Object { - "text": "18", - "value": "*/18", - }, - Object { - "text": "19", - "value": "*/19", - }, - Object { - "text": "20", - "value": "*/20", - }, - Object { - "text": "21", - "value": "*/21", - }, - Object { - "text": "22", - "value": "*/22", - }, - Object { - "text": "23", - "value": "*/23", - }, - Object { - "text": "24", - "value": "*/24", - }, - Object { - "text": "25", - "value": "*/25", - }, - Object { - "text": "26", - "value": "*/26", - }, - Object { - "text": "27", - "value": "*/27", - }, - Object { - "text": "28", - "value": "*/28", - }, - Object { - "text": "29", - "value": "*/29", + "value": "0,15,30,45", }, Object { "text": "30", - "value": "*/30", - }, - Object { - "text": "31", - "value": "*/31", - }, - Object { - "text": "32", - "value": "*/32", - }, - Object { - "text": "33", - "value": "*/33", - }, - Object { - "text": "34", - "value": "*/34", - }, - Object { - "text": "35", - "value": "*/35", - }, - Object { - "text": "36", - "value": "*/36", - }, - Object { - "text": "37", - "value": "*/37", - }, - Object { - "text": "38", - "value": "*/38", - }, - Object { - "text": "39", - "value": "*/39", - }, - Object { - "text": "40", - "value": "*/40", - }, - Object { - "text": "41", - "value": "*/41", - }, - Object { - "text": "42", - "value": "*/42", - }, - Object { - "text": "43", - "value": "*/43", - }, - Object { - "text": "44", - "value": "*/44", - }, - Object { - "text": "45", - "value": "*/45", - }, - Object { - "text": "46", - "value": "*/46", - }, - Object { - "text": "47", - "value": "*/47", - }, - Object { - "text": "48", - "value": "*/48", - }, - Object { - "text": "49", - "value": "*/49", - }, - Object { - "text": "50", - "value": "*/50", - }, - Object { - "text": "51", - "value": "*/51", - }, - Object { - "text": "52", - "value": "*/52", - }, - Object { - "text": "53", - "value": "*/53", - }, - Object { - "text": "54", - "value": "*/54", - }, - Object { - "text": "55", - "value": "*/55", - }, - Object { - "text": "56", - "value": "*/56", - }, - Object { - "text": "57", - "value": "*/57", - }, - Object { - "text": "58", - "value": "*/58", - }, - Object { - "text": "59", - "value": "*/59", + "value": "0,30", }, ] } @@ -3690,241 +3470,21 @@ exports[`CronEditor is rendered with a MINUTE frequency 1`] = ` onFocus={[Function]} options={ Array [ - Object { - "text": "1", - "value": "*/1", - }, - Object { - "text": "2", - "value": "*/2", - }, - Object { - "text": "3", - "value": "*/3", - }, - Object { - "text": "4", - "value": "*/4", - }, Object { "text": "5", - "value": "*/5", - }, - Object { - "text": "6", - "value": "*/6", - }, - Object { - "text": "7", - "value": "*/7", - }, - Object { - "text": "8", - "value": "*/8", - }, - Object { - "text": "9", - "value": "*/9", + "value": "0,5,10,15,20,25,30,35,40,45,50,55", }, Object { "text": "10", - "value": "*/10", - }, - Object { - "text": "11", - "value": "*/11", - }, - Object { - "text": "12", - "value": "*/12", - }, - Object { - "text": "13", - "value": "*/13", - }, - Object { - "text": "14", - "value": "*/14", + "value": "0,10,20,30,40,50", }, Object { "text": "15", - "value": "*/15", - }, - Object { - "text": "16", - "value": "*/16", - }, - Object { - "text": "17", - "value": "*/17", - }, - Object { - "text": "18", - "value": "*/18", - }, - Object { - "text": "19", - "value": "*/19", - }, - Object { - "text": "20", - "value": "*/20", - }, - Object { - "text": "21", - "value": "*/21", - }, - Object { - "text": "22", - "value": "*/22", - }, - Object { - "text": "23", - "value": "*/23", - }, - Object { - "text": "24", - "value": "*/24", - }, - Object { - "text": "25", - "value": "*/25", - }, - Object { - "text": "26", - "value": "*/26", - }, - Object { - "text": "27", - "value": "*/27", - }, - Object { - "text": "28", - "value": "*/28", - }, - Object { - "text": "29", - "value": "*/29", + "value": "0,15,30,45", }, Object { "text": "30", - "value": "*/30", - }, - Object { - "text": "31", - "value": "*/31", - }, - Object { - "text": "32", - "value": "*/32", - }, - Object { - "text": "33", - "value": "*/33", - }, - Object { - "text": "34", - "value": "*/34", - }, - Object { - "text": "35", - "value": "*/35", - }, - Object { - "text": "36", - "value": "*/36", - }, - Object { - "text": "37", - "value": "*/37", - }, - Object { - "text": "38", - "value": "*/38", - }, - Object { - "text": "39", - "value": "*/39", - }, - Object { - "text": "40", - "value": "*/40", - }, - Object { - "text": "41", - "value": "*/41", - }, - Object { - "text": "42", - "value": "*/42", - }, - Object { - "text": "43", - "value": "*/43", - }, - Object { - "text": "44", - "value": "*/44", - }, - Object { - "text": "45", - "value": "*/45", - }, - Object { - "text": "46", - "value": "*/46", - }, - Object { - "text": "47", - "value": "*/47", - }, - Object { - "text": "48", - "value": "*/48", - }, - Object { - "text": "49", - "value": "*/49", - }, - Object { - "text": "50", - "value": "*/50", - }, - Object { - "text": "51", - "value": "*/51", - }, - Object { - "text": "52", - "value": "*/52", - }, - Object { - "text": "53", - "value": "*/53", - }, - Object { - "text": "54", - "value": "*/54", - }, - Object { - "text": "55", - "value": "*/55", - }, - Object { - "text": "56", - "value": "*/56", - }, - Object { - "text": "57", - "value": "*/57", - }, - Object { - "text": "58", - "value": "*/58", - }, - Object { - "text": "59", - "value": "*/59", + "value": "0,30", }, ] } @@ -3970,358 +3530,28 @@ exports[`CronEditor is rendered with a MINUTE frequency 1`] = ` > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ({ - value: '*/' + value.toString(), - text: value.toString(), -})); +export const EVERY_MINUTE_OPTIONS = [ + { + text: '5', + value: '0,5,10,15,20,25,30,35,40,45,50,55', + }, + { + text: '10', + value: '0,10,20,30,40,50', + }, + { + text: '15', + value: '0,15,30,45', + }, + { + text: '30', + value: '0,30', + }, +]; export const MINUTE_OPTIONS = makeSequence(0, 59).map((value) => ({ value: value.toString(), @@ -111,7 +125,7 @@ export const frequencyToFieldsMap: Record = { export const frequencyToBaselineFieldsMap: Record = { MINUTE: { second: '0', - minute: '*/1', + minute: '0,5,10,15,20,25,30,35,40,45,50,55', hour: '*', date: '*', month: '*', diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/cron_editor.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/cron_editor.tsx index bcda5c37f33c73..ed27a69085d97f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/cron_editor.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/cron_editor.tsx @@ -29,7 +29,6 @@ import { CronMonthly } from './cron_monthly'; import { CronWeekly } from './cron_weekly'; import { CronYearly } from './cron_yearly'; import { cronExpressionToParts, cronPartsToExpression } from './services'; -import { convertFromEveryXMinute, convertToEveryXMinute } from './services/cron'; import { Frequency, Field, FieldToValueMap } from './types'; const excludeBlockListedFrequencies = ( @@ -80,20 +79,14 @@ export class CronEditor extends Component { } onChangeFrequency = (frequency: Frequency) => { - const { onChange, fieldToPreferredValueMap, frequency: oldFrequency } = this.props; + const { onChange, fieldToPreferredValueMap } = this.props; // Update fields which aren't editable with acceptable baseline values. const editableFields = Object.keys(frequencyToFieldsMap[frequency]) as Field[]; const inheritedFields = editableFields.reduce( (fieldBaselines, field) => { if (fieldToPreferredValueMap[field] != null) { - if (oldFrequency === 'MINUTE') { - fieldBaselines[field] = convertFromEveryXMinute(fieldToPreferredValueMap[field]); - } else if (frequency === 'MINUTE') { - fieldBaselines[field] = convertToEveryXMinute(fieldToPreferredValueMap[field]); - } else { - fieldBaselines[field] = fieldToPreferredValueMap[field]; - } + fieldBaselines[field] = fieldToPreferredValueMap[field]; } return fieldBaselines; }, diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/services/cron.ts b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/services/cron.ts index fc2019d63c17d7..542502fbcbe769 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/services/cron.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/cron_editor/services/cron.ts @@ -56,18 +56,3 @@ export function cronPartsToExpression({ }: FieldToValueMap): string { return `${second} ${minute} ${hour} ${date} ${month} ${day}`; } - -export function convertToEveryXMinute( - minute: FieldToValueMap['minute'] -): FieldToValueMap['minute'] { - if (!minute) return minute; - if (minute.startsWith('*/')) return minute; - return '*/' + minute; -} - -export function convertFromEveryXMinute( - minute: FieldToValueMap['minute'] -): FieldToValueMap['minute'] { - if (!minute) return minute; - return minute.startsWith('*/') ? minute.slice(2) : minute; -} From 6a9e8d422cc1e27089615429152b175f075790a7 Mon Sep 17 00:00:00 2001 From: Kevin Logan <56395104+kevinlog@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:53:46 -0400 Subject: [PATCH 33/98] [Security Solution] Update session viewer Policy permissions to use Policy specific check (#160448) ## Summary This PR updates the session viewer code to use the `canReadPolicyManagement ` permission as opposed to `canAccessEndpointManagement`. This is because `canAccessEndpointManagement` requires super user permissions while `canReadPolicyManagement` which is a more specific permission. ### 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: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../session_tab_content/use_session_view.test.tsx | 2 +- .../timeline/session_tab_content/use_session_view.tsx | 6 +++--- .../public/components/session_view/index.tsx | 4 ++-- .../public/components/tty_player/index.test.tsx | 4 +--- .../public/components/tty_player/index.tsx | 10 ++++------ x-pack/plugins/session_view/public/types.ts | 2 +- 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx index 805cb5bf03e8ed..6cf0474ead6dfe 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx @@ -158,7 +158,7 @@ describe('useSessionView with active timeline and a session id and graph event i height: 1000, sessionEntityId: 'test', loadAlertDetails: mockOpenDetailFn, - canAccessEndpointManagement: false, + canReadPolicyManagement: false, }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx index d2d6a82895be90..e16ac4ee9b7fdd 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx @@ -264,7 +264,7 @@ export const useSessionView = ({ }, [scopeId]); const { globalFullScreen } = useGlobalFullScreen(); const { timelineFullScreen } = useTimelineFullScreen(); - const { canAccessEndpointManagement } = useUserPrivileges().endpointPrivileges; + const { canReadPolicyManagement } = useUserPrivileges().endpointPrivileges; const defaults = isTimelineScope(scopeId) ? timelineDefaults : tableDefaults; const { sessionViewConfig, activeTab } = useDeepEqualSelector((state) => ({ @@ -309,7 +309,7 @@ export const useSessionView = ({ loadAlertDetails: openEventDetailsPanel, isFullScreen: fullScreen, height: heightMinusSearchBar, - canAccessEndpointManagement, + canReadPolicyManagement, }) : null; }, [ @@ -318,7 +318,7 @@ export const useSessionView = ({ sessionView, openEventDetailsPanel, fullScreen, - canAccessEndpointManagement, + canReadPolicyManagement, ]); return { diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index ee4bbb40891e8f..42c16c40baf5cb 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -51,7 +51,7 @@ export const SessionView = ({ jumpToCursor, investigatedAlertId, loadAlertDetails, - canAccessEndpointManagement, + canReadPolicyManagement, }: SessionViewDeps) => { // don't engage jumpTo if jumping to session leader. if (jumpToEntityId === sessionEntityId) { @@ -435,7 +435,7 @@ export const SessionView = ({ isFullscreen={isFullScreen} onJumpToEvent={onJumpToEvent} autoSeekToEntityId={currentJumpToOutputEntityId} - canAccessEndpointManagement={canAccessEndpointManagement} + canReadPolicyManagement={canReadPolicyManagement} />
); diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx index a3a17380c8fc97..42be993d39d1d4 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx @@ -107,9 +107,7 @@ describe('TTYPlayer component', () => { }); it('renders a message warning when max_bytes exceeded with link to policies page', async () => { - renderResult = mockedContext.render( - - ); + renderResult = mockedContext.render(); await waitForApiCall(); await new Promise((r) => setTimeout(r, 10)); diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.tsx index 36d685371e0234..aa85f4bd794c0b 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.tsx @@ -41,7 +41,7 @@ export interface TTYPlayerDeps { isFullscreen: boolean; onJumpToEvent(event: ProcessEvent): void; autoSeekToEntityId?: string; - canAccessEndpointManagement?: boolean; + canReadPolicyManagement?: boolean; } export const TTYPlayer = ({ @@ -53,7 +53,7 @@ export const TTYPlayer = ({ isFullscreen, onJumpToEvent, autoSeekToEntityId, - canAccessEndpointManagement, + canReadPolicyManagement, }: TTYPlayerDeps) => { const ref = useRef(null); const { ref: scrollRef, height: containerHeight = 1 } = useResizeObserver({}); @@ -71,10 +71,8 @@ export const TTYPlayer = ({ const { getUrlForApp } = useKibana().services.application; const policiesUrl = useMemo( () => - canAccessEndpointManagement - ? getUrlForApp(SECURITY_APP_ID, { path: POLICIES_PAGE_PATH }) - : '', - [canAccessEndpointManagement, getUrlForApp] + canReadPolicyManagement ? getUrlForApp(SECURITY_APP_ID, { path: POLICIES_PAGE_PATH }) : '', + [canReadPolicyManagement, getUrlForApp] ); const { search, currentLine, seekToLine } = useXtermPlayer({ diff --git a/x-pack/plugins/session_view/public/types.ts b/x-pack/plugins/session_view/public/types.ts index 3783abdfd2e8b4..846d3baaa86efb 100644 --- a/x-pack/plugins/session_view/public/types.ts +++ b/x-pack/plugins/session_view/public/types.ts @@ -34,7 +34,7 @@ export interface SessionViewDeps { // Callback used when alert flyout panel is closed handleOnAlertDetailsClosed: () => void ) => void; - canAccessEndpointManagement?: boolean; + canReadPolicyManagement?: boolean; } export interface EuiTabProps { From d6d4c6495faa77fa8ca093cdc1c92397da1713d1 Mon Sep 17 00:00:00 2001 From: Juan Pablo Djeredjian Date: Mon, 3 Jul 2023 19:22:40 +0200 Subject: [PATCH 34/98] [Security Solution] Expand prebuilt rules install/update workflow test coverage (#155241) ## Summary Extends test coverage for the current Prebuilt Rules installation and update workflows, in the Rules Management area. Follows the test plan: https://docs.google.com/document/d/1d_1DYnHlnCaPznWTjeCxhoaRUwxc2O_V0LToAPG0xLE/edit#heading=h.y4vywfmfu3ef Other changes besides the new tests: - Integration tests related to prebuilt rules were moved to a new `prebuilt_rules` dir from their old `group1` dir. - Existing Cypress tests related to prebuilt rules were renamed to `prebuilt_rules_management.cy.ts` to differentiate those tests to the new tests related to notifications, installation and updates. - Prevented the installation of the +700 prebuilt rules in test suites where it is not necessary. Replaced that with installing a low number of mock prebuilt rules, which enables to test the same functionality. - Unskipping tests in [rules_selection.cy.ts](https://github.com/elastic/kibana/blob/3d146298a43e1ba24d83e0ede2758b87e826d0b6/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts#L34). See [explanation](https://github.com/elastic/kibana/issues/154694#issuecomment-1607265120). ### 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: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .buildkite/ftr_configs.yml | 3 + .../security_solution/common/constants.ts | 1 + ...built_rules_install_update_workflows.cy.ts | 175 ++++++++++++++++++ ....cy.ts => prebuilt_rules_management.cy.ts} | 25 ++- .../prebuilt_rules_notifications.cy.ts | 117 ++++++++++++ .../e2e/detection_rules/rules_selection.cy.ts | 22 ++- .../cypress/helpers/rules.ts | 21 ++- .../cypress/screens/alerts_detection_rules.ts | 17 +- .../cypress/tasks/alerts_detection_rules.ts | 4 +- .../cypress/tasks/api_calls/prebuilt_rules.ts | 143 ++++++++++++++ .../security_solution/cypress/tasks/common.ts | 21 +++ .../cypress/tasks/prebuilt_rules.ts | 33 ++++ .../security_solution/cypress/tsconfig.json | 3 +- .../logic/prebuilt_rules/translations.ts | 2 +- .../add_prebuilt_rules_header_buttons.tsx | 6 +- .../upgrade_prebuilt_rules_table_buttons.tsx | 7 +- .../pages/rule_management/index.tsx | 6 +- ...utton.tsx => add_elastic_rules_button.tsx} | 8 +- .../pre_packaged_rules/load_empty_prompt.tsx | 6 +- .../bundled_prebuilt_rules_package/config.ts | 38 ++++ .../security_detection_engine-99.0.0.zip | Bin 0 -> 20201 bytes ...ecurity_detection_engine-99.0.1-beta.1.zip | Bin 0 -> 22554 bytes .../install_latest_bundled_prebuilt_rules.ts | 79 ++++++++ .../prerelease_packages.ts | 66 +++++++ .../security_and_spaces/group1/index.ts | 4 - .../large_prebuilt_rules_package/config.ts | 43 +++++ .../security_detection_engine-100.0.0.zip | Bin 0 -> 28775077 bytes .../install_large_prebuilt_rules_package.ts | 49 +++++ .../prebuilt_rules/config.ts | 18 ++ .../fleet_integration.ts | 0 .../get_prebuilt_rules_status.ts | 50 ++++- .../get_prebuilt_timelines_status.ts | 0 .../prebuilt_rules/index.ts | 18 ++ .../install_prebuilt_rules.ts | 0 .../test/security_solution_cypress/config.ts | 5 + 35 files changed, 955 insertions(+), 35 deletions(-) create mode 100644 x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_install_update_workflows.cy.ts rename x-pack/plugins/security_solution/cypress/e2e/detection_rules/{prebuilt_rules.cy.ts => prebuilt_rules_management.cy.ts} (89%) create mode 100644 x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_notifications.cy.ts create mode 100644 x-pack/plugins/security_solution/cypress/tasks/prebuilt_rules.ts rename x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/{load_prepackaged_rules_button.tsx => add_elastic_rules_button.tsx} (90%) create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/config.ts create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.0.zip create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.1-beta.1.zip create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/install_latest_bundled_prebuilt_rules.ts create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/prerelease_packages.ts create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/config.ts create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-100.0.0.zip create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/install_large_prebuilt_rules_package.ts create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.ts rename x-pack/test/detection_engine_api_integration/security_and_spaces/{group1 => prebuilt_rules}/fleet_integration.ts (100%) rename x-pack/test/detection_engine_api_integration/security_and_spaces/{group1 => prebuilt_rules}/get_prebuilt_rules_status.ts (78%) rename x-pack/test/detection_engine_api_integration/security_and_spaces/{group1 => prebuilt_rules}/get_prebuilt_timelines_status.ts (100%) create mode 100644 x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/index.ts rename x-pack/test/detection_engine_api_integration/security_and_spaces/{group1 => prebuilt_rules}/install_prebuilt_rules.ts (100%) diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index c83af688ed47f1..518192fbe05f3d 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -232,6 +232,9 @@ enabled: - x-pack/test/detection_engine_api_integration/security_and_spaces/group9/config.ts - x-pack/test/detection_engine_api_integration/security_and_spaces/group10/config.ts - x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/config.ts + - x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.ts + - x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/config.ts + - x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/config.ts - x-pack/test/encrypted_saved_objects_api_integration/config.ts - x-pack/test/examples/config.ts - x-pack/test/fleet_api_integration/config.agent.ts diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 14a48f78afe3e2..a311cae265f33b 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -165,6 +165,7 @@ export const ALERT_DETAILS_REDIRECT_PATH = `${ALERTS_PATH}/redirect` as const; export const RULES_PATH = '/rules' as const; export const RULES_LANDING_PATH = `${RULES_PATH}/landing` as const; export const RULES_ADD_PATH = `${RULES_PATH}/add_rules` as const; +export const RULES_UPDATES = `${RULES_PATH}/updates` as const; export const RULES_CREATE_PATH = `${RULES_PATH}/create` as const; export const EXCEPTIONS_PATH = '/exceptions' as const; export const EXCEPTION_LIST_DETAIL_PATH = `${EXCEPTIONS_PATH}/details/:detailName` as const; diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_install_update_workflows.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_install_update_workflows.cy.ts new file mode 100644 index 00000000000000..bec5b77de52c9a --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_install_update_workflows.cy.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { BulkInstallPackageInfo } from '@kbn/fleet-plugin/common'; +import type { Rule } from '../../../public/detection_engine/rule_management/logic/types'; +import { createRuleAssetSavedObject } from '../../helpers/rules'; +import { + GO_BACK_TO_RULES_TABLE_BUTTON, + INSTALL_ALL_RULES_BUTTON, + INSTALL_SELECTED_RULES_BUTTON, + RULES_MANAGEMENT_TABLE, + RULES_ROW, + RULES_UPDATES_TABLE, + SELECT_ALL_RULES_ON_PAGE_CHECKBOX, + TOASTER, +} from '../../screens/alerts_detection_rules'; +import { waitForRulesTableToBeLoaded } from '../../tasks/alerts_detection_rules'; +import { + getRuleAssets, + createAndInstallMockedPrebuiltRules, +} from '../../tasks/api_calls/prebuilt_rules'; +import { resetRulesTableState, deleteAlertsAndRules, reload } from '../../tasks/common'; +import { esArchiverResetKibana } from '../../tasks/es_archiver'; +import { login, visitWithoutDateRange } from '../../tasks/login'; +import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation'; +import { + addElasticRulesButtonClick, + assertRuleUpgradeAvailableAndUpgradeAll, + ruleUpdatesTabClick, +} from '../../tasks/prebuilt_rules'; + +describe('Detection rules, Prebuilt Rules Installation and Update workflow', () => { + beforeEach(() => { + login(); + resetRulesTableState(); + deleteAlertsAndRules(); + esArchiverResetKibana(); + + visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); + }); + + describe('Installation of prebuilt rules package via Fleet', () => { + beforeEach(() => { + cy.intercept('POST', '/api/fleet/epm/packages/_bulk*').as('installPackage'); + waitForRulesTableToBeLoaded(); + }); + + it('should install package from Fleet in the background', () => { + /* Assert that the package in installed from Fleet by checking that + /* the installSource is "registry", as opposed to "bundle" */ + cy.wait('@installPackage', { + timeout: 60000, + }).then(({ response }) => { + cy.wrap(response?.statusCode).should('eql', 200); + + const packages = response?.body.items.map(({ name, result }: BulkInstallPackageInfo) => ({ + name, + installSource: result.installSource, + })); + + expect(packages.length).to.have.greaterThan(0); + expect(packages).to.deep.include.members([ + { name: 'security_detection_engine', installSource: 'registry' }, + ]); + }); + }); + + it('should install rules from the Fleet package when user clicks on CTA', () => { + /* Retrieve how many rules were installed from the Fleet package */ + cy.wait('@installPackage', { + timeout: 60000, + }).then(() => { + getRuleAssets().then((response) => { + const ruleIds = response.body.hits.hits.map( + (hit: { _source: { ['security-rule']: Rule } }) => hit._source['security-rule'].rule_id + ); + + const numberOfRulesToInstall = new Set(ruleIds).size; + addElasticRulesButtonClick(); + + cy.get(INSTALL_ALL_RULES_BUTTON).click(); + cy.get(TOASTER) + .should('be.visible') + .should('have.text', `${numberOfRulesToInstall} rules installed successfully.`); + }); + }); + }); + }); + + describe('Installation of prebuilt rules', () => { + const RULE_1 = createRuleAssetSavedObject({ + name: 'Test rule 1', + rule_id: 'rule_1', + }); + const RULE_2 = createRuleAssetSavedObject({ + name: 'Test rule 2', + rule_id: 'rule_2', + }); + beforeEach(() => { + createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false }); + waitForRulesTableToBeLoaded(); + }); + + it('should install selected rules when user clicks on Install selected rules', () => { + addElasticRulesButtonClick(); + cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); + cy.get(INSTALL_SELECTED_RULES_BUTTON).click(); + cy.get(TOASTER).should('be.visible').should('have.text', `2 rules installed successfully.`); + cy.get(GO_BACK_TO_RULES_TABLE_BUTTON).click(); + cy.get(RULES_MANAGEMENT_TABLE).find(RULES_ROW).should('have.length', 2); + cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_1['security-rule'].name); + cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_2['security-rule'].name); + }); + + it('should fail gracefully with toast error message when request to install rules fails', () => { + /* Stub request to force rules installation to fail */ + cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform', { + statusCode: 500, + }).as('installPrebuiltRules'); + addElasticRulesButtonClick(); + cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); + cy.get(INSTALL_SELECTED_RULES_BUTTON).click(); + cy.wait('@installPrebuiltRules'); + cy.get(TOASTER).should('be.visible').should('have.text', 'Rule installation failed'); + }); + }); + + describe('Update of prebuilt rules', () => { + const RULE_ID = 'rule_id'; + const OUTDATED_RULE = createRuleAssetSavedObject({ + name: 'Outdated rule', + rule_id: RULE_ID, + version: 1, + }); + const UPDATED_RULE = createRuleAssetSavedObject({ + name: 'Updated rule', + rule_id: RULE_ID, + version: 2, + }); + beforeEach(() => { + /* Create a new rule and install it */ + createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE] }); + /* Create a second version of the rule, making it available for update */ + createAndInstallMockedPrebuiltRules({ rules: [UPDATED_RULE], installToKibana: false }); + waitForRulesTableToBeLoaded(); + reload(); + }); + + it('should update rule succesfully', () => { + cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform').as( + 'updatePrebuiltRules' + ); + ruleUpdatesTabClick(); + assertRuleUpgradeAvailableAndUpgradeAll(OUTDATED_RULE); + cy.get(TOASTER).should('be.visible').should('have.text', `1 rule updated successfully.`); + }); + + it('should fail gracefully with toast error message when request to update rules fails', () => { + /* Stub request to force rules update to fail */ + cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform', { + statusCode: 500, + }).as('updatePrebuiltRules'); + ruleUpdatesTabClick(); + assertRuleUpgradeAvailableAndUpgradeAll(OUTDATED_RULE); + cy.get(TOASTER).should('be.visible').should('have.text', 'Rule update failed'); + + /* Assert that the rule has not been updated in the UI */ + cy.get(RULES_UPDATES_TABLE).should('contain', OUTDATED_RULE['security-rule'].name); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_management.cy.ts similarity index 89% rename from x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules.cy.ts rename to x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_management.cy.ts index 024797b7fde789..f36d8f7fa0948c 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_management.cy.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { createRuleAssetSavedObject } from '../../helpers/rules'; import { COLLAPSED_ACTION_BTN, ELASTIC_RULES_BTN, - LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN, + ADD_ELASTIC_RULES_BTN, RULES_EMPTY_PROMPT, RULES_MONITORING_TAB, RULES_ROW, @@ -29,13 +30,20 @@ import { waitForRuleToUpdate, } from '../../tasks/alerts_detection_rules'; import { - excessivelyInstallAllPrebuiltRules, + createAndInstallMockedPrebuiltRules, getAvailablePrebuiltRulesCount, } from '../../tasks/api_calls/prebuilt_rules'; -import { cleanKibana, deleteAlertsAndRules } from '../../tasks/common'; +import { cleanKibana, deleteAlertsAndRules, deletePrebuiltRulesAssets } from '../../tasks/common'; import { login, visitWithoutDateRange } from '../../tasks/login'; import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../urls/navigation'; +const rules = Array.from(Array(5)).map((_, i) => { + return createRuleAssetSavedObject({ + name: `Test rule ${i + 1}`, + rule_id: `rule_${i + 1}`, + }); +}); + describe('Prebuilt rules', () => { before(() => { cleanKibana(); @@ -44,8 +52,9 @@ describe('Prebuilt rules', () => { beforeEach(() => { login(); deleteAlertsAndRules(); + deletePrebuiltRulesAssets(); visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - excessivelyInstallAllPrebuiltRules(); + createAndInstallMockedPrebuiltRules({ rules }); cy.reload(); waitForPrebuiltDetectionRulesToBeLoaded(); }); @@ -114,10 +123,10 @@ describe('Prebuilt rules', () => { 'have.text', `Elastic rules (${expectedNumberOfRulesAfterDeletion})` ); - cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should('have.text', `Add Elastic rules1`); + cy.get(ADD_ELASTIC_RULES_BTN).should('have.text', `Add Elastic rules1`); // Navigate to the prebuilt rule installation page - cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).click(); + cy.get(ADD_ELASTIC_RULES_BTN).click(); // Click the "Install all rules" button cy.get(INSTALL_ALL_RULES_BUTTON).click(); @@ -144,7 +153,7 @@ describe('Prebuilt rules', () => { selectNumberOfRules(numberOfRulesToBeSelected); deleteSelectedRules(); - cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should( + cy.get(ADD_ELASTIC_RULES_BTN).should( 'have.text', `Add Elastic rules${numberOfRulesToBeSelected}` ); @@ -154,7 +163,7 @@ describe('Prebuilt rules', () => { ); // Navigate to the prebuilt rule installation page - cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).click(); + cy.get(ADD_ELASTIC_RULES_BTN).click(); // Click the "Install all rules" button cy.get(INSTALL_ALL_RULES_BUTTON).click(); diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_notifications.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_notifications.cy.ts new file mode 100644 index 00000000000000..782298088244f0 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_notifications.cy.ts @@ -0,0 +1,117 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { createRuleAssetSavedObject } from '../../helpers/rules'; +import { ADD_ELASTIC_RULES_BTN, RULES_UPDATES_TAB } from '../../screens/alerts_detection_rules'; +import { deleteFirstRule, waitForRulesTableToBeLoaded } from '../../tasks/alerts_detection_rules'; +import { + installAllPrebuiltRulesRequest, + createAndInstallMockedPrebuiltRules, +} from '../../tasks/api_calls/prebuilt_rules'; +import { resetRulesTableState, deleteAlertsAndRules, reload } from '../../tasks/common'; +import { login, visitWithoutDateRange } from '../../tasks/login'; +import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation'; + +describe('Detection rules, Prebuilt Rules Installation and Update workflow', () => { + beforeEach(() => { + login(); + /* Make sure persisted rules table state is cleared */ + resetRulesTableState(); + deleteAlertsAndRules(); + + const RULE_1 = createRuleAssetSavedObject({ + name: 'Test rule 1', + rule_id: 'rule_1', + }); + createAndInstallMockedPrebuiltRules({ rules: [RULE_1], installToKibana: false }); + }); + + describe('Rules installation notification when no rules have been installed', () => { + beforeEach(() => { + visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); + }); + + it('should notify user about prebuilt rules available for installation', () => { + cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); + }); + }); + + describe('No notifications', () => { + it('should display no install or update notifications when latest rules are installed', () => { + /* Install current available rules */ + installAllPrebuiltRulesRequest(); + visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); + waitForRulesTableToBeLoaded(); + + /* Assert that there are no installation or update notifications */ + /* Add Elastic Rules button and Rule Upgrade tabs should not contain a number badge */ + cy.get(ADD_ELASTIC_RULES_BTN).should('have.text', 'Add Elastic rules'); + cy.get(RULES_UPDATES_TAB).should('have.text', 'Rule Updates'); + }); + }); + + describe('Rule installation notification when at least one rule already installed', () => { + beforeEach(() => { + installAllPrebuiltRulesRequest(); + /* Create new rule assets with a different rule_id as the one that was */ + /* installed before in order to trigger the installation notification */ + const RULE_2 = createRuleAssetSavedObject({ + name: 'Test rule 2', + rule_id: 'rule_2', + }); + const RULE_3 = createRuleAssetSavedObject({ + name: 'Test rule 3', + rule_id: 'rule_3', + }); + + createAndInstallMockedPrebuiltRules({ rules: [RULE_2, RULE_3], installToKibana: false }); + visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); + waitForRulesTableToBeLoaded(); + }); + + it('should notify user about prebuilt rules package available for installation', () => { + const numberOfAvailableRules = 2; + cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); + cy.get(ADD_ELASTIC_RULES_BTN).should( + 'have.text', + `Add Elastic rules${numberOfAvailableRules}` + ); + }); + + it('should notify user a rule is again available for installation if it is deleted', () => { + /* Install available rules, assert that the notification is gone */ + /* then delete one rule and assert that the notification is back */ + installAllPrebuiltRulesRequest(); + reload(); + deleteFirstRule(); + cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); + cy.get(ADD_ELASTIC_RULES_BTN).should('have.text', `Add Elastic rules${1}`); + }); + }); + + describe('Rule update notification', () => { + beforeEach(() => { + installAllPrebuiltRulesRequest(); + /* Create new rule asset with the same rule_id as the one that was installed */ + /* but with a higher version, in order to trigger the update notification */ + const UPDATED_RULE = createRuleAssetSavedObject({ + name: 'Test rule 1.1 (updated)', + rule_id: 'rule_1', + version: 2, + }); + createAndInstallMockedPrebuiltRules({ rules: [UPDATED_RULE], installToKibana: false }); + visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); + waitForRulesTableToBeLoaded(); + reload(); + }); + + it('should notify user about prebuilt rules package available for update', () => { + cy.get(RULES_UPDATES_TAB).should('be.visible'); + cy.get(RULES_UPDATES_TAB).should('have.text', `Rule Updates${1}`); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts index 43d2445b318b02..848fd94ad94ed9 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { createRuleAssetSavedObject } from '../../helpers/rules'; import { SELECTED_RULES_NUMBER_LABEL, SELECT_ALL_RULES_BTN, @@ -17,17 +18,32 @@ import { import { excessivelyInstallAllPrebuiltRules, getAvailablePrebuiltRulesCount, + createAndInstallMockedPrebuiltRules, } from '../../tasks/api_calls/prebuilt_rules'; import { cleanKibana } from '../../tasks/common'; import { login, visitWithoutDateRange } from '../../tasks/login'; import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../urls/navigation'; -// TODO: See https://github.com/elastic/kibana/issues/154694 -describe.skip('Rules selection', () => { - beforeEach(() => { +const RULE_1 = createRuleAssetSavedObject({ + name: 'Test rule 1', + rule_id: 'rule_1', +}); +const RULE_2 = createRuleAssetSavedObject({ + name: 'Test rule 2', + rule_id: 'rule_2', +}); + +describe('Rules selection', () => { + before(() => { cleanKibana(); + }); + + beforeEach(() => { login(); + /* Create and install two mock rules */ + createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2] }); visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); + waitForPrebuiltDetectionRulesToBeLoaded(); }); it('should correctly update the selection label when rules are individually selected and unselected', () => { diff --git a/x-pack/plugins/security_solution/cypress/helpers/rules.ts b/x-pack/plugins/security_solution/cypress/helpers/rules.ts index b8ad823d669cf9..a9a65943013847 100644 --- a/x-pack/plugins/security_solution/cypress/helpers/rules.ts +++ b/x-pack/plugins/security_solution/cypress/helpers/rules.ts @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import dateMath from '@kbn/datemath'; import moment from 'moment'; +import type { PrebuiltRuleAsset } from '../../server/lib/detection_engine/prebuilt_rules'; +import { getPrebuiltRuleMock } from '../../server/lib/detection_engine/prebuilt_rules/mocks'; import type { ThreatArray } from '../../common/detection_engine/rule_schema'; @@ -77,3 +78,21 @@ export const convertHistoryStartToSize = (relativeTime: string) => { return relativeTime; } }; + +/** + * A helper function to create a rule asset saved object (type: security-rule) + * + * @param overrideParams Params to override the default mock + * @returns Created rule asset saved object + */ +export const createRuleAssetSavedObject = (overrideParams: Partial) => ({ + 'security-rule': { + ...getPrebuiltRuleMock(), + ...overrideParams, + }, + type: 'security-rule', + references: [], + coreMigrationVersion: '8.6.0', + updated_at: '2022-11-01T12:56:39.717Z', + created_at: '2022-11-01T12:56:39.717Z', +}); diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts index a4383b48d2dd0d..2a83a70338e5e0 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts @@ -59,12 +59,21 @@ export const INTEGRATIONS_POPOVER = '[data-test-subj="IntegrationsDisplayPopover export const INTEGRATIONS_POPOVER_TITLE = '[data-test-subj="IntegrationsPopoverTitle"]'; -export const LOAD_PREBUILT_RULES_BTN = '[data-test-subj="load-prebuilt-rules"]'; +export const ADD_ELASTIC_RULES_BTN = '[data-test-subj="addElasticRulesButton"]'; -export const LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN = '[data-test-subj="loadPrebuiltRulesBtn"]'; +export const ADD_ELASTIC_RULES_EMPTY_PROMPT_BTN = + '[data-test-subj="add-elastc-rules-empty-empty-prompt-button"]'; export const INSTALL_ALL_RULES_BUTTON = '[data-test-subj="installAllRulesButton"]'; +export const INSTALL_SELECTED_RULES_BUTTON = '[data-test-subj="installSelectedRulesButton"]'; + +export const UPGRADE_ALL_RULES_BUTTON = '[data-test-subj="upgradeAllRulesButton"]'; + +export const UPGRADE_SELECTED_RULES_BUTTON = '[data-test-subj="upgradeSelectedRulesButton"]'; + +export const GO_BACK_TO_RULES_TABLE_BUTTON = '[data-test-subj="addRulesGoBackToRulesTableBtn"]'; + export const RULES_TABLE_INITIAL_LOADING_INDICATOR = '[data-test-subj="initialLoadingPanelAllRulesTable"]'; @@ -90,10 +99,14 @@ export const RULES_MANAGEMENT_TAB = '[data-test-subj="navigation-management"]'; export const RULES_MONITORING_TAB = '[data-test-subj="navigation-monitoring"]'; +export const RULES_UPDATES_TAB = '[data-test-subj="navigation-updates"]'; + export const RULES_MANAGEMENT_TABLE = '[data-test-subj="rules-management-table"]'; export const RULES_MONITORING_TABLE = '[data-test-subj="rules-monitoring-table"]'; +export const RULES_UPDATES_TABLE = '[data-test-subj="rules-upgrades-table"]'; + export const RULES_ROW = '.euiTableRow'; export const SEVERITY = '[data-test-subj="severity"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts index 7f4a8fcacd0b10..97dbdad4506a9b 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts @@ -13,7 +13,6 @@ import { DELETE_RULE_ACTION_BTN, DELETE_RULE_BULK_BTN, RULES_SELECTED_TAG, - LOAD_PREBUILT_RULES_BTN, RULES_TABLE_INITIAL_LOADING_INDICATOR, RULES_TABLE_AUTOREFRESH_INDICATOR, RULE_CHECKBOX, @@ -65,6 +64,7 @@ import { DUPLICATE_WITH_EXCEPTIONS_OPTION, DUPLICATE_WITH_EXCEPTIONS_WITHOUT_EXPIRED_OPTION, TOASTER_CLOSE_ICON, + ADD_ELASTIC_RULES_EMPTY_PROMPT_BTN, } from '../screens/alerts_detection_rules'; import type { RULES_MONITORING_TABLE } from '../screens/alerts_detection_rules'; import { EUI_CHECKBOX } from '../screens/common/controls'; @@ -336,7 +336,7 @@ export const waitForRulesTableToBeRefreshed = () => { export const waitForPrebuiltDetectionRulesToBeLoaded = () => { cy.log('Wait for prebuilt rules to be loaded'); - cy.get(LOAD_PREBUILT_RULES_BTN, { timeout: 300000 }).should('not.exist'); + cy.get(ADD_ELASTIC_RULES_EMPTY_PROMPT_BTN, { timeout: 300000 }).should('not.exist'); cy.get(RULES_MANAGEMENT_TABLE).should('exist'); cy.get(RULES_TABLE_REFRESH_INDICATOR).should('not.exist'); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts index 424426e91d793a..1a079cb43ec20d 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts @@ -5,7 +5,10 @@ * 2.0. */ +import { ELASTIC_SECURITY_RULE_ID } from '../../../common/detection_engine/constants'; import type { PrePackagedRulesStatusResponse } from '../../../public/detection_engine/rule_management/logic/types'; +import { getPrebuiltRuleWithExceptionsMock } from '../../../server/lib/detection_engine/prebuilt_rules/mocks'; +import { createRuleAssetSavedObject } from '../../helpers/rules'; export const getPrebuiltRulesStatus = () => { return cy.request({ @@ -15,6 +18,18 @@ export const getPrebuiltRulesStatus = () => { }); }; +export const SAMPLE_PREBUILT_RULE = createRuleAssetSavedObject({ + ...getPrebuiltRuleWithExceptionsMock(), + rule_id: ELASTIC_SECURITY_RULE_ID, + tags: ['test-tag-1'], + enabled: true, +}); + +/* Install all prebuilt rules available as security-rule saved objects + * Use in combination with `preventPrebuiltRulesPackageInstallation` and + * `createNewRuleAsset` to create mocked prebuilt rules and install only those + * instead of all rules available in the `security_detection_engine` package + */ export const installAllPrebuiltRulesRequest = () => { return cy.request({ method: 'POST', @@ -58,3 +73,131 @@ export const excessivelyInstallAllPrebuiltRules = () => { waitTillPrebuiltRulesReadyToInstall(); installAllPrebuiltRulesRequest(); }; + +export const createNewRuleAsset = ({ + index = '.kibana_security_solution', + rule = SAMPLE_PREBUILT_RULE, +}: { + index?: string; + rule?: typeof SAMPLE_PREBUILT_RULE; +}) => { + const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_doc/security-rule:${ + rule['security-rule'].rule_id + }`; + cy.waitUntil( + () => { + return cy + .request({ + method: 'PUT', + url, + headers: { 'kbn-xsrf': 'cypress-creds', 'Content-Type': 'application/json' }, + failOnStatusCode: false, + body: rule, + }) + .then((response) => response.status === 200); + }, + { interval: 500, timeout: 12000 } + ); +}; + +export const bulkCreateRuleAssets = ({ + index = '.kibana_security_solution', + rules = [SAMPLE_PREBUILT_RULE], +}: { + index?: string; + rules?: Array; +}) => { + const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_bulk`; + + const bulkIndexRequestBody = rules.reduce((body, rule) => { + const indexOperation = { + index: { + _index: index, + _id: rule['security-rule'].rule_id, + }, + }; + + const documentData = JSON.stringify(rule); + + return body.concat(JSON.stringify(indexOperation), '\n', documentData, '\n'); + }, ''); + + cy.request({ + method: 'PUT', + url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_mapping`, + body: { + dynamic: true, + }, + headers: { + 'Content-Type': 'application/json', + }, + }); + + cy.waitUntil( + () => { + return cy + .request({ + method: 'POST', + url, + headers: { 'kbn-xsrf': 'cypress-creds', 'Content-Type': 'application/json' }, + failOnStatusCode: false, + body: bulkIndexRequestBody, + }) + .then((response) => response.status === 200); + }, + { interval: 500, timeout: 12000 } + ); +}; + +export const getRuleAssets = (index: string | undefined = '.kibana_security_solution') => { + const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_search?size=10000`; + return cy.request({ + method: 'GET', + url, + headers: { 'kbn-xsrf': 'cypress-creds', 'Content-Type': 'application/json' }, + failOnStatusCode: false, + body: { + query: { + term: { type: { value: 'security-rule' } }, + }, + }, + }); +}; + +/* Prevent the installation of the `security_detection_engine` package from Fleet +/* by intercepting the request and returning a mock empty object as response +/* Used primarily to prevent the unwanted installation of "real" prebuilt rules +/* during e2e tests, and allow for manual installation of mock rules instead. */ +export const preventPrebuiltRulesPackageInstallation = () => { + cy.intercept('POST', '/api/fleet/epm/packages/_bulk*', {}); +}; + +/** + * Prevent the installation of the `security_detection_engine` package from Fleet. + * The create a `security-rule` asset for each rule provided in the `rules` array. + * Optionally install the rules to Kibana, with a flag defaulting to true + * Explicitly set the `installToKibana` flag to false in cases when needing to + * make mock rules available for installation or update, but do those operations manually + * + * * @param {Array} rules - Rule assets to be created and optionally installed + * + * * @param {string} installToKibana - Flag to decide whether to install the rules as 'alerts' SO. Defaults to true. + */ +export const createAndInstallMockedPrebuiltRules = ({ + rules, + installToKibana = true, +}: { + rules?: Array; + installToKibana?: boolean; +}) => { + cy.log('Install prebuilt rules'); + preventPrebuiltRulesPackageInstallation(); + // TODO: use this bulk method once the issue with Cypress is fixed + // bulkCreateRuleAssets({ rules }); + rules?.forEach((rule) => { + createNewRuleAsset({ rule }); + }); + if (installToKibana) { + installAllPrebuiltRulesRequest(); + } +}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts index 08518c2049f1c4..1767b70fe33fec 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common.ts @@ -218,6 +218,27 @@ export const deleteConnectors = () => { }); }; +export const deletePrebuiltRulesAssets = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'security-rule', + }, + }, + ], + }, + }, + }, + }); +}; + export const postDataView = (dataSource: string) => { rootRequest({ method: 'POST', diff --git a/x-pack/plugins/security_solution/cypress/tasks/prebuilt_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/prebuilt_rules.ts new file mode 100644 index 00000000000000..5035b50acaff95 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/tasks/prebuilt_rules.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RULES_ADD_PATH, RULES_UPDATES } from '../../common/constants'; +import { + ADD_ELASTIC_RULES_BTN, + RULES_ROW, + RULES_UPDATES_TAB, + RULES_UPDATES_TABLE, + UPGRADE_ALL_RULES_BUTTON, +} from '../screens/alerts_detection_rules'; +import type { SAMPLE_PREBUILT_RULE } from './api_calls/prebuilt_rules'; + +export const addElasticRulesButtonClick = () => { + cy.get(ADD_ELASTIC_RULES_BTN).click(); + cy.location('pathname').should('include', RULES_ADD_PATH); +}; + +export const ruleUpdatesTabClick = () => { + cy.get(RULES_UPDATES_TAB).click(); + cy.location('pathname').should('include', RULES_UPDATES); +}; + +export const assertRuleUpgradeAvailableAndUpgradeAll = (rule: typeof SAMPLE_PREBUILT_RULE) => { + cy.get(RULES_UPDATES_TABLE).find(RULES_ROW).should('have.length', 1); + cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name); + cy.get(UPGRADE_ALL_RULES_BUTTON).click(); + cy.wait('@updatePrebuiltRules'); +}; diff --git a/x-pack/plugins/security_solution/cypress/tsconfig.json b/x-pack/plugins/security_solution/cypress/tsconfig.json index bbe065934c0666..b1ba42799a478c 100644 --- a/x-pack/plugins/security_solution/cypress/tsconfig.json +++ b/x-pack/plugins/security_solution/cypress/tsconfig.json @@ -36,6 +36,7 @@ "@kbn/cases-plugin", "@kbn/data-plugin", "@kbn/core-http-common", - "@kbn/data-views-plugin" + "@kbn/data-views-plugin", + "@kbn/fleet-plugin", ] } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/translations.ts index 2e6e0c622301e6..965bb48a8c979a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/translations.ts @@ -36,7 +36,7 @@ export const INSTALL_RULE_FAILED = (failed: number) => export const RULE_UPGRADE_FAILED = i18n.translate( 'xpack.securitySolution.detectionEngine.prebuiltRules.toast.ruleUpgradeFailed', { - defaultMessage: 'Rule upgrade failed', + defaultMessage: 'Rule update failed', } ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx index b9fd334e9393c1..8e38be7b45db87 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_header_buttons.tsx @@ -27,7 +27,11 @@ export const AddPrebuiltRulesHeaderButtons = () => { {shouldDisplayInstallSelectedRulesButton ? ( - + {i18n.INSTALL_SELECTED_RULES(numberOfSelectedRules)} {isRuleInstalling ? : undefined} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx index 5dfff6c5fc462d..b0d305dd0cf695 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx @@ -27,7 +27,11 @@ export const UpgradePrebuiltRulesTableButtons = () => { {shouldDisplayUpgradeSelectedRulesButton ? ( - + <> {i18n.UPDATE_SELECTED_RULES(numberOfSelectedRules)} {isRuleUpgrading ? : undefined} @@ -41,6 +45,7 @@ export const UpgradePrebuiltRulesTableButtons = () => { iconType="plusInCircle" onClick={upgradeAllRules} disabled={!isRulesAvailableForUpgrade || isRequestInProgress} + data-test-subj="upgradeAllRulesButton" > {i18n.UPDATE_ALL} {isRuleUpgrading ? : undefined} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index ba68f2ef3eb368..43c09c7bf451ce 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -20,9 +20,9 @@ import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { MissingPrivilegesCallOut } from '../../../../detections/components/callouts/missing_privileges_callout'; import { MlJobCompatibilityCallout } from '../../../../detections/components/callouts/ml_job_compatibility_callout'; import { NeedAdminForUpdateRulesCallOut } from '../../../../detections/components/callouts/need_admin_for_update_callout'; -import { LoadPrePackagedRulesButton } from '../../../../detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button'; -import { useUserData } from '../../../../detections/components/user_info'; +import { AddElasticRulesButton } from '../../../../detections/components/rules/pre_packaged_rules/add_elastic_rules_button'; import { ValueListsFlyout } from '../../../../detections/components/value_lists_management_flyout'; +import { useUserData } from '../../../../detections/components/user_info'; import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; import { redirectToDetections } from '../../../../detections/pages/detection_engine/rules/helpers'; import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; @@ -106,7 +106,7 @@ const RulesPageComponent: React.FC = () => { - + diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/add_elastic_rules_button.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx rename to x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/add_elastic_rules_button.tsx index 76e3a6e3556676..014ba9d2c53e82 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/add_elastic_rules_button.tsx @@ -14,17 +14,17 @@ import { useGetSecuritySolutionLinkProps } from '../../../../common/components/l import { SecurityPageName } from '../../../../../common'; import { usePrebuiltRulesStatus } from '../../../../detection_engine/rule_management/logic/prebuilt_rules/use_prebuilt_rules_status'; -interface LoadPrePackagedRulesButtonProps { +interface AddElasticRulesButtonProps { 'data-test-subj'?: string; fill?: boolean; showBadge?: boolean; } -export const LoadPrePackagedRulesButton = ({ - 'data-test-subj': dataTestSubj = 'loadPrebuiltRulesBtn', +export const AddElasticRulesButton = ({ + 'data-test-subj': dataTestSubj = 'addElasticRulesButton', fill, showBadge = true, -}: LoadPrePackagedRulesButtonProps) => { +}: AddElasticRulesButtonProps) => { const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); const { onClick: onClickLink } = getSecuritySolutionLinkProps({ deepLinkId: SecurityPageName.rulesAdd, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx index da6ccd39753c8b..803aa86b8d88d8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx @@ -8,7 +8,7 @@ import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { memo } from 'react'; import styled from 'styled-components'; -import { LoadPrePackagedRulesButton } from './load_prepackaged_rules_button'; +import { AddElasticRulesButton } from './add_elastic_rules_button'; import * as i18n from './translations'; const EmptyPrompt = styled(EuiEmptyPrompt)` @@ -26,9 +26,9 @@ const PrePackagedRulesPromptComponent = () => { actions={ - diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/config.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/config.ts new file mode 100644 index 00000000000000..28f71daa1f0f4c --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/config.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 { FtrConfigProviderContext } from '@kbn/test'; +import path from 'path'; + +export const BUNDLED_PACKAGE_DIR = path.join( + path.dirname(__filename), + './fleet_bundled_packages/fixtures' +); + +// eslint-disable-next-line import/no-default-export +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile(require.resolve('../config.base.ts')); + + return { + ...functionalConfig.getAll(), + testFiles: [ + require.resolve('./prerelease_packages.ts'), + require.resolve('./install_latest_bundled_prebuilt_rules.ts'), + ], + kbnTestServer: { + ...functionalConfig.get('kbnTestServer'), + serverArgs: [ + ...functionalConfig.get('kbnTestServer.serverArgs'), + /* Tests in this directory simulate an air-gapped environment in which the instance doesn't have access to EPR. + * To do that, we point the Fleet url to an invalid URL, and instruct Fleet to fetch bundled packages at the + * location defined in BUNDLED_PACKAGE_DIR. + */ + `--xpack.fleet.registryUrl=http://invalidURL:8080`, + `--xpack.fleet.developer.bundledPackageLocation=${BUNDLED_PACKAGE_DIR}`, + ], + }, + }; +} diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.0.zip b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..7c725ce134e426990f7084dfa290c84cf151a490 GIT binary patch literal 20201 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
uJ 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 JZ+@SS{vVP4BDw$o literal 0 HcmV?d00001 diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.1-beta.1.zip b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-99.0.1-beta.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..d9f1118bca0325a07411b5409c13ed4aa689129c GIT binary patch literal 22554 zcmeHP&5t8VR`;+wup}T>Vh$WY3fze8E}Utno&G9y_sCV{>NZ_pa=B-Am>F8>%&;q` z(wW}ObbTyZLErcT5E3BZ(nt2fjX!_`hrJ*q4&3&#r$yqz5%GHw8R@jEs>@YVv(*w^ z(=}yhM!tC8??uFWdGO*}-~OmTKbyyY`-%9F{_kPoR|_$BW|5bizjArPox}@+S3DSd z0oU7Yqhgr)kSDfbmR}A&EPU`^r+?%g2yoxI1YGR~;C6bO-Mz!Ek(?zN8O4Y?nl z8UplYI6aTN@lm31)wBTs%h|(-jUziqVhNrFVW9If#|Hu@m@^8`Z9h5JN0_$6PQ%D| zPd%5HG#VGrh7yQ9^l_IiC4d!=ctlsy83eks7y}$2Qev(bCy_UtCAc!NkGW=_*q$#z z5E0XePeCtpdE}kg3DBT0(ME(0Scc3_XWtHnGzfv~}^ zBMw4@6y+raH->gaXXnsm=p7iW`WRs z+lMJEvjsBG6EX=&jLwlAjPVz|my8A!$BUfV9Xih)w; z?bPfJ>;$}x-)3wQIOH-5pzVTdQ}GmYeA|Oj&jmvQvjZ)A0^f(+2`8k5WNSboyNAzY zSS5C3Lo5^Ej2XxPWA6Ll$p{9@Mq#AIHrcH=nTAm!tVBE@ze6I6Qoq95XcW-8(%J-r z!L1ZKgAI=6-yFYdiV;EpdEn9ygC?mAxJC2|-_8RU8aJ76*MoZa=ZcU;3Supu!5i8V z`^zU?hD2Bh_sYTmoISGr5#dhU(NgZnAhMU*k901xIAMr-Wa@%RpfwEOr;kE5=7=T0 z0lt3D1*lhQcuE#*6onI-N3;F-!c#foF?}jEA!z9&6cia0Cxng{AZWp3L*Il*g;s!@ zK!jYioPO?q;CCj-8z8FGGcb7FLl9oF3NL`}9g#5yuCE*0H93&gydx`)T+DGh=0H8o=v=ljn zCSzL4RzgCUT835$+>qhJ;S{$ik;!gKoOAvm2sKax9t(ceD$KRdp9*3;UE<8lJ`_!aqwN$=6Y=pvZ;91bIg|BcFfHkX%v%2x}#iPZLNfr3E1i{7G-% zfPKs_gANISd+ljtZ*2|y!YmO7LLzDqe9-72+nj+yFeSxVWcmVU z$~rSOQb01-FL9>HB#-3du=WrFf?-Z0k0)UiA9>SUI;8j-Mq@khekdJ=Fd`Bt<=Z6H z5}RTnAlDkXfy7(*NZ}tv5DbAh8IVSKdltT+atM%gZzN`(--Iqs5O36d;V}rLmPf~6 zYisEU&^X~(Sg`Ok0N+3g=}azDCLaqwLd>*dWX;0gBVAI=NY!o%Lx%!}$b;cH5Hm1P zCha0<3u_CZMHDcQj-DVjrEC&Zz*!ItnsDByUJNI=nNo+ej7%a0iJ3^81b!|mW$K`V zn4nNqmovW)%#=M5DM~FROP4~z+8T@~V+`bvr3ti-o=5CSS(<|p@gK}QVFVPZ!9I+f zJA8p_mfmJyvn%i!>8b_{L;fqRCq~-m!}o|}J2td~7r*kI@xT4#tB-!OP@vzdSKrke ztiJd52UveEEWWqY@}Ko*KC=4x61Q5Znk-$L$J~w(@-~c5K%TDaSoXp%z$V-ogg=C$ z;#n3E1U5u0f~N_x)%zGOayG=meNx`=XMDiz$&NjY%Q5Lxz%Zy1i)`2H09zgHp0#Ue8*vWJz1 zix4^->9*_Gy4AAr$!WIr(a0THPHkxNw*5%Ji$bx&-11_PW<#?9Z(zsAKGx!ZGhE{)GeoN>%;b_uGed$ifuM4O`DsKG!62c@1e|f?xFLDRV!wjb=}a8V13Vc6vlRm z?fdqKJ;!E2h-j!CPyz)WfhtIywg%v1(v+`+d>9)$U?i665iQl>3q%BgzrzFJFtHKt zD6GICiPReY0AMm7LCy=lFLY>$;KB!BaStt$o_*wzjz1))Qanu8@x@1C5|<IxN_$4}(c(4`JbCI1 zgJhd`7Hbb_Z-aO)$WwVOv0Dg$(z8^mGXG>TR#CoOrivvA<@4n8 zkzL892&l_#@}xO}TB2k^fX^B{@3O=F?ZKy=ewXzQ*+GB*lipT$ixoSE_+BirPkV#s z`!5F!Bl?}a!DnoLn|1a+V=sDpTP4>0{z1Qcc*yqqT5tDYr`N@`-rnZU%dOttGq!=} z;9J>F4|)xtgMCI5rl5LVJh#nuyZz1QfZW;W?eqqpm9*{NV2@yK@Ap}U9d!C|&M$X5 zeRlA&f3Sbp#q?VMyVu*>?qinjZg+2h6~i8`vF<1M!VaHzc6Mkgt@9Gt_X$6?xqt9k zzxV9vlDiF1~)9LM&*j8t^^Ng_TvwcA6Ycxz^$3A`DrAstl z2mdw)z5P8RV{?CR(8t#jsO%52M?dWyc1x_&?;R3Dw)^|LC5_mLCjcEl@Z4TkLLpWQ z24xb#5MtO%5Up@wTiwnMU_m^4fqVgLL)!S}JDrWgvd_c7bM5$>h&-K74^vOh zFe8>pq`LA`oQphmrP64byr#Fg+t4km>FD;b>R|W1VYOOS(`i(z*SX7Tg>CDSEJk$Q zt$&n054f7F)zBSOl1|M=cN3fKCJ^pCW7 z`2FAhi`u{cTA@I{S1%swH&{H#lMg=}8|M>0JG^_q0!~XoELtfai`h7&+&>AY+5?J- z-F2*d#r72KRA75fkGTAvJ@JqmV}r>9$I2rt(Gt%`ayG@9068V)9TB%(9D^X4NtYa$ z3F&wWVVx};S!ygjq>0z@kue?TU$GN;Q_6zZSwEdVP7grSg~V*?BHI%WFqWK8`8u`_ zu(RlJ%Kg&oz84(NPbG8fn)Dp9>;(x&9x67_%hQ?fm+LLdx`1ls-NvzHG>mF`0Q|0F zS~sfi9E!EPz*`1Td{>!SUBuKftapu>we|%R-%)1Pnv0k=4f7piX0^E_Z=m>YGPByK zFEX?7?lH5m;Md7#zO&4{;E?V@Gj9_Ns}1tj^m8%9=HfZ|%sXV}?Jy-Ct$?Xz)b7B{ zZ-rvLxiX4(XXdxUwANY`)4Pb~w?VP8s%Bbu8O?8nX>~=h*X|^m-ws8}BUUgTpm@KU zS*cJiz7nSQWad^Iv2Z06tviX4w~)7mlZn+(tlb-ml?KUg1wmKu55?+AAqPoYtU5Z>*w?CMvP-DInIWtHo@Ties|?#K`TT+wZyD-0#HY zn%Q2-WCW7;l=D`bmG-K#zAqFTm6bva*m!T*ZnaijiH!os`_ad;*{-gX_Xr&CN7ixK ztgmb{wfkDyn6<{Lc3rzC=TkPT?UnLy2>af$9@A{z07u>BCuqHSyDLA)?cmdfyd)1r z2C|(g;7qy*@446n#3f zm`0SP;j9=H*eEc2;SEvvB{YK0qtat0_iG@$YNiCu6`F7zQ**fI4wM)QaD8<`bqmvK zwO5w9MDw~RnnN>2dkkv+(n=tlo>762(hFf`w`Xs2RX?lPdtGGR#BpMRv&i&(k=%nq z^?NZ63)6l`oc~cj!b&jY>Kyq=OYoNJJh^5GS&qT?BQ56e72v8hC|Op&0RJ+G%tuT*q>;_*}CD4F<= zs9=l=+)e{Ov_(UrJRY9A6V&9P&h8k6)rUNxW|tV1zEAPBN1YKUTDz7zX?gY9nn7#| z*yplY>;{xf&^F7XvS6z|^YnTBwV>hw;jSy*%2@YEbU;c$z_o~a_?*}zGeAAsXm`?X z+&$5*gqk8~>{tKr@L&G>gF=CRuh!Vo4YbRfj8{?E=QjkYq^+Y|A=I7F4jAu~B=_W@{iUgyGf>UZ! zQr}2zHo~(f#R{vihJ}B{JW#X9Fij9YDUyn&&CI7Y0|ol!Dz+cX0G|$7KO?t(*+8@1 zZkNT~;#1*}9{--Mqc|2d{5I@pogE%?ifs*~nyA68TJ`E96h0`Uh{av1z-GFh0ua&U z=~aw+T$cCcWK=-$RJu)97R1Z>jK{Df+>)cl%yXX)KEHw5>5!J>)=(;K0lo~#k9S4|e7^3nV($a?^#6lt{vUBnOOkR0u6`wvX z)3Xv^0ZQWhEDC4SA~mI=u#XB6EOAGhEEAjm}2pI$X@<=|SkG**2_7 zqheO8C97hz8&xpEWEfh*UQ-*532phUVpvrmgFb~F3Fk6AYCzpGFXHjIJWdstK0GEn zd`eEP{b%3(@o#;*P@vzdom}|_9_d(QoXdXhvS9z@=1`Try&|u^JjZ3PYZ!dpIcTC+ z3nf>^SE#Jd{OX^=9Td^iAzw`p7uOkGp=&er%0>A8x%iGNX=E>o?_ZYWuw1zo#uj%& z#95kC6o4hDqld*)sXAFI6=lsS z>!*B}yG+fSsEhlexW`ZR0eL_wqwj;?Uleo0(1D2X!Pn8ZN$n|L1PVRTfQPUN0ptX$ zA`fMx#>8{b#errC(F4Q-eHNER0~uNgP$GxE22x$TD?_Z=$|xw5Z@(Z!Nbnz1h<&2& z>r*9a2<+N<)KggksDoR`2+&RJk@A!$cx8q@LeGNCke0tM>H*p@k6)qnCn5>Kb4!I4 z2I09RH1Y9Lu|j5uF&ILv5c?za*>eUFvK^=#+xEGr5YMUyOVp$!)RWpizys0umv)Jv zM-R~xomVJiM}GoW^5}_&j_JgnOkdGDE5eeD*d<*SR08+7(xxI62GL#V_EHN=lXP6C z#l7HKDz+;OE(4>&qp|Z&499iCscG@(Q@m>_4&SQw#A#T@k0EG>#Ce=I;pOX}y%>krm% zILF0;L__b6#8rF0Qo{la;aO zBikY>-|O9&$&2J)KxJv!w~R{Oxl$-qKW| { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + /* This test simulates an air-gapped environment in which the user doesn't have access to EPR. + /* We first download the package from the registry as done during build time, and then + /* attempt to install it from the local file system. The API response from EPM provides + /* us with the information of whether the package was installed from the registry or + /* from a package that was bundled with Kibana */ + describe('install_bundled_prebuilt_rules', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es); + }); + + it('should list `security_detection_engine` as a bundled fleet package in the `fleet_package.json` file', async () => { + const configFilePath = path.resolve(REPO_ROOT, 'fleet_packages.json'); + const fleetPackages = await fs.readFile(configFilePath, 'utf8'); + + const parsedFleetPackages: PackageSpecManifest[] = JSON5.parse(fleetPackages); + + const securityDetectionEnginePackage = parsedFleetPackages.find( + (fleetPackage) => fleetPackage.name === 'security_detection_engine' + ); + + expect(securityDetectionEnginePackage).not.toBeUndefined(); + + expect(securityDetectionEnginePackage?.name).toBe('security_detection_engine'); + }); + + it('should install prebuilt rules from the package that comes bundled with Kibana', async () => { + // Verify that status is empty before package installation + const statusBeforePackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusBeforePackageInstallation.rules_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_updated).toBe(0); + + const EPM_URL = `/api/fleet/epm/packages/security_detection_engine/99.0.0`; + + const bundledInstallResponse = await supertest + .post(EPM_URL) + .set('kbn-xsrf', 'xxxx') + .type('application/json') + .send({ force: true }) + .expect(200); + + // As opposed to "registry" + expect(bundledInstallResponse.body._meta.install_source).toBe('bundled'); + + // Verify that status is updated after package installation + const statusAfterPackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusAfterPackageInstallation.rules_installed).toBe(0); + expect(statusAfterPackageInstallation.rules_not_installed).toBeGreaterThan(0); + expect(statusAfterPackageInstallation.rules_not_updated).toBe(0); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/prerelease_packages.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/prerelease_packages.ts new file mode 100644 index 00000000000000..0079e67c91f7ea --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/bundled_prebuilt_rules_package/prerelease_packages.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 { ALL_SAVED_OBJECT_INDICES } from '@kbn/core-saved-objects-server'; +import { DETECTION_ENGINE_RULES_URL_FIND } from '@kbn/security-solution-plugin/common/constants'; +import expect from 'expect'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + deleteAllPrebuiltRuleAssets, + deleteAllRules, + getPrebuiltRulesAndTimelinesStatus, + installPrebuiltRulesAndTimelines, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + /* This test makes use of the mock packages created in the '/fleet_bundled_packages' folder, + /* in order to assert that, in production environments, the latest stable version of the package + /* is installed, and that prerelease packages are ignored. + /* The mock packages to test are 99.0.0 and 99.0.1-beta.1, where the latter is a prerelease package. + /* (We use high mock version numbers to prevent clashes with real packages downloaded in other tests.) + /* To do assertions on which packages have been installed, 99.0.0 has a single rule to install, + /* while 99.0.1-beta.1 has 2 rules to install. Also, both packages have the version as part of the rule names. */ + describe('prerelease_packages', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es); + }); + + it('should install latest stable version and ignore prerelease packages', async () => { + // Verify that status is empty before package installation + const statusBeforePackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusBeforePackageInstallation.rules_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_updated).toBe(0); + + await installPrebuiltRulesAndTimelines(supertest); + await es.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES }); + + // Verify that status is updated after package installation + const statusAfterPackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusAfterPackageInstallation.rules_installed).toBe(1); // 1 rule in package 99.0.0 + expect(statusAfterPackageInstallation.rules_not_installed).toBe(0); + expect(statusAfterPackageInstallation.rules_not_updated).toBe(0); + + // Get installed rules + const { body: rulesResponse } = await supertest + .get(DETECTION_ENGINE_RULES_URL_FIND) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + // Assert that installed rules are from package 99.0.0 and not from prerelease (beta) package + expect(rulesResponse.data.length).toBe(1); + expect(rulesResponse.data[0].name).not.toContain('beta'); + expect(rulesResponse.data[0].name).toContain('99.0.0'); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/index.ts index 4bf702f4d2a753..f181b10e25bbc5 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/index.ts @@ -29,10 +29,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./export_rules')); loadTestFile(require.resolve('./find_rules')); loadTestFile(require.resolve('./find_rule_exception_references')); - loadTestFile(require.resolve('./get_prebuilt_rules_status')); - loadTestFile(require.resolve('./get_prebuilt_timelines_status')); - loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./get_rule_management_filters')); - loadTestFile(require.resolve('./fleet_integration')); }); }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/config.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/config.ts new file mode 100644 index 00000000000000..cba74885725939 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/config.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { FtrConfigProviderContext } from '@kbn/test'; +import path from 'path'; + +export const BUNDLED_PACKAGE_DIR = path.join( + path.dirname(__filename), + './fleet_bundled_packages/fixtures' +); + +// eslint-disable-next-line import/no-default-export +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile(require.resolve('../config.base.ts')); + + return { + ...functionalConfig.getAll(), + testFiles: [require.resolve('./install_large_prebuilt_rules_package.ts')], + kbnTestServer: { + ...functionalConfig.get('kbnTestServer'), + serverArgs: [ + ...functionalConfig.get('kbnTestServer.serverArgs'), + /* Tests in this directory simulate an air-gapped environment in which the instance doesn't have access to EPR. + * To do that, we point the Fleet url to an invalid URL, and instruct Fleet to fetch bundled packages at the + * location defined in BUNDLED_PACKAGE_DIR. + * Since we want to test the installation of a large package, we created a specific package `security_detection_engine-100.0.0` + * which contains 15000 rules assets and 750 unique rules, and attempt to install it. + */ + `--xpack.fleet.registryUrl=http://invalidURL:8080`, + `--xpack.fleet.developer.bundledPackageLocation=${BUNDLED_PACKAGE_DIR}`, + ], + env: { + /* Limit the heap memory to the lowest amount with which Kibana doesn't crash with an out of memory error + * when installing the large package. + */ + NODE_OPTIONS: '--max-old-space-size=700', + }, + }, + }; +} diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-100.0.0.zip b/x-pack/test/detection_engine_api_integration/security_and_spaces/large_prebuilt_rules_package/fleet_bundled_packages/fixtures/security_detection_engine-100.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..27c81a0c89a31ed8e66de44b0cae82db0824d517 GIT binary patch literal 28775077 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 z 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%0A&<+3qeX( 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 z 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%0A&=n$AT0t z=i%|mIXq1mTTwgBpka%8N#o2}Hw4`Dx-vhT{lZ6v^%-CfS8r%FhFz)`2WUZHIALdt zVJOmAjT<0)q%Gn+?8FhRK_%syK6g25n(R3?#v_rFqkm;v#zU8=M+5z!*RKm&bda<% zr8~!Lsfs=lw2$ZO3F9eTw%j#ZS)oTIdh}6c74sC(W)Aq=J3p`QNkC-(gn+}_G9MU2 zKnMr{^*nO|kBzK{AKoam)|MGV9Y;RN)jKBVs}QhaNdHN5K%4xZ&phuRTb=|&`ZEX! z0VkHU@hzYd5D)@xcMfRCe?|h@BtX0I0U!Q?CjpTG4FWAly+?hJU z0RbQY1b_e#0J;Rw7!7C>47lTCcYlVTlxQ6QS_n5Bz~Y@CW`}@@I^Mw+V!Q zV&&D>`r!|8@Zb;pfj{sE{#^2B41>3cf`8-JKb8974?*zY5Bz~Y@CW`}@@I^Jw+VrN z-yhEYfgk=50T2GbANT`*;Ljz0#sGMm`1j=afhYUn58?0N5Bz~Y@CW`}@@I^Gw+ViK z^t}af8Y=Nfj^i08AIP~BHy2Q_cuS%2Y<75l!8BN{<2@;rJ9$qP{W$Z zqvFkltUB_zh;ow(JyUVHs+e7vF9o`CHVfh=%PK7QrC6hq%d)z3I_v~gZh2x~7%1Kr za=kj>jfu@csHog>b)|5O4~oNb(tRP-a@yr9g^9yNszTA@)g%o=o+K-AetD8p`Dq^0 zMtbRaDbL$_Dfn??q6{F)0M-^!25`G&0IAmeuzYYKYU&z^U=odC3ne1FOFf8&)~N4`4|5Hmms z2mv7=7C^B8>T&_JQZY^eZRUV)dirB7@FXCze?mYA2mv7=1avB(A^j)K0d4YszV_vJ znDHba(w{*<2nYcoAOv(OpdtSm322i5?b??<;8~soL$cLgn$qb0y-7YkPD3jv`L2cp11#WrzZiC4GjW9KnMr{ zA)r$M4e8KGK%0DMFZ=k94|x(03DF=R1cZPP5CS?C(2x<01hh$s_NtG3>*rewxcy?d zvvq_60zd!=00AHXbP1p_8qg*f@Q&ZTS){DD942mZjHOa6>8 z@HQdv?|<*FJl+p~h=2!w;1B$PKk(<0KVtyAP5k?*Rq52jZ}``5b3gnc_8t6zKkx_sz@JP0jG^x~k?)O#YoFtTzqvX}!JjpM+3zqhR)~e- z`dJElsr)hhd@AK~U2ouPJXWPseV!|mzyF?O1&tQA`vZBqNgbHxR@s8z8G+sba=O0?ujOy zt;|Q4T#o5NRDL0ncI{t__~7Dvf3cs8&TVs^{88nEhpCLzdXe6(B3(zn8wGULT2DeDbqmey%eT@4>rqp;k$#Ti-2AvPsio4s-cjpt zcD&V!Le8k+*b&iA*ugI6ibXNCiwtxt>}3a|E^qKavFuIR%Y&-m&xZ?Ppm8J{+3bHI+ZS-sFl8`^7qs+fmGmmFejc{VlIXjUW!jok?Av zr<~vP^$H^2b+&dyb9qNaW<`U)h%N&?V~8KtJg9>w*>?B&|&8&M{l6qK^da=|GGnOY$S1ja$K-q!0#*#^KWPqVlmBz~1${3CAn0?KJ>YDqXHfvc$tox^pg}+g2m$eXF!&zO>Gyz!6lf%% zO%AjNocGVGo>oDT1Pua0KnMr{A)r$M4O!4gK$|pZ4}QQ0Kj}$8R>Yp(s+Kf#~ zwEfTe$!KmZ5;0U!W$37|0;-X<3QPM^5|{DD942mW00XAFb4iGmO2uJck3ey)xnc<=}Qz#sSn ze=hkm#=zTzz{^Md#tA=*pNN15f8Y=Nfj{u)l0RbryiNT3dtZLhyZ!Ko@OSVB{=gsj z1Ai|0Ge*DL1iuI8zo+YmKg7O+Kkx_sz#sT?$)7Rw-6rz=O&|E!(|zzaUq>nUv*s`R z5|?UT#zGBiCXb3Y7qaTe<08sUD)dan<*H(KVZIdT%GoT4n=Gra+?QgFN-oRl(&?}h zP`TxaePN(@Tgdh5fHx*K2ce>J%hi>_F+L~`%SrczRLg0XuM{Q@6R8SCk5`j440)2Q z#QEh(PUWY0OdIK?=cPPv>!skwjfpaVC<9nqL>a*CmI0(%^TYDNg{Y}}SV`Seac-W# zu_yxgxdX2iTl2U5$alILM83m6O#kS{%tr_C5B|YFv9?|R43Y1e918*O`~EN8xOL>a z69F*;gn$qb0%8Fa3!p9+Kr0pF6wqc4Sa|z?-_etR$o>fdAs_^VfDq8BfQIy+GzYZF z|M`&X|Kc8=1Vs8X2nYcoAOwVfP6agNKO+Hc5}@7f_3yaOlYq#81_2=;1cZPP(5Zli z6lf%%O%Ak2ynM%gPXZzd8U%!Z5D)@FK&Jv4vY?TGHfhlA_|p4a<4Hi|L4$x05CTF# z2AsPgPfDjM@LO`bi8Zx4hfHo=7ia-AKFKjK~ z_KV@p*AWf~00AHX1b_h0C4k0gK$~E|zqxqn`F>KO%^)Qj{DXh+5B|YFr~VmJqRrT( zM7#gg1E1h$0*GjM00;m9AOHk_E&((K!`sBdpYyHx*47h17wex0g$IA&5Bz~Y@aK|0 zV*B!#j4q;=)&bX>0xtP3@Y>A6{>A#fSZ3oyYAc=EchNbcz0!SEEJ{2jkA9 zuFq4>Z~A%#k?*=&8Fd`&2=#Vx!r5AupFrCd^oH$J4?n- z($;LeQd^v!u4KW}da$YgjBnDV)2*mW12H`^nRq@rVm#*4r_G0Yfua+w(qKqoQKCJ=kPRPY(?!f zgN7~YC5&pCW_6r{w)@Oh{T)m;y7%9H0e(;e?$nhM`DfHEw|Hk+z8Q zuoFkL29=a+`rPHLX|m_o7>`6wj{cQx84q2e9u4$^UcWAA(LvJ6lcxtWrZG<=+Q@&Rm@XBn>pa6r5FChlYq$n2?2+Urh_9vfK? zKfFf0CWkUF&fY& z81T7|edLs%lxQ!QG&}$VfB+Bx0zj7l z8iV0&V&M-wW%`?2PXJx4e$KXteN^1~m(-@zaF1ApKT{JG@M82xS&{C>gXUsU$PA7bCZANT`* z;1B${=CDCLjFmtD_YBS@V~dcrL_34QnQkiZ>Us>d50F%1tWtOvUA@ zVs>G^6zIy?EQp&dtFYXcVvR~J%j(kUuoFA5qH@dCmBKMT zC=Sa>_k~o;X_v1QCJqy+3Pq1slQax@lB~q}80nTJa6lz;Kz-LGJq%p zSX)FH!0na+q+0XC^1+3use4#S-BWRHp1>J)L*q*F2@g{lsr8~hps;&m_ld(hc3%5S z&)K^*e}|@aP2~@-H#rq3*8O6g$L%QQ#me+_iT;*Xqec)1k6F0kl#vP62J^ zfUVa*>J6R*MD|Yz2mv7=1cZQ21vI4pq&c8X{?G3F?{|YI0g?U;0zyCt2mv9WQvnV6 z&qzR<1Za$cL zgn$qb0y-7YkPD3jv`L00U;6c@coGoV&>$cLgn$qb0y-7YkPeLmw8@8d;=AAYJ5K^4 zAsPgPfDjM@LO`bi8Zx4hfHo=7qObi>Z7tyTi{b98BODL_0zd!=00E#&0FBXrHo<_; zPr85WCneepQlh~>_y_;sAN+IbpD`ucj7>_k$KULL^M1A1b_e#00Kal02+hg zZDQdUUvs|)Z9M^WvHporc<=}Qz#sSne=hkmM#9?!!hhpgU-$<<{2>k={DD942mZjH zOa6>u@HSEKd!BIpen0#n2p;@_Kkx_sz@JP0j4|*wA@K9;=)d^k4-xR-5Bz~Y@CW`} z@@EWyw~2rM*^e(?@WUU%-@zaF1ApKT{JG@M82xS&{Jv-7#;^F{53%py5Bz~Y@CW`} z@@EWvw~2iJ#-D#;w-5d7QD#7&m%>`Sp0HMy)Voen!e+~yPe!a(u1kn7a}Z%k|sLKTU)x>7jC z2gRBU;-oL6T28xsr7&@rNL46$yqct8$dhCx&M!~$7MDDxjdYDy4lkK5x}#J-sg}!4 z5hkTx6iShZmMYOxlzCiClX71SxJ){{+b#D*lg?J=qf0KwbRjCg5J|iCuSI-talXIU zPe$jqIZytma>Bz@MryrC?^cnnqu-4Jy6SQ-h`PmAR}6~!RLL!WE(~AM$x&O#C|Rv1 zp^&4EjAsoO|DM{#a`+?do-XDX{0wO!5W1c`DP#JinO`;FE;vEw4t6AP&ZzNnM|(oZs~I3L@Wiw=(KD*b(aO;)Juc zEI)y^E$9u~sm2qL-M)r$kPATXS;v&AqJX{^Q#kUi2CaUOQ!h}NKza!sGRoHb4M92?`2$jQ;a zvMuAGOVp!*e$eaJ1uZ&ATA9+FW42U99|_vW^Yw)B6fRrt8m+9*qY^#(sIrQA3TQJ2 zywAzCyL%E4**_uR@V3kc#t;w!LO?ywoWNrv>*0qt3azze#!$zRPjdB+$@wY-tQgXN z(j3qx|L0wo*g2jAMEWxb2mvRSwDB#V5)cpqZg&o7$bUux+9W``@c6~=_aq=Ppg}+g z2m$eXF!&zO>Gyz!6lf%%O%Akk(&s$HlYmHq1_2=;1cZPP(5ZliENCR4O&YX|uYTe0 zdlC?N&>$cLgn$qb0y-7YkO++gw8@0Ful$cLgn$qb0y-7YkPD3jv`L0` zm)<{J;z>YcLxX@25CTF#2|0`Zoe4rMRkM&0zd!=00AHXbP1p_8qg*f@cbLTdv`x6(Poem4gSGD z_y_;spHu&gDbZ$ZQldTR8`oXtX99?5cmN0h0U!VbfGz0kZu zhah=0a8-d0a%fNrj%NxLj4tF3gt#T{)Wtag${gmitny zQORXlT{<0h0xGvWu`di1Zwt9z9q`7)<{(s5Zn?TrIK~IXVL9o(kZL*Y@|D8GVIozb z=<#Zjh9OUql{mjV$*KG_k7*;l^t_bkZM_uyxG_-%5M=;sizoxQ-7DtfL1ETDWJ_9@S;y&f6$YF$o>fdAs_^V zfDq8BfQIy+GzYZF|2gxwKRe+`K%_r|fDjM@LO=-UR6s-iGZN4y0own$>FfXINkC*k zgMbha0zyCt=u|*M3N#YXCI{M{pFj4=o&-b^GzbU*As_^VfKCN8WI-bVZPK9q%8wrP z5l;dl4;lo7fDjM@LO`bi8WN$AfHs-X?)mTc`+H9UA{810gn$qb0zyEi0vd9mk$^VI z(Dr`ycE9CGKx9LMfDjM@LO=-UR6s*IG!oDzAKG26J@-ML1VlnK2nYcoAOwVfP6ae% zL?Z!hQljm9$=zSEwSe0%hWoHO!T|vw00e*l5CFOa&=?J96AXCISNzo%{iH;jK}t0E z2mjz7{DXf^{WGRSo3TlWwj)UH?`HytXm|h!00AHX1b{99GzP=l#KM36vbXKqdIIQT z{S%?^;1B$PKkx_sT=Hj(gtrNVmreO0Kl~vM9{hnn@CW|DpG*FXVemFl@b7)w?Tdc+ zLl8Xp1ApKT{DD80{2625Z9?GR^zko$+z)?d&$+QaHv3#hMJ_q%WjeruJMZOdKXs6^b6OCTSS* zBw2~`%agptC68$%UE`I*mq0I~qf|esmdi~MCZ%2!N|A_`D$!Gvd0b4Ba$gL%Ogg;V zE%!uIe}wqxlFKn&h{`WSf3WtiMSO5^zQ5Q{M(4IUPyVR!=e0=hR*|lw-;Dyg>T)lL zy2Vyk42t?x$t`~_3}4a7QQOEUS*<6bkh+ED_T^jYf%T}V+h}wj>DNV1)#!3Ih*XEEjy{Giue5nZYh2&o`l5Qg8Ku2^j|$pn zG~rS=NK_PVzSjr3B5iK|cr9}uyEeX!4^eTFjdb(Vn@wAbL0&E?$(?1O!2h!GTs8U;;o~~q3(|X*g|BP?ZrPHmbOJguSDw%jbI$}KB z)2Gcxd4Zx6tl5$O-yPP#m z_8c4IQOL>Bzp^dkVN2AbA%4*7*99#$NLrB6U1PRFMIQ;;$MbcBv0m9K*Jwe79+l{k zN0n8KQ$L%z-|ziLf5DG_Ncai;=;j!Yh@l_!gMKu>oPc8^>)nTT(RWLkFVt=1lUu!G za-ItPDu#TY^@>ft&zC*#1^?hjKV&jMFzO(y-d;RE#L}$^@>fJv;X(lnY(VSpMx}K z2=@bizz_HVKj7yMKU1`yO|ai5AMksR@sj3j25HVvw+m-CIxm9ISaF%pLTBKF|mHK%YDMOi}JO zLGJet-t%ZL^dZI_^npIm2l_ytJNir^?%93zizD2hIQYT)ywHaLchCp=Kp*G>eeUQp z#kbppx4-UiZP^Qbh;9dcpbzwcKG5fmK2vbJO>Fz;Pu}-NFZ3a_9rS@d&dj|)~H&ttS+4nI{{Tnp4b-#inoPa zuMT))VskKT=ITn}7#|dem7x1Vs%2`?mBPefB2}U2@oJKWAy1N(IKMo}sd6-rX(PS# zyb|Yayo~K;W1^BDY8j!L!}hDVQMOo`$diD`cm@F>AOwVf5YVZB zx1RJ&3z&r*{o>yR{pA;b|L2|rMB+0D2mv7=1cZQ21-$j#XIem;>}Pj>&TGEqNkHU3 zgMbha0zyCt=v2U4Pl2Wdv`K>Y&}Y2+(VhfE8Z-z90U;m+gn&*3y!A|IT0omzXuJO3 zJ0IXlKx9LMfDjM@LO=-URKQzLh^7U!Nr^W7gFk=m)&janiH2}M00;m9AOHk_E&((~ z1KI=w-nVw=qMwv#Gf0UB|KK0|gMaYPsei_lXfrk`(WdV3u|0k!fQW_%fB+Bx0zd%h z5v{uUwE9d?4a%_sJSf#Pi;*Q*2GnAjYIDiU#Z zrErW7iZvO;Nnc2{oObz2Vd5~6s!;TJHA%yeC&@~jU!LSGE_qBF=^C%3ip}6}ZeiS* zC`;=_Ki&f|6z^I~Os zx z`R+tO%m5)E1cZPP5CS?CuwtA7+ROp(zyA{#dJ+)XKOrClgn$qb0y-7Ykp7eAfHwI* z&wubA?)M}h(w{*<2nYcoAOv(OpdtSm322i5tyFyaHJ$`S1~do=0U;m+gn&*3G^9Wy z0c~=i-QoPXdw3EMNzfo51cZPP5CS?C(2xa<1hh$mR=xj)*Le~UdC(vr1cZPP5CS?C z(2xj?1hmP7HhssdZ}cP}QlUXW2nYcoAOv(Opdl9;322iHZP&StJ9-ij+0Y;$1cZPP z5CS?C(2x#|1hmPA_RvB1QJw@uLNo{n0U;m+gn&*3G-O000c}#E-F@TK_qG;r`^9i8 zb%X-~KmZ5;0U!W$37|0=&?Xr0-hKA3eo~^%ASD|7gMaW3{=q+|{uxuE&Df+wEBxMF zrJo5PqTvA`00e*l5CFOa&=?GF6AS;@*PqzA^#stx`X@r+!5{bof8Y=Nx#Z6n32ze! z|J%R!!k_u!4{`9|5Bz~Y@CW`}@@EW#w~2y(^T~g`yC41#1P}heANT`*;Ljz0#u#{; z5cpR=@OIz#!yh8x!5{bof8Y=Nx#Z6n0B;lj-uuC+`}*Mz;qTxN{DD942mW00XN-Qg z34VX`Z-4(2e)vP|JNN^C;1B$PKbQO&L*H#8-+%khp7vlL{LR!+3jVD5%VIbgE5t%^ z{VavORQ{NLK9zF0t~c;C9;;F_P(i{~Rm?8Tmx8nzDHg;{mhJ3Iu@*JCtS+4nJ3-v$ z6Z^tI@wSlb)d6ozYz{&diMYB_IK~IXnhfHkFQi&dyL_cEahOO|D0;k_q+!UDWF^io zPx2O*Jf@9wjaLpYnJ&7cR6nVf%S{m`rCt|mF3#iE$nMFzSR_OgRfmp6EzSoWsuWkRwf>P6i^cGp>=WE!ee z@+Q+C0~RGr@>6M~Hz>gxoaq-vPu1vhHi%S*sg6E|E~=EbS3;i@{XXc6>hWfj_VPU{ zXrIxBOWhz*QMmbLALxp-x%uPKyjk@t+T46V#0va@KbQO&D!~&t!_Qqot@nq0=J+Pp zANj)Wjol{>@7Q^?`Qhhn&EKJ^T~qnP>rJlsuwSh6xE;m3Sec$K(ckiF)Cl5W+?mw% zdCK`sU#}qYU3V*^j)NVc-Y!l!TN`(WanKvKQ;jEzEz^6);GZN4y0orf8&`3a=d}v3% zJ@rmc0wN(A1cZPP5CTF#rve%>qLF|$Dbdu|?|Aly+?hJU0RbQY1b_e#0J;Rw z7!7C>4ETimJSg^)5^V-4(cmBagMaW3{yFu}m=bNqCMDXXcYE^l{Y(H64G#bTAOHk_ z0MI3X#$b4xSojxw{4vkmdIIQT{S%?^;1B$PKkx_sT=Hj(gtrNVf7q8^to-nYIC$^} z{=gsj1Ai|0Gls$2M8W@f-&bGmhd%_tgFo;G{=gsjbIG4E2HqwF{;QXrv*Cw7M8JbT z@CW|DANX_0pD_U5CjR}`UZGy>hd+eBgFo;G{=gsjbIG4E`rRh@{m1A1c+n4kh7g26f zp=T;CR~54h^QAyn&SpW}WLbsfz7%Uza#>cFPKTX<$}Laq3j@X5LatW_yfLvk2o;rE zuC5f0@j-D|PP#9oT28xsr7&@rNL46$yqct8$dhCx&M!}LDnHF*+DI=wFXee#F9knt zOq2mc8Nk{i$^dS+3?S8-AC?a;L`~hpO6s19a|;B{up1gzl23S;%1Esj^#O(58@o>& z-m&xeBft6UTl05lYS&c$@OqO|fnwb+)_L5HVqUCFPnYO#c{OSTaZnx~sLxa0yc$Hl z!#_;_=*G-P2k;O6!9TIKUH=S`?*yPtpa)i|bGEBp|YXLO=)z0U;m+bSj`B{U^-ioYx-;;ny zg$4m3AOwVf5YVZBhFoYQpiMHgqxb*J8$1b!Y-kV=0zyCt2mzf6Xh?@f0@~z56a4dE z@gyJ;qCr3i2mv7=1avB(AtM?IXp<7{3USlpwia;v#c*fq2nPg!01yBIKmh0xKw~tZ zO)%ifCAz@dP2Y=uX{DD94=aN5TB)m-^{KG%=u6Oz24{`9|5Bz~Y z@CW`}@@EW#w~2!P;XVHP(SGL=B5xhcY=)QdtX646p6dWtfSi)m8sivgEOhj+W>o@mn9%6xRm<(Mu+^x9 z3mGM=^&}Khx6s_ad@DV$9yN6v>E|fUEsPtJS}N`99kmW;$6Ku^9qe+h zSQJyc$UwKkUUo3*@&*qS%iff|Oh}eQy{H?=?mA19Ohc7Q-eme?z@mgnekzUh1|?X7 zGyTHosTy6*29fG8)zQb$MV0dQO6ZfK-v@nBJ>HDcUcN^K?K9eNsT(9J3OC>E16`3e zH-9{uH>-X{o0|`aSb;zA=aN4|C3pg7__-^n_5QHW9N*;nBVX9PvHQf~9Xp@)jvFlk z9}Z3Jn#vzuZ*s+l{bHTR?I`BO%Jg)J{+3sxMi2+%&ZMr-Q_gStdIgd1x?34_9P9}7 zc5%YlT9%(c+ZObO?NsB5V$1a2u{iBDxMUMuCj5hc@Q<;4%%M7x1_X3p<%6rMMuRN6 zpIVY`sDY5H`nEfIS#5cVE!Jv#4jdkHOb01F#0%+&%?HxfY`juioSv>^!P9!MssD^` z(xua_s7nJeJu;biK00DN=F_LmhkAjc6Rpx&dyb9q zNaW<`U)h%N&?V~8KtJg9>w*>?B&|&8&M{l6qK^dahQ4HogT^0s=z7?al!W`Oh>t!`bb45}ALI zH~daN{~qwe&sel50O4d66dBMUAOwVf_&peW59suJKtl>N63`|G+Be?&AAjd*6%NrU$H@A!`LBp~vjK|lxy0U;m+bSj`B5gG|-lL_tfZ+uU~ zlYmHt1_2=;1cZPP(5ZliTxcYqO)|7EzvgwH^CTd$p+P_h2mv7=1avB(AsreCXp;}^ z1OI&8OFRjPglG^D0zyCt2mzf6Xvm000@|cR`{_Tty|}f2+b@PYS4TJ?00e*l5C8%| zmjD{00d0Z-U-;Kg_=~MGg1QKWm_bT3_y_;sAN+%VPW>~cM4PcmiT2T7{q!6COaKuL z4*&rm00e*l&?SJzV0fEY`1-Guetqi+po{fSgu;VA@CW|DANX_0pD_~NCJ_EdGvD=6 z4t}nVIC$^}{=gsj1Ai|0Gls$2M8RM5wO4v62R~Ow5Ipz;f8Y=Nfj^i08DrpWLf{|z z$5+40&*CQ{;K3jG1ApKT{JG@M7yxe*|NgZj=RVpGe+YjEf8Y=Nfj{u)l0RegyG`)> zMK?X?8bACY_8t6zKkx_sz@JP0jG^x~k?%jc+s}JG_?xez6#QB9mwky#H7{eKhBcE% z#hVLRb>wjo$h) z^wRTEp11W<@Z-ir89zDf0WkxFfDjM@ zVgVEjpe`3cD;47u&}I(!>HGivpLh}w**_s51cZPP5CS?C(2)L<=72W&Kfid#XTH;u zfJlD^0U;m+gn$sxsep$3XC$Ca0<@dY{i8d35)c{CARq*UfDjM@Iu+260*wT;$$|Da z^AG)FPXZzd8U%!Z5D)@FK&Jv4vY?TGHfhlQbN>SKBp~vjK|lxy0U;m+bSj`B5gG|- zlL_so4}Ri;CjpTP4FWJn`CGoC~iF0lYq#E1_2=;1cZPP(5Zli zbZ8`?O+K_QKPLH0PXZz#8U%!Z5D)@FK&Jv4GNO@yHYw3QUys+f7I6E;aOdj?2Lyls z5C8%|0O%4xV>F;mFyQZhTekhAM4LfMH24Sq;2->he@^`~rbL^uNs0Dv*PZ)cekOp3 zh6jKE5C8%|0O%4xV=%l;Ed0rb-~M@9PXJx4e|{DD942mW00XAFb4iGr_w@NF;l!ykg+!5{bof8Y=Nx#Z6n18)-of8qNt zSAO_I1U&cyf8Y=Nfj^i083W*L;@@xXJn-dy_(S+R_yd375Bz~Ym;4!{-)(~5t6zTA zZ}{O4vG3py{DD942mW00XAFI}iG2UT{3rj!2Y(B7l!8BN{<2kU#tN}eTt7=;FO@&0 zpHHP+uImkajmN6g3{;SCRTZ-f^Q9ndMv4V-lVv;mQmjQyE~`tY!%h&l`NY03P`oYV zdUe1X6PtrjMIx@Q6pryhu_l8!=?kfr(=J~rOdKXs6^b6OCTSS*Bw2~`%agptC68$% zUE`I*OQwtNDAiA@<#JPmNvRiwQY50KO7s+E9v9Q3+!q5blMe58%RSMgvz7VilFKn& zh{`WS(ysk$5g%Nf?=SX~(YbBTlRv7Q@GzB;S})SORix|accXx=y4(w*Zn4!BgQ7lF za?76!!&h{2)D|*IR_jS9q;8?Pefd^;U_EN;Hqy^goLd+-Cbd-B*E?z*&W^WQQOFrJ z96KV~2|L*3T(Kyoc9DT@g}v-x)a4BxD3-k`dzp|diF#2tkll5bD4B*TmAuLH$ACo% zll)W~=?zM-250(((Ni_LoDCw?VXC8#p^GZz?Um3cMZXXFqI$d;rM-NQ3fgD1;Ziq9 zR1|K$*$28JZEpT}G;db@iZ(YN5U~P(;Ljz0hDz`R&hT?rQ0x6+pE*B z!#j3<rPxix=>rglx`53e`5;=_Ki&f|6z^I~OsxgnGL;;cP9-PoQlJdc$_A@kFs@dhb}A_8MHWi7pfV!9V!NSU%=Z9Z3TM zy07xV)m5WG7Tr%RNjKC$$W?vY9lfl!yu=o3wLJ$8k2$7;lpf-Rbj0QZX=^rKsVz=V zSF+$~J=oNL#y9EG=~mRGftVhdOgtYQF&^{j)8<3HK+%a-X|SgxFA4bP)IUSyI{|1D z`Tp$Zyz1tyBj23}h#8>1Cm`UsTfhtuGe8-|?Xe(*%XxTwat==u##Yo$GicbNUeY*o z)(rtSy{^p9X20-}VSNVJ!_^yFjbWGS#Q|Cn7*5#PVi<}vR^tZ99%+j>4?A&0YfwqK zrq5l@nkIXWjqyn2d`jK%_r|fDmwENgLk+Dggl@;CAPLhWuwF zpiKg_r@r_{-}59OGN3^~2nYf3docJO(CPPph7@QdpiK_6H@xvs%aedef(8L0AOwVf z5YVZBhAe0#piLUIKX}b=e!-J~$b$v}As_^VfDq8BfQCe9B%nQAN~*o5B|U(_yd37&n17x7LM=AKT<}WYtT!@7l)=VB1Z!Tojk;g@pn^fqTipy2S z?81C0(3P`U5I0#?VYx5G8kJm@)uq#6C!li66Z^tI@wSlb)d6ozYz{(2<(8`}g=2hB z9F~*r3#pdVE?+53941l~iXN{fX&CY(S&8$@lbp&=^O!c$OV3Mr-quUOj~f$Z08s|8 zwumx-+bsh~wdRNAg9}kp_pp+>r{dfKfivue#+Bp~9;Px<>qUJ)VfV)F6Nh)~{O~`& z=R;fbcW7$YRQ~XKlT(3W-7nU8+>T;itV~ar=x=#7Y6Njm9v`UBQ{KE9M83m6O#kS{ z%tr_C5B|YFv9?|R43X~ypiSiapWX4Qw{0Ey?nFS$03jd*gn(E8#R90y1<*>xI0dws z1HRzg)=p0XBKs!ZIYo~v;S`{@FXCzp+P_h2mv7=1avB(AsreCXp;}^b%#E*>PbK( zM1z135CTF#2Ieq}fB+Bx0zd%h5i8f=C675Ylyz6p56F@}613&->00AHXbP1p_ z7~Uop{+H8-ethc*po{fSgu;VA@CW|DANX_0pD_~NCJ_EDkNegoe)vNiJop2D;1B$P zKbQO&!{BYA;IDrEAAQyje+YsHf8Y=Nfj{u)l0Rb%yiEvv_j^y;=Z8N;z=J>V2mZhx z_;bmhF#z5s{{2t)?Ea!3{t*5S{=gsj1ApMpC4a`~cbnk%tKaaf|Ko>0#J+<+@CW|D zANX_0pE2~^Ci49)SN-(MKKQ$+j#BVv&0jW-VXP1f#r3lk_EPy{`uSAK<+|R$*LbW- z%|HbSS5+~)FkcGNW~5jUH(9o`FU4Ba{6~>K0pFF(~R&CAa*!FnmQPM{Oaa zWVN1zLh2Tp+m~;p2iBveZX^91#kqxXV^T|{eZ8aB;p}*;6@{Ep!?7cxov?#l&J~Md zY8M&kR@lo9MqS?EfnwR4vX=?TlBgGT1KC|?iIQokQpuZ4e+*cZFv(A)k=~#LYjCDt z7(G>^%h@1O9i}?^7`muZ-d+iPQuO}Yx;{@izv=50M84~8Wz=!7Bh=f) z31@3regbV<&>OZ>jVFpN(|gC_wAbL0O>~*?5B|YF#_}PQ+8(0!E;uC5vlvgm$l zNxGp1LayrD?&xK;!r1TIkq$4&TNL#b%pe}Grmce zPPd{i4aD@wWa9bgi1CLracXWbBR)9cFoZ1xKu z8P;cjJzTw^)fjfEUL2qWf#HOmEry{;V>NDo?2)#J^RN>~v<8)wYx>;ftZB06*cgvQ zPLBSSZ5a<;q8<(OgI>QbXwgB^%9QRLv!yEfNYFl>uP2PBaM^O#Xk~>SmFUq&l~v4B zK$|(>w}1GX@9-obvVTIr;cb}@j3FQdgn)XUIf2JU*252P6k2P`jG>MrpXBNtlk-&w zSTUskq&c8X{?D&}=gzP4Bp}kCK|lyNv80V}0hNG&5OBM5KtujB63`|A+P~aN63`|G+V{Wks^@qT5J}J=AOwVf5D)@770{3cjRdqw zgZ8n{zHgr=0g(p{0zyCt2mv9WQvnT$&`3a=OlTkcyMOytPXZzp8U%!Z5D)@FK&Jv4 za-orcHp$R_^5Gx-ktYF>4GjW9KnMr{A)r$M4e8KGK%0DM|Mb3}e8!W2NQedjAs_^V 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
80Q&jY%z)49z*w=y7(e(-9$O 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° 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 z

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%0DMfByb|{gEdDkq`|6LO=)z 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ⅆ<+bA5oiD7 zF=q>iIfH$$5B9-6*yqu{qL{OVY)?CV$mf@y^l!gk%ES+q?!XWD0YBge{QTipROs$f z=l-bs?ETv2`PLrJd7{i6^npIm2l_ytKl+NQ++B*?f1ocps}%ZB;|}^jALs*ppwAzD zMJ4Vo74A>tXWv{3eJF4TeV`BYfj-dZkG`V%c9-(@{f~RyIi=8t>UPiv`amD(1AYGJ zD=KbxscnDwrC>Zru1dah#9LS(s27AqvphP`FP6Jx?RB6cw%Z%U;^q4 z-juucEY^ZF5{3my#Ih>~O0J2BtLD;)uoomy;#5J;gg*@q`xAI$lYwmhGQP&zOO3*6WcB zb*(Q#CAI9B8a+gvC)HHf2Xe@j?(sOT_hm%SR_EhYt|zo2CSMUnS6#Fw`0&E~`szTB zpWEem@_W@a4^t(~dX?U-Dy_#L76Gkwy&s6U+KJ_`YM)Bq_Ht$PijM6Z{imXYUTx`6 zD!YYt@6DIe9a|!@+sHmf_58`UL<@Jca7PRGt+#NW*}vN3bnZcSm-V-a3|~{We!@<9G@CU?0oI13Q^iOpCsV0~N0`ZB!bXRPl(} z5fBraDSkW^c7c(s&6zblFrrPLtD!JGW_tEE^f9aDLlsSfBs&DKAJaaMMB2}#`eEjWnIH6nejfE}6ixkH=6;{Q>faw*j($kXPS|IE}>=@+jKj;Vjpr1$mW~ZEyel9U*FZkh0j&H8t zmK)hNS}6Aee!vg-0YBj955J;nKbK;^zv@5o?WM$=EgvfZVy{pPRV{avNdhq`vq2l_xC=mUNJ=qoB~cd2TB>5r~_ObPTYw9vx+OzF!i zG#RTT(s27Am7UbLm@Xerxmvdi_!>`4EecGaxoOH>dlqX!8VSRKBx2c>10~l)#8q?Y zMA!?GE}yzC3=Ho|wcZ@^_SE7aG(slLmC6x5tS+k{(F3W>(KO~Om8qM_)P%Cnn>r0c zuJuZiub$!^u6RNVX&tW|tun22&zOO3*6WcBb*(Q#CAI9B8a+gvC)HHf2Xe@j?(sOT z_hm%SR_EhYt|zo2CSMUnS6#Fw`0&E~`szTBpWEem@_W@a4^t(~dX?U-Dy_#L76Gkw zy&s6U+KJ_`YM)Bq_Ht$PijIx9g%WzTr9-Lg7TUcxUrKjuiO6mv`xw>pC)<)XR64NB zmwTLD+UbapGum$KknC!9Am-dKkaf#0?)E6U(v{?qiA;;O0{Zty2F<&A6;VmmY2`le{e!E-N@L{T}Zds zxFapihAPYZ=I0w(Wwae<+CP9s&LGV*+M=nE8pMJJF+ZIS((Lp1RXS zu_L-^h78+h&t#lB*@k`_RyP)RWxwvopgslb(McOR3BxY7Ck5z4z-Xe*_JyHL6EoQW z**#qW=V31qbm~dhm+f=cvrUsd#>vSjf zXy=%Wh@l_!gMKu>oPy(IcDj6I7oA|se4)ceKDo75OwUuHUt@NhC(Zp_@;q;M(=R{2 z9Q_b!2K}Jl8na&~&_{y4`r-L^$dm8wvR^oizf7mEr?oxn z++>Z}nP#M)OQ_kuZA&`k=!aA@=m-6vAAa+K@BKWU`J5eVM*6wrnspxZmY0^JAA-%G zAM}HM&=2}~)NgjO8R_Q|ZFa+VZo0Z0{g7=2{h%N8gMQG@qkgl)%}76&bhE#B&PCUi zqaWhUpda*ue$Ws4dDL%qz8UG~5^$DYd1+dXen>cje$Ws4K|ko{QNP&{XQZD?#@P)Y z{O4DeqaQ-fpda*ue$Ws4dDL%q${FeB5_8r$``wppuHTj$*)FtD?g#vUAMgWyz|S9k zMb&=Uel{tW$aBg@frWX@*>C>i(4mp7hoF}Q#GJuC*a!PyAMEpJUs252f=kTV)gQg_ z=SrFQq0$}r0YBge{D7Z7{E7FQuyyYTQ8|=mUMA5A^w?uc*Y`rNaHjS8jh?DfFSh9rS@d&f2q) z+wXDR8{Sb0eW-2+eV`BYfj-dZkG`Vfc9+`r)n|S2@ukp*(ss}X`amD(1AYGJE2?aF zDQw?+$ping6#7ut4*EbJ=mUMA&mVn7W$i9i?Z4hyeRK)*?P{Tg`?SCV}76sNw? zJfVg3%JV*)KjTeoC)*Nj{Lsd4dEY$R_-(O`AN7bIwf?P$$R1x69i6J@lQyG+(CMq% zcfRE2uWnA?maE!nWl+@)`!MZ;eVF!P+UIZD*O*<^ZoP5P@2$V`t_N>k)$T(-%>1Aq z^n-rT5Bho3uTeDhbD8@+>6U-|*K+hjnkV#we$Ws4K|hcB&5rY=xnK6>`svSn#?O3c ztsMOjX$JkEAM}HM(9ffOvop;|zidxCy?(E5J?{PG=!aA@=m-6vAM}HM9`&0YYexFH ze!vg-0YBge{QTip zRPEiIfH$$5B9-6*yqu{qL{MzTKs~{kk8&?DnP5 zhw66F2l_xC=mUNJ=qoC2cd2dv%vV4D%~I$?X*=ixeV`BYfj)oq6;-yo6t@56L+-n+ z6#7ut4*EbJ=mUMA&mVn7W$i9i?SK97<82h9TE_CCOJ$@eWr!p@p=L zSB_ShR=Q`*KsW34NQS!B7on0`c1(>PqRx|Qs_O$eb5h zV&f7nS`&PDVSasepvTYc@;v#yCMgV6dbg^y9)nl}wAS^0AmVB#mcy!jDt+6_mC-9Y zHr^IW=+%}ErLtRS_uhOd-LWMiyN$ARhsn024V4b;^5q_9mv%ZLfW?U=KnFg<2^_BOP7wS04F`k>g<3cFH$9*MM{Ut@yqDVuO94zv;B#(TX#mT9zc z@o>IX?JL??yk90pB%lxU`J-=k2Y1qD^szgAal^gd{f;X(r|-a416^okP}Ob^D&xZj zJ4DC2M02*5MGsimg8m4$Wv&f7N(UvDr2RHm?EJ~`686D9*vInWhUqC94A5SckE@V3*g0sZo00%m@g`H7@E(W7!X4=Pgp^?Q_?& zO_M#w$;l|>*!cglC6i%`NBs(?elByrpIr5p`%HDGbuqwr8E2tT8*&jP%QXS~j_V-e6($ z4Sr?E$sLy+JZIYjZoTLp<>-f0Gw28XpdWtog75u2p81>|YexEId)n#sd)6m@@`ZBr zL$De2gMQEt`awUB`pr%@BmG>W%`U#v^Uf_tKV+LhKj;Vjpda+}sNd{xGt$o`-R!YC z`C2*pA>Iu7K|kmR{h*&m{buKzk$x@#XTN*>FW;dY{g7}5{h%N8gMQG@qkgj^&PYF( zjI)bte{f?t`XS^D`awVF2mPR*NBw4}oRNMmF=x;E;ny$NT)!&T+3Abif8nPO z{>xJ6LybG=1AU+m^npHq^c9u3yHvO*U+z7+6#7u$4*EbJ=mUMA&mVn7_3bX@?Kgbn zAKp_6eW-2+eV`BYfj-dZkG`Vfc9+`rkG%I8M@yj(rR|^(^npIm2m1WcS5(>VQrLd& z+|t`ip$~QKpbzwcKF|mH{Lxob*6vc({=Iwbcw7neEw<3Y{Y>f0zOto;m5DT?hF9aR z%ayFP)uaPfL>-!`J6u!l+Ot>-Y|CpFBoWKnV-1vCqkdVcxpX4z1=K5R>bfv6yerju zbI99Mi-XWmudL=u

{EM}43NQkkP^%vUN?H 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%0D?mb}rz6ZK(@ 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

=uD&V>LE0q@=lI}%sh4O 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


>6?D+|OCj%>Q~TzfRM0_UUxkfkPB5E) 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
diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts index cc10602114ef45..2c9c9cb7a6b98f 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts @@ -6,32 +6,7 @@ */ import { FtrProviderContext } from '../../../ftr_provider_context'; - -interface Detector { - identifier: string; - function: string; - field?: string; - byField?: string; - overField?: string; - partitionField?: string; - excludeFrequent?: string; - description?: string; -} - -interface DatafeedConfig { - queryDelay?: string; - frequency?: string; - scrollSize?: string; -} - -interface PickFieldsConfig { - detectors: Detector[]; - influencers: string[]; - bucketSpan: string; - memoryLimit: string; - categorizationField?: string; - summaryCountField?: string; -} +import type { PickFieldsConfig, DatafeedConfig, Detector } from './types'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts new file mode 100644 index 00000000000000..230f2d79f24486 --- /dev/null +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts @@ -0,0 +1,796 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-plugin/common/constants/categorization_job'; +import type { PickFieldsConfig, DatafeedConfig, Detector } from './types'; +import type { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const esArchiver = getService('esArchiver'); + const ml = getService('ml'); + + const calendarId = `wizard-test-calendar_${Date.now()}`; + + const assertConversionToAdvancedJobWizardRetainsSettingsAndRuns = async ({ + testSuite, + testData, + previousJobGroups, + bucketSpan, + previousDetectors, + previousInfluencers, + }: { + testSuite: string; + testData: { + suiteTitle: string; + jobSource: string; + jobId: string; + jobDescription: string; + jobGroups: string[]; + pickFieldsConfig: PickFieldsConfig; + datafeedConfig: DatafeedConfig; + categorizationFieldIdentifier?: string; + }; + previousJobGroups: string[]; + bucketSpan: string; + previousDetectors: Array<{ advancedJobIdentifier: string }>; + previousInfluencers: string[]; + }) => { + const previousJobWizard = `${testSuite} job wizard`; + + it(`${testSuite} converts to advanced job and retains previous settings`, async () => { + await ml.testExecution.logTestStep(`${previousJobWizard} converts to advanced job creation`); + await ml.jobWizardCommon.assertCreateJobButtonExists(); + await ml.jobWizardCommon.convertToAdvancedJobWizard(); + + await ml.testExecution.logTestStep('advanced job creation advances to the pick fields step'); + await ml.jobWizardCommon.advanceToPickFieldsSection(); + + await ml.testExecution.logTestStep('advanced job creation retains the categorization field'); + await ml.jobWizardAdvanced.assertCategorizationFieldSelection( + testData.categorizationFieldIdentifier ? [testData.categorizationFieldIdentifier] : [] + ); + + await ml.testExecution.logTestStep( + 'advanced job creation retains or inputs the summary count field' + ); + await ml.jobWizardAdvanced.assertSummaryCountFieldInputExists(); + if (testData.pickFieldsConfig.hasOwnProperty('summaryCountField')) { + await ml.jobWizardAdvanced.selectSummaryCountField( + testData.pickFieldsConfig.summaryCountField! + ); + } else { + await ml.jobWizardAdvanced.assertSummaryCountFieldSelection([]); + } + + await ml.testExecution.logTestStep( + `advanced job creation retains detectors from ${previousJobWizard}` + ); + for (const [index, detector] of previousDetectors.entries()) { + await ml.jobWizardAdvanced.assertDetectorEntryExists(index, detector.advancedJobIdentifier); + } + + await ml.testExecution.logTestStep('advanced job creation adds additional detectors'); + for (const detector of testData.pickFieldsConfig.detectors) { + await ml.jobWizardAdvanced.openCreateDetectorModal(); + await ml.jobWizardAdvanced.assertDetectorFunctionInputExists(); + await ml.jobWizardAdvanced.assertDetectorFunctionSelection([]); + await ml.jobWizardAdvanced.assertDetectorFieldInputExists(); + await ml.jobWizardAdvanced.assertDetectorFieldSelection([]); + await ml.jobWizardAdvanced.assertDetectorByFieldInputExists(); + await ml.jobWizardAdvanced.assertDetectorByFieldSelection([]); + await ml.jobWizardAdvanced.assertDetectorOverFieldInputExists(); + await ml.jobWizardAdvanced.assertDetectorOverFieldSelection([]); + await ml.jobWizardAdvanced.assertDetectorPartitionFieldInputExists(); + await ml.jobWizardAdvanced.assertDetectorPartitionFieldSelection([]); + await ml.jobWizardAdvanced.assertDetectorExcludeFrequentInputExists(); + await ml.jobWizardAdvanced.assertDetectorExcludeFrequentSelection([]); + await ml.jobWizardAdvanced.assertDetectorDescriptionInputExists(); + await ml.jobWizardAdvanced.assertDetectorDescriptionValue(''); + + await ml.jobWizardAdvanced.selectDetectorFunction(detector.function); + if (detector.hasOwnProperty('field')) { + await ml.jobWizardAdvanced.selectDetectorField(detector.field!); + } + if (detector.hasOwnProperty('byField')) { + await ml.jobWizardAdvanced.selectDetectorByField(detector.byField!); + } + if (detector.hasOwnProperty('overField')) { + await ml.jobWizardAdvanced.selectDetectorOverField(detector.overField!); + } + if (detector.hasOwnProperty('partitionField')) { + await ml.jobWizardAdvanced.selectDetectorPartitionField(detector.partitionField!); + } + if (detector.hasOwnProperty('excludeFrequent')) { + await ml.jobWizardAdvanced.selectDetectorExcludeFrequent(detector.excludeFrequent!); + } + if (detector.hasOwnProperty('description')) { + await ml.jobWizardAdvanced.setDetectorDescription(detector.description!); + } + + await ml.jobWizardAdvanced.confirmAddDetectorModal(); + } + + await ml.testExecution.logTestStep('advanced job creation displays detector entries'); + for (const [index, detector] of testData.pickFieldsConfig.detectors.entries()) { + await ml.jobWizardAdvanced.assertDetectorEntryExists( + index + previousDetectors.length, + detector.identifier, + detector.hasOwnProperty('description') ? detector.description! : undefined + ); + } + + await ml.testExecution.logTestStep('advanced job creation retains the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.assertBucketSpanValue(bucketSpan); + + await ml.testExecution.logTestStep( + `advanced job creation retains influencers from ${previousJobWizard}` + ); + await ml.jobWizardCommon.assertInfluencerInputExists(); + await ml.jobWizardCommon.assertInfluencerSelection(previousInfluencers); + for (const influencer of testData.pickFieldsConfig.influencers) { + await ml.jobWizardCommon.addInfluencer(influencer); + } + + await ml.testExecution.logTestStep('advanced job creation inputs the model memory limit'); + await ml.jobWizardCommon.assertModelMemoryLimitInputExists({ + withAdvancedSection: false, + }); + await ml.jobWizardCommon.setModelMemoryLimit(testData.pickFieldsConfig.memoryLimit, { + withAdvancedSection: false, + }); + + await ml.testExecution.logTestStep('advanced job creation displays the job details step'); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep( + `advanced job creation retains the job id from ${previousJobWizard}` + ); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.assertJobIdValue(testData.jobId); + + await ml.testExecution.logTestStep( + `advanced job creation retains the job description from ${previousJobWizard}` + ); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.assertJobDescriptionValue(testData.jobDescription); + + await ml.testExecution.logTestStep( + `advanced job creation retains job groups and inputs new groups from ${previousJobWizard}` + ); + await ml.jobWizardCommon.assertJobGroupInputExists(); + for (const jobGroup of testData.jobGroups) { + await ml.jobWizardCommon.addJobGroup(jobGroup); + } + await ml.jobWizardCommon.assertJobGroupSelection([ + ...previousJobGroups, + ...testData.jobGroups, + ]); + + await ml.testExecution.logTestStep( + 'advanced job creation opens the additional settings section' + ); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep( + `advanced job creation retains calendar and custom url from ${previousJobWizard}` + ); + await ml.jobWizardCommon.assertCalendarsSelection([calendarId]); + await ml.jobWizardCommon.assertCustomUrlLabel(0, { label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('advanced job creation displays the validation step'); + await ml.jobWizardCommon.advanceToValidationSection(); + + await ml.testExecution.logTestStep('advanced job creation displays the summary step'); + await ml.jobWizardCommon.advanceToSummarySection(); + }); + + it('advanced job creation runs the job and displays it correctly in the job list', async () => { + await ml.testExecution.logTestStep('advanced job creates the job and finishes processing'); + await ml.jobWizardCommon.assertCreateJobButtonExists(); + await ml.jobWizardAdvanced.createJob(); + await ml.jobManagement.assertStartDatafeedModalExists(); + await ml.jobManagement.confirmStartDatafeedModal(); + + await ml.testExecution.logTestStep( + 'advanced job creation displays the created job in the job list' + ); + await ml.jobTable.filterWithSearchString(testData.jobId, 1); + }); + }; + + describe('conversion to advanced job wizard', function () { + this.tags(['ml']); + + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/categorization_small'); + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); + await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createIndexPatternIfNeeded('ft_categorization_small', '@timestamp'); + + await ml.testResources.setKibanaTimeZoneToUTC(); + + await ml.api.createCalendar(calendarId); + await ml.securityUI.loginAsMlPowerUser(); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteIndexPatternByTitle('ft_categorization_small'); + }); + + describe('from multi-metric job creation wizard', function () { + const jobGroups = ['automated', 'farequote', 'multi-metric']; + const splitField = 'customer_gender'; + const multiMetricDetectors = [ + { + identifier: 'High count(Event rate)', + advancedJobIdentifier: 'high_count partition_field_name=customer_gender', + }, + { + identifier: 'Low mean(products.base_price)', + advancedJobIdentifier: + 'low_mean("products.base_price") partition_field_name=customer_gender', + }, + ]; + const multiMetricInfluencers = ['customer_gender']; + + const bucketSpan = '2h'; + const memoryLimit = '8mb'; + + const testData = { + suiteTitle: 'multi-metric job to advanced job wizard', + jobSource: 'ft_ecommerce', + jobId: `ec_multimetric_to_advanced_1_${Date.now()}`, + jobDescription: 'advanced job from multi-metric wizard', + jobGroups: ['advanced'], + pickFieldsConfig: { + detectors: [], + influencers: ['geoip.region_name'], + bucketSpan: '1h', + memoryLimit: '10mb', + } as PickFieldsConfig, + datafeedConfig: { + queryDelay: '55s', + frequency: '350s', + scrollSize: '999', + } as DatafeedConfig, + }; + + it('multi-metric job creation loads the multi-metric job wizard for the source data', async () => { + await ml.testExecution.logTestStep('job creation loads the job management page'); + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + + await ml.testExecution.logTestStep('job creation loads the new job source selection page'); + await ml.jobManagement.navigateToNewJobSourceSelection(); + + await ml.testExecution.logTestStep('job creation loads the job type selection page'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('ft_ecommerce'); + + await ml.testExecution.logTestStep('job creation loads the multi-metric job wizard page'); + await ml.jobTypeSelection.selectMultiMetricJob(); + }); + + it('multi-metric job creation navigates through the multi-metric job wizard and sets all needed fields', async () => { + await ml.testExecution.logTestStep('job creation displays the time range step'); + await ml.jobWizardCommon.assertTimeRangeSectionExists(); + + await ml.testExecution.logTestStep('job creation sets the time range'); + await ml.jobWizardCommon.clickUseFullDataButton( + 'Jun 12, 2019 @ 00:04:19.000', + 'Jul 12, 2019 @ 23:45:36.000' + ); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the event rate chart' + ); + await ml.jobWizardCommon.assertEventRateChartExists(); + await ml.jobWizardCommon.assertEventRateChartHasData(); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the pick fields step' + ); + await ml.jobWizardCommon.advanceToPickFieldsSection(); + + for (const [ + index, + { identifier: aggAndFieldIdentifier }, + ] of multiMetricDetectors.entries()) { + await ml.jobWizardCommon.assertAggAndFieldInputExists(); + await ml.jobWizardCommon.selectAggAndField(aggAndFieldIdentifier, false); + await ml.jobWizardCommon.assertDetectorPreviewExists( + aggAndFieldIdentifier, + index, + 'LINE' + ); + } + + await ml.testExecution.logTestStep( + 'multi-metric job creation inputs the split field and displays split cards' + ); + await ml.jobWizardMultiMetric.assertSplitFieldInputExists(); + await ml.jobWizardMultiMetric.selectSplitField(splitField); + + await ml.jobWizardMultiMetric.assertDetectorSplitExists(splitField); + await ml.jobWizardMultiMetric.assertDetectorSplitFrontCardTitle('FEMALE'); + await ml.jobWizardMultiMetric.assertDetectorSplitNumberOfBackCards(1); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the influencer field' + ); + await ml.jobWizardCommon.assertInfluencerInputExists(); + await ml.jobWizardCommon.assertInfluencerSelection(multiMetricInfluencers); + + await ml.testExecution.logTestStep('multi-metric job creation inputs the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.setBucketSpan(bucketSpan); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the job details step' + ); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep('multi-metric job creation inputs the job id'); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.setJobId(testData.jobId); + + await ml.testExecution.logTestStep('multi-metric job creation inputs the job description'); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.setJobDescription(testData.jobDescription); + + await ml.testExecution.logTestStep('multi-metric job creation inputs job groups'); + await ml.jobWizardCommon.assertJobGroupInputExists(); + for (const jobGroup of jobGroups) { + await ml.jobWizardCommon.addJobGroup(jobGroup); + } + await ml.jobWizardCommon.assertJobGroupSelection(jobGroups); + + await ml.testExecution.logTestStep( + 'multi-metric job creation opens the additional settings section' + ); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep('multi-metric job creation adds a new custom url'); + await ml.jobWizardCommon.addCustomUrl({ label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('multi-metric job creation assigns calendars'); + await ml.jobWizardCommon.addCalendar(calendarId); + + await ml.testExecution.logTestStep('multi-metric job creation opens the advanced section'); + await ml.jobWizardCommon.ensureAdvancedSectionOpen(); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the model plot switch' + ); + await ml.jobWizardCommon.assertModelPlotSwitchExists(); + + await ml.testExecution.logTestStep( + 'multi-metric job creation enables the dedicated index switch' + ); + await ml.jobWizardCommon.assertDedicatedIndexSwitchExists(); + await ml.jobWizardCommon.activateDedicatedIndexSwitch(); + + await ml.testExecution.logTestStep( + 'multi-metric job creation inputs the model memory limit' + ); + await ml.jobWizardCommon.assertModelMemoryLimitInputExists(); + await ml.jobWizardCommon.setModelMemoryLimit(memoryLimit); + + await ml.testExecution.logTestStep( + 'multi-metric job creation displays the validation step' + ); + await ml.jobWizardCommon.advanceToValidationSection(); + + await ml.testExecution.logTestStep('multi-metric job creation displays the summary step'); + await ml.jobWizardCommon.advanceToSummarySection(); + }); + + assertConversionToAdvancedJobWizardRetainsSettingsAndRuns({ + testSuite: 'multi-metric', + testData, + bucketSpan, + previousInfluencers: multiMetricInfluencers, + previousDetectors: multiMetricDetectors, + previousJobGroups: jobGroups, + }); + }); + + describe('from population job creation wizard', function () { + const jobGroups = ['automated', 'ecommerce', 'population']; + const populationField = 'customer_id'; + const populationDetectors = [ + { + identifier: 'Mean(products.base_price)', + splitField: 'customer_gender', + frontCardTitle: 'FEMALE', + numberOfBackCards: 1, + advancedJobIdentifier: 'mean("products.base_price") by customer_gender over customer_id', + }, + { + identifier: 'Mean(products.quantity)', + splitField: 'category.keyword', + frontCardTitle: "Men's Clothing", + numberOfBackCards: 5, + advancedJobIdentifier: 'mean("products.quantity") by "category.keyword" over customer_id', + }, + ]; + const populationInfluencers = [populationField].concat( + populationDetectors.map((detector) => detector.splitField) + ); + + const bucketSpan = '2h'; + const memoryLimit = '8mb'; + + const testData = { + suiteTitle: 'population job to advanced job wizard', + jobSource: 'ft_ecommerce', + jobId: `ec_population_to_advanced_1_${Date.now()}`, + jobDescription: 'advanced job from population wizard', + jobGroups: ['advanced'], + pickFieldsConfig: { + detectors: [ + { + identifier: 'high_count', + function: 'high_count', + description: 'high_count detector without split', + } as Detector, + { + identifier: 'mean("products.base_price") by "category.keyword"', + function: 'mean', + field: 'products.base_price', + byField: 'category.keyword', + } as Detector, + { + identifier: 'sum("products.discount_amount") over customer_id', + function: 'sum', + field: 'products.discount_amount', + overField: 'customer_id', + } as Detector, + { + identifier: 'median(total_quantity) partition_field_name=customer_gender', + function: 'median', + field: 'total_quantity', + partitionField: 'customer_gender', + } as Detector, + { + identifier: + 'max(total_quantity) by "geoip.continent_name" over customer_id partition_field_name=customer_gender', + function: 'max', + field: 'total_quantity', + byField: 'geoip.continent_name', + overField: 'customer_id', + partitionField: 'customer_gender', + } as Detector, + ], + influencers: ['geoip.continent_name'], + bucketSpan: '1h', + memoryLimit: '10mb', + } as PickFieldsConfig, + datafeedConfig: { + queryDelay: '55s', + frequency: '350s', + scrollSize: '999', + } as DatafeedConfig, + }; + + it('population job creation loads the population wizard for the source data', async () => { + await ml.testExecution.logTestStep('job creation loads the job management page'); + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + + await ml.testExecution.logTestStep('job creation loads the new job source selection page'); + await ml.jobManagement.navigateToNewJobSourceSelection(); + + await ml.testExecution.logTestStep('job creation loads the job type selection page'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('ft_ecommerce'); + + await ml.testExecution.logTestStep('job creation loads the population job wizard page'); + await ml.jobTypeSelection.selectPopulationJob(); + }); + + it('population job creation navigates through the population wizard and sets all needed fields', async () => { + await ml.testExecution.logTestStep('job creation displays the time range step'); + await ml.jobWizardCommon.assertTimeRangeSectionExists(); + + await ml.testExecution.logTestStep('job creation sets the time range'); + await ml.jobWizardCommon.clickUseFullDataButton( + 'Jun 12, 2019 @ 00:04:19.000', + 'Jul 12, 2019 @ 23:45:36.000' + ); + + await ml.testExecution.logTestStep('population job creation displays the event rate chart'); + await ml.jobWizardCommon.assertEventRateChartExists(); + await ml.jobWizardCommon.assertEventRateChartHasData(); + + await ml.testExecution.logTestStep('population job creation displays the pick fields step'); + await ml.jobWizardCommon.advanceToPickFieldsSection(); + + await ml.testExecution.logTestStep('population job creation selects the population field'); + await ml.jobWizardPopulation.selectPopulationField(populationField); + + await ml.testExecution.logTestStep( + 'population job creation selects populationDetectors and displays detector previews' + ); + for (const [index, detector] of populationDetectors.entries()) { + await ml.jobWizardCommon.assertAggAndFieldInputExists(); + await ml.jobWizardCommon.selectAggAndField(detector.identifier, false); + await ml.jobWizardCommon.assertDetectorPreviewExists( + detector.identifier, + index, + 'SCATTER' + ); + } + + await ml.testExecution.logTestStep( + 'population job creation inputs detector split fields and displays split cards' + ); + for (const [index, detector] of populationDetectors.entries()) { + await ml.jobWizardPopulation.assertDetectorSplitFieldInputExists(index); + await ml.jobWizardPopulation.selectDetectorSplitField(index, detector.splitField); + + await ml.jobWizardPopulation.assertDetectorSplitExists(index); + await ml.jobWizardPopulation.assertDetectorSplitFrontCardTitle( + index, + detector.frontCardTitle + ); + await ml.jobWizardPopulation.assertDetectorSplitNumberOfBackCards( + index, + detector.numberOfBackCards + ); + } + + await ml.testExecution.logTestStep('population job creation displays the influencer field'); + await ml.jobWizardCommon.assertInfluencerInputExists(); + await ml.jobWizardCommon.assertInfluencerSelection(populationInfluencers); + + await ml.testExecution.logTestStep('population job creation inputs the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.setBucketSpan(bucketSpan); + + await ml.testExecution.logTestStep('population job creation displays the job details step'); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep('population job creation inputs the job id'); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.setJobId(testData.jobId); + + await ml.testExecution.logTestStep('population job creation inputs the job description'); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.setJobDescription(testData.jobDescription); + + await ml.testExecution.logTestStep('population job creation inputs job groups'); + await ml.jobWizardCommon.assertJobGroupInputExists(); + for (const jobGroup of jobGroups) { + await ml.jobWizardCommon.addJobGroup(jobGroup); + } + await ml.jobWizardCommon.assertJobGroupSelection(jobGroups); + + await ml.testExecution.logTestStep( + 'population job creation opens the additional settings section' + ); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep('population job creation adds a new custom url'); + await ml.jobWizardCommon.addCustomUrl({ label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('population job creation assigns calendars'); + await ml.jobWizardCommon.addCalendar(calendarId); + + await ml.testExecution.logTestStep('population job creation opens the advanced section'); + await ml.jobWizardCommon.ensureAdvancedSectionOpen(); + + await ml.testExecution.logTestStep( + 'population job creation displays the model plot switch' + ); + await ml.jobWizardCommon.assertModelPlotSwitchExists(); + + await ml.testExecution.logTestStep( + 'population job creation enables the dedicated index switch' + ); + await ml.jobWizardCommon.assertDedicatedIndexSwitchExists(); + await ml.jobWizardCommon.activateDedicatedIndexSwitch(); + + await ml.testExecution.logTestStep('population job creation inputs the model memory limit'); + await ml.jobWizardCommon.assertModelMemoryLimitInputExists(); + await ml.jobWizardCommon.setModelMemoryLimit(memoryLimit); + + await ml.testExecution.logTestStep('population job creation displays the validation step'); + await ml.jobWizardCommon.advanceToValidationSection(); + + await ml.testExecution.logTestStep('population job creation displays the summary step'); + await ml.jobWizardCommon.advanceToSummarySection(); + }); + + assertConversionToAdvancedJobWizardRetainsSettingsAndRuns({ + testSuite: 'population', + testData, + bucketSpan, + previousInfluencers: populationInfluencers, + previousDetectors: populationDetectors, + previousJobGroups: jobGroups, + }); + }); + + describe('from categorization job creation wizard', function () { + const jobGroups = ['automated', 'categorization']; + const detectorTypeIdentifier = 'Rare'; + const categorizationFieldIdentifier = 'field1'; + const categorizationExampleCount = 5; + const bucketSpan = '1d'; + const memoryLimit = '15MB'; + const categorizationInfluencers = ['mlcategory']; + const testData = { + suiteTitle: 'categorization job to advanced job wizard', + jobSource: 'ft_ecommerce', + jobId: `categorization_to_advanced_${Date.now()}`, + jobDescription: 'advanced job from categorization wizard', + jobGroups: ['advanced'], + categorizationFieldIdentifier, + pickFieldsConfig: { + categorizationField: 'field1', + detectors: [], + influencers: [], + bucketSpan: '1h', + memoryLimit: '10mb', + } as PickFieldsConfig, + datafeedConfig: { + queryDelay: '55s', + frequency: '350s', + scrollSize: '999', + } as DatafeedConfig, + }; + const categorizationDetectors = [{ advancedJobIdentifier: 'rare by mlcategory' }]; + + it('categorization job creation loads the categorization wizard for the source data', async () => { + await ml.testExecution.logTestStep( + 'categorization job creation loads the job management page' + ); + await ml.testExecution.logTestStep(''); + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + + await ml.testExecution.logTestStep( + 'categorization job creation loads the new job source selection page' + ); + await ml.jobManagement.navigateToNewJobSourceSelection(); + + await ml.testExecution.logTestStep( + 'categorization job creation loads the job type selection page' + ); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('ft_categorization_small'); + + await ml.testExecution.logTestStep( + 'categorization job creation loads the categorization job wizard page' + ); + await ml.jobTypeSelection.selectCategorizationJob(); + }); + + it('categorization job creation navigates through the categorization wizard and sets all needed fields', async () => { + await ml.testExecution.logTestStep( + 'categorization job creation displays the time range step' + ); + await ml.jobWizardCommon.assertTimeRangeSectionExists(); + + await ml.testExecution.logTestStep('categorization job creation sets the time range'); + await ml.jobWizardCommon.clickUseFullDataButton( + 'Apr 5, 2019 @ 11:25:35.770', + 'Nov 21, 2019 @ 00:01:13.923' + ); + + await ml.testExecution.logTestStep( + 'categorization job creation displays the event rate chart' + ); + await ml.jobWizardCommon.assertEventRateChartExists(); + await ml.jobWizardCommon.assertEventRateChartHasData(); + + await ml.testExecution.logTestStep( + 'categorization job creation displays the pick fields step' + ); + await ml.jobWizardCommon.advanceToPickFieldsSection(); + + await ml.testExecution.logTestStep( + `categorization job creation selects ${detectorTypeIdentifier} detector type` + ); + await ml.jobWizardCategorization.assertCategorizationDetectorTypeSelectionExists(); + await ml.jobWizardCategorization.selectCategorizationDetectorType(detectorTypeIdentifier); + + await ml.testExecution.logTestStep( + `categorization job creation selects the categorization field` + ); + await ml.jobWizardCategorization.selectCategorizationField( + testData.categorizationFieldIdentifier + ); + await ml.jobWizardCategorization.assertCategorizationExamplesCallout( + CATEGORY_EXAMPLES_VALIDATION_STATUS.VALID + ); + await ml.jobWizardCategorization.assertCategorizationExamplesTable( + categorizationExampleCount + ); + + await ml.testExecution.logTestStep('categorization job creation inputs the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.setBucketSpan(bucketSpan); + + await ml.testExecution.logTestStep( + 'categorization job creation displays the job details step' + ); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep('categorization job creation inputs the job id'); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.setJobId(testData.jobId); + + await ml.testExecution.logTestStep( + 'categorization job creation inputs the job description' + ); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.setJobDescription(testData.jobDescription); + + await ml.testExecution.logTestStep('categorization job creation inputs job groups'); + await ml.jobWizardCommon.assertJobGroupInputExists(); + for (const jobGroup of jobGroups) { + await ml.jobWizardCommon.addJobGroup(jobGroup); + } + await ml.jobWizardCommon.assertJobGroupSelection(jobGroups); + + await ml.testExecution.logTestStep( + 'categorization job creation opens the additional settings section' + ); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep('categorization job creation adds a new custom url'); + await ml.jobWizardCommon.addCustomUrl({ label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('categorization job creation assigns calendars'); + await ml.jobWizardCommon.addCalendar(calendarId); + + await ml.testExecution.logTestStep( + 'categorization job creation opens the advanced section' + ); + await ml.jobWizardCommon.ensureAdvancedSectionOpen(); + + await ml.testExecution.logTestStep( + 'categorization job creation displays the model plot switch' + ); + await ml.jobWizardCommon.assertModelPlotSwitchExists(); + await ml.jobWizardCommon.assertModelPlotSwitchEnabled(false); + await ml.jobWizardCommon.assertModelPlotSwitchCheckedState(false); + + await ml.testExecution.logTestStep( + 'categorization job creation enables the dedicated index switch' + ); + await ml.jobWizardCommon.assertDedicatedIndexSwitchExists(); + await ml.jobWizardCommon.activateDedicatedIndexSwitch(); + + await ml.testExecution.logTestStep( + 'categorization job creation inputs the model memory limit' + ); + await ml.jobWizardCommon.assertModelMemoryLimitInputExists(); + await ml.jobWizardCommon.setModelMemoryLimit(memoryLimit); + + await ml.testExecution.logTestStep( + 'categorization job creation displays the validation step' + ); + await ml.jobWizardCommon.advanceToValidationSection(); + + await ml.testExecution.logTestStep('categorization job creation displays the summary step'); + await ml.jobWizardCommon.advanceToSummarySection(); + }); + + assertConversionToAdvancedJobWizardRetainsSettingsAndRuns({ + testSuite: 'categorization', + testData, + bucketSpan, + previousInfluencers: categorizationInfluencers, + previousDetectors: categorizationDetectors, + previousJobGroups: jobGroups, + }); + }); + }); +} diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts new file mode 100644 index 00000000000000..c4694400300382 --- /dev/null +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts @@ -0,0 +1,213 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const config = getService('config'); + const esNode = config.get('esTestCluster.ccs') + ? getService('remoteEsArchiver' as 'esArchiver') + : getService('esArchiver'); + const ml = getService('ml'); + + const calendarId = `wizard-test-calendar_${Date.now()}`; + const remoteName = 'ftr-remote:'; + const indexPatternName = 'ft_farequote'; + const indexPatternString = config.get('esTestCluster.ccs') + ? remoteName + indexPatternName + : indexPatternName; + + describe('single metric job conversion to multi-metric job', function () { + this.tags(['ml']); + before(async () => { + await esNode.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); + await ml.testResources.createIndexPatternIfNeeded(indexPatternString, '@timestamp'); + await ml.testResources.setKibanaTimeZoneToUTC(); + + await ml.api.createCalendar(calendarId); + await ml.securityUI.loginAsMlPowerUser(); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + await ml.testResources.deleteIndexPatternByTitle(indexPatternString); + }); + + const jobId = `fq_single_to_multi_${Date.now()}`; + const jobDescription = 'Create multi metric job from single metric job'; + const jobGroups = ['automated', 'farequote', 'multi-metric']; + const smAggAndFieldIdentifier = 'Mean(responsetime)'; + const bucketSpan = '30m'; + + const mmAggAndFieldIdentifiers = [ + 'Min(responsetime)', + 'Max(responsetime)', + 'High mean(responsetime)', + ]; + const splitField = 'airline'; + + it('loads the single metric wizard for the source data', async () => { + await ml.testExecution.logTestStep('loads the job management page'); + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + + await ml.testExecution.logTestStep('loads the new job source selection page'); + await ml.jobManagement.navigateToNewJobSourceSelection(); + + await ml.testExecution.logTestStep('loads the job type selection page'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(indexPatternString); + + await ml.testExecution.logTestStep('loads the single metric job wizard page'); + await ml.jobTypeSelection.selectSingleMetricJob(); + }); + + it('navigates through the single metric wizard and sets all needed fields', async () => { + await ml.testExecution.logTestStep('displays the time range step'); + await ml.jobWizardCommon.assertTimeRangeSectionExists(); + + await ml.testExecution.logTestStep('sets the time range'); + await ml.jobWizardCommon.clickUseFullDataButton( + 'Feb 7, 2016 @ 00:00:00.000', + 'Feb 11, 2016 @ 23:59:54.000' + ); + + await ml.testExecution.logTestStep('displays the event rate chart'); + await ml.jobWizardCommon.assertEventRateChartExists(); + await ml.jobWizardCommon.assertEventRateChartHasData(); + + await ml.testExecution.logTestStep('displays the pick fields step'); + await ml.jobWizardCommon.advanceToPickFieldsSection(); + + await ml.testExecution.logTestStep('selects field and aggregation'); + await ml.jobWizardCommon.selectAggAndField(smAggAndFieldIdentifier, true); + await ml.jobWizardCommon.assertAnomalyChartExists('LINE'); + + await ml.testExecution.logTestStep('inputs the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.setBucketSpan(bucketSpan); + + await ml.testExecution.logTestStep('displays the job details step'); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep('inputs the job id'); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.setJobId(jobId); + + await ml.testExecution.logTestStep('inputs the job description'); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.setJobDescription(jobDescription); + + await ml.testExecution.logTestStep('inputs job groups'); + await ml.jobWizardCommon.assertJobGroupInputExists(); + for (const jobGroup of jobGroups) { + await ml.jobWizardCommon.addJobGroup(jobGroup); + } + await ml.jobWizardCommon.assertJobGroupSelection(jobGroups); + + await ml.testExecution.logTestStep('opens the additional settings section'); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep('adds a new custom url'); + await ml.jobWizardCommon.addCustomUrl({ label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('assigns calendars'); + await ml.jobWizardCommon.addCalendar(calendarId); + }); + + it('converts to multi-metric job creation wizard and retains all previously set fields', async () => { + await ml.testExecution.logTestStep( + 'navigates to previous page and converts to multi-metric job wizard' + ); + await ml.jobWizardCommon.navigateToPreviousJobWizardPage( + 'mlJobWizardButtonConvertToMultiMetric' + ); + await ml.jobWizardCommon.convertToMultiMetricJobWizard(); + await ml.jobWizardCommon.assertPickFieldsSectionExists(); + + await ml.testExecution.logTestStep( + 'multi-metric job wizard selects detectors and displays detector previews' + ); + for (const [index, aggAndFieldIdentifier] of mmAggAndFieldIdentifiers.entries()) { + await ml.jobWizardCommon.assertAggAndFieldInputExists(); + await ml.jobWizardCommon.selectAggAndField(aggAndFieldIdentifier, false); + await ml.jobWizardCommon.assertDetectorPreviewExists( + aggAndFieldIdentifier, + // +1 to account for the one detector set from single metric job wizard + index + 1, + 'LINE' + ); + } + + await ml.jobWizardMultiMetric.selectSplitField(splitField); + + await ml.jobWizardMultiMetric.assertDetectorSplitExists(splitField); + await ml.jobWizardMultiMetric.assertDetectorSplitFrontCardTitle('AAL'); + await ml.jobWizardMultiMetric.assertDetectorSplitNumberOfBackCards(9); + + await ml.jobWizardCommon.assertInfluencerSelection([splitField]); + + await ml.testExecution.logTestStep('multi-metric job wizard retains the bucket span'); + await ml.jobWizardCommon.assertBucketSpanInputExists(); + await ml.jobWizardCommon.assertBucketSpanValue(bucketSpan); + + await ml.testExecution.logTestStep('multi-metric job wizard displays the job details step'); + await ml.jobWizardCommon.advanceToJobDetailsSection(); + + await ml.testExecution.logTestStep('multi-metric job wizard retains job id'); + await ml.jobWizardCommon.assertJobIdInputExists(); + await ml.jobWizardCommon.assertJobIdValue(jobId); + + await ml.testExecution.logTestStep('multi-metric job wizard retains the job description'); + await ml.jobWizardCommon.assertJobDescriptionInputExists(); + await ml.jobWizardCommon.assertJobDescriptionValue(jobDescription); + + await ml.testExecution.logTestStep('multi-metric job wizard retains job groups'); + await ml.jobWizardCommon.assertJobGroupInputExists(); + await ml.jobWizardCommon.assertJobGroupSelection(jobGroups); + + await ml.testExecution.logTestStep( + 'multi-metric job wizard opens the additional settings section' + ); + await ml.jobWizardCommon.ensureAdditionalSettingsSectionOpen(); + + await ml.testExecution.logTestStep('multi-metric job wizard retains calendar and custom url'); + await ml.jobWizardCommon.assertCalendarsSelection([calendarId]); + await ml.jobWizardCommon.assertCustomUrlLabel(0, { label: 'check-kibana-dashboard' }); + + await ml.testExecution.logTestStep('multi-metric job wizard displays the validation step'); + await ml.jobWizardCommon.advanceToValidationSection(); + + await ml.testExecution.logTestStep('multi-metric job wizard displays the summary step'); + await ml.jobWizardCommon.advanceToSummarySection(); + }); + + it('runs the converted job and displays it correctly in the job list', async () => { + await ml.testExecution.logTestStep( + 'multi-metric job wizard creates the job and finishes processing' + ); + await ml.jobWizardCommon.assertCreateJobButtonExists(); + await ml.jobWizardCommon.createJobAndWaitForCompletion(); + + await ml.testExecution.logTestStep( + 'multi-metric job wizard displays the created job in the job list' + ); + await ml.navigation.navigateToMl(); + await ml.navigation.navigateToJobManagement(); + + await ml.jobTable.filterWithSearchString(jobId, 1); + + await ml.testExecution.logTestStep( + 'job list displays details for the created job in the job list' + ); + + await ml.testExecution.logTestStep('job has detector results'); + for (let i = 0; i < mmAggAndFieldIdentifiers.length; i++) { + await ml.api.assertDetectorResultsExist(jobId, i); + } + }); + }); +} diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts index ed9f63be66dd4b..d63f6af6c04861 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts @@ -6,31 +6,7 @@ */ import { FtrProviderContext } from '../../../ftr_provider_context'; - -interface Detector { - identifier: string; - function: string; - field?: string; - byField?: string; - overField?: string; - partitionField?: string; - excludeFrequent?: string; - description?: string; -} - -interface DatafeedConfig { - queryDelay?: string; - frequency?: string; - scrollSize?: string; -} - -interface PickFieldsConfig { - detectors: Detector[]; - influencers: string[]; - bucketSpan: string; - memoryLimit: string; - summaryCountField?: string; -} +import type { PickFieldsConfig, DatafeedConfig, Detector } from './types'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/index.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/index.ts index e350ced98aa79f..254bd76f5616bc 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/index.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/index.ts @@ -50,6 +50,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./date_nanos_job')); loadTestFile(require.resolve('./custom_urls')); loadTestFile(require.resolve('./delete_job_and_delete_annotations')); + loadTestFile(require.resolve('./convert_single_metric_job_to_multi_metric')); + loadTestFile(require.resolve('./convert_jobs_to_advanced_job')); } }); } diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/types.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/types.ts new file mode 100644 index 00000000000000..3aaa182ff75851 --- /dev/null +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/types.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface Detector { + identifier: string; + function: string; + field?: string; + byField?: string; + overField?: string; + partitionField?: string; + excludeFrequent?: string; + description?: string; +} + +export interface DatafeedConfig { + queryDelay?: string; + frequency?: string; + scrollSize?: string; +} + +export interface PickFieldsConfig { + detectors: Detector[]; + influencers: string[]; + bucketSpan: string; + memoryLimit: string; + categorizationField?: string; + summaryCountField?: string; +} diff --git a/x-pack/test/functional/services/ml/job_wizard_common.ts b/x-pack/test/functional/services/ml/job_wizard_common.ts index 5f3c685467c08f..9d9c91f500456a 100644 --- a/x-pack/test/functional/services/ml/job_wizard_common.ts +++ b/x-pack/test/functional/services/ml/job_wizard_common.ts @@ -17,7 +17,7 @@ export interface SectionOptions { } export function MachineLearningJobWizardCommonProvider( - { getService }: FtrProviderContext, + { getPageObject, getService }: FtrProviderContext, mlCommonUI: MlCommonUI, customUrls: MlCustomUrls, mlCommonFieldStatsFlyout: MlCommonFieldStatsFlyout @@ -25,6 +25,7 @@ export function MachineLearningJobWizardCommonProvider( const comboBox = getService('comboBox'); const retry = getService('retry'); const testSubjects = getService('testSubjects'); + const headerPage = getPageObject('header'); function advancedSectionSelector(subSelector?: string) { const subj = 'mlJobWizardAdvancedSection'; @@ -492,6 +493,20 @@ export function MachineLearningJobWizardCommonProvider( await testSubjects.existOrFail('mlJobWizardButtonCreateJob'); }, + async assertConvertToAdvancedJobExists() { + await testSubjects.existOrFail('mlJobWizardButtonConvertToAdvancedJob'); + }, + + async convertToAdvancedJobWizard() { + await this.assertConvertToAdvancedJobExists(); + + await retry.tryForTime(5000, async () => { + await testSubjects.click('mlJobWizardButtonConvertToAdvancedJob'); + await headerPage.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('mlPageJobWizardHeader-advanced'); + }); + }, + async assertDateRangeSelectionExists() { await testSubjects.existOrFail('mlJobWizardDateRange'); }, @@ -558,6 +573,12 @@ export function MachineLearningJobWizardCommonProvider( await customUrls.assertCustomUrlLabel(expectedIndex, customUrl.label); }, + async assertCustomUrlLabel(expectedIndex: number, customUrl: { label: string }) { + await this.ensureAdditionalSettingsSectionOpen(); + + await customUrls.assertCustomUrlLabel(expectedIndex, customUrl.label); + }, + async ensureAdvancedSectionOpen() { await retry.tryForTime(5000, async () => { if ((await testSubjects.exists(advancedSectionSelector())) === false) { @@ -576,5 +597,27 @@ export function MachineLearningJobWizardCommonProvider( await testSubjects.clickWhenNotDisabledWithoutRetry('mlJobWizardButtonCreateJob'); await testSubjects.existOrFail('mlPageJobManagement'); }, + + async assertConvertToMultiMetricButtonExist(bucketSpan: string) { + await testSubjects.existOrFail('mlJobWizardButtonConvertToMultiMetric'); + }, + + async convertToMultiMetricJobWizard() { + await retry.tryForTime(5 * 1000, async () => { + await testSubjects.click('mlJobWizardButtonConvertToMultiMetric'); + await headerPage.waitUntilLoadingHasFinished(); + + await testSubjects.existOrFail('mlPageJobWizardHeader-multi_metric'); + }); + }, + + async navigateToPreviousJobWizardPage(expectedSelector: string) { + await retry.tryForTime(5 * 1000, async () => { + await testSubjects.click('mlJobWizardNavButtonPrevious'); + await headerPage.waitUntilLoadingHasFinished(); + + await testSubjects.existOrFail(expectedSelector); + }); + }, }; } From 04f8885727053cb0f4c6b7f6749c110bc60a02b6 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 3 Jul 2023 19:49:51 +0100 Subject: [PATCH 36/98] skip flaky suite (#150790) --- .../sections/alerts_table/alerts_table_state.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx index 33e1a59ac0280d..755231033cc9c6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx @@ -707,7 +707,8 @@ describe('AlertsTableState', () => { }); }); - describe('field browser', () => { + // FLAKY: https://github.com/elastic/kibana/issues/150790 + describe.skip('field browser', () => { const browserFields: BrowserFields = { kibana: { fields: { From 6b02be44880b05713cc553fbe700b50135a2ab7a Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Mon, 3 Jul 2023 21:02:31 +0100 Subject: [PATCH 37/98] Restrict ability to disable features within a Space (#160416) Resolves https://github.com/elastic/kibana/issues/159392 ## Summary This PR hides the feature visibility section on the space management screen and disables adding `disabledFeatures` when creating or updating spaces using the REST API or spaces client on serverless. ## Screenshot ![Spaces-Elastic (2)](https://github.com/elastic/kibana/assets/190132/14d4900b-989d-420c-bddf-5ff70d305934) ## Testing 1. Start Kibana in serverless mode: `yarn start --serverless` 2. Edit default space and observe that the feature visibility section is not rendered 3. Quit Kibana and restart using classic mode: `yarn start` 4. Edit default space and observe that the feature visibility section is rendered correctly 5. Other considerations: - Disabling feature visibility in the classic offering should throw an error (`xpack.spaces.allowFeatureVisibility: false`) - Enabling feature visibility on serverless should throw an error (`xpack.spaces.allowFeatureVisibility: true`) --- config/serverless.yml | 3 +- .../test_suites/core_plugins/rendering.ts | 1 + x-pack/plugins/spaces/public/config.ts | 1 + .../edit_space/manage_space_page.test.tsx | 65 ++++++++ .../edit_space/manage_space_page.tsx | 18 ++- .../management/management_service.test.ts | 1 + .../management/spaces_management_app.test.tsx | 5 +- .../management/spaces_management_app.tsx | 2 + x-pack/plugins/spaces/server/config.test.ts | 23 +++ x-pack/plugins/spaces/server/config.ts | 16 ++ x-pack/plugins/spaces/server/index.ts | 1 + .../server/routes/api/external/post.test.ts | 2 + .../server/routes/api/external/put.test.ts | 1 + .../spaces_client/spaces_client.test.ts | 139 +++++++++++++++++- .../server/spaces_client/spaces_client.ts | 12 ++ .../test_suites/common/spaces.ts | 22 ++- 16 files changed, 296 insertions(+), 16 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index b7f2833810d0a1..e3ecaaa44a8d3b 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -53,8 +53,9 @@ server.versioned.versionResolution: newest # do not enforce client version check server.versioned.strictClientVersionCheck: false -# Enforce single "default" space +# Enforce single "default" space and disable feature visibility controls xpack.spaces.maxSpaces: 1 +xpack.spaces.allowFeatureVisibility: false # Temporarily allow unauthenticated access to task manager utilization & status/stats APIs for autoscaling status.allowAnonymous: true diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index c4f5cf5a695689..8ec34f1b91ec41 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -258,6 +258,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.security.showNavLinks (boolean)', 'xpack.security.ui (any)', 'xpack.spaces.maxSpaces (number)', + 'xpack.spaces.allowFeatureVisibility (any)', 'xpack.securitySolution.enableExperimental (array)', 'xpack.securitySolution.prebuiltRulesPackageVersion (string)', 'xpack.snapshot_restore.slm_ui.enabled (boolean)', diff --git a/x-pack/plugins/spaces/public/config.ts b/x-pack/plugins/spaces/public/config.ts index 1f0565016bfe5b..567c01c66cfe17 100644 --- a/x-pack/plugins/spaces/public/config.ts +++ b/x-pack/plugins/spaces/public/config.ts @@ -7,4 +7,5 @@ export interface ConfigType { maxSpaces: number; + allowFeatureVisibility: boolean; } diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx index 071f02e6d31141..ccb5412aa39c68 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx @@ -20,6 +20,7 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import type { SpacesManager } from '../../spaces_manager'; import { spacesManagerMock } from '../../spaces_manager/mocks'; import { ConfirmAlterActiveSpaceModal } from './confirm_alter_active_space_modal'; +import { EnabledFeatures } from './enabled_features'; import { ManageSpacePage } from './manage_space_page'; // To be resolved by EUI team. @@ -74,6 +75,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); @@ -103,6 +105,64 @@ describe('ManageSpacePage', () => { }); }); + it('shows feature visibility controls when allowed', async () => { + const spacesManager = spacesManagerMock.create(); + spacesManager.createSpace = jest.fn(spacesManager.createSpace); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); + + const wrapper = mountWithIntl( + + ); + + await waitFor(() => { + wrapper.update(); + expect(wrapper.find('input[name="name"]')).toHaveLength(1); + }); + + expect(wrapper.find(EnabledFeatures)).toHaveLength(1); + }); + + it('hides feature visibility controls when not allowed', async () => { + const spacesManager = spacesManagerMock.create(); + spacesManager.createSpace = jest.fn(spacesManager.createSpace); + spacesManager.getActiveSpace = jest.fn().mockResolvedValue(space); + + const wrapper = mountWithIntl( + + ); + + await waitFor(() => { + wrapper.update(); + expect(wrapper.find('input[name="name"]')).toHaveLength(1); + }); + + expect(wrapper.find(EnabledFeatures)).toHaveLength(0); + }); + it('allows a space to be updated', async () => { const spaceToUpdate = { id: 'existing-space', @@ -135,6 +195,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); @@ -202,6 +263,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); @@ -250,6 +312,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); @@ -286,6 +349,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); @@ -346,6 +410,7 @@ describe('ManageSpacePage', () => { catalogue: {}, spaces: { manage: true }, }} + allowFeatureVisibility /> ); diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx index f2892916d296fb..143f4fce34d26d 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.tsx @@ -54,6 +54,7 @@ interface Props { onLoadSpace?: (space: Space) => void; capabilities: Capabilities; history: ScopedHistory; + allowFeatureVisibility: boolean; } interface State { @@ -161,13 +162,16 @@ export class ManageSpacePage extends Component { validator={this.validator} /> - - - + {this.props.allowFeatureVisibility && ( + <> + + + + )} diff --git a/x-pack/plugins/spaces/public/management/management_service.test.ts b/x-pack/plugins/spaces/public/management/management_service.test.ts index 251707dd954982..105466e42827ea 100644 --- a/x-pack/plugins/spaces/public/management/management_service.test.ts +++ b/x-pack/plugins/spaces/public/management/management_service.test.ts @@ -18,6 +18,7 @@ import { ManagementService } from './management_service'; describe('ManagementService', () => { const config: ConfigType = { maxSpaces: 1000, + allowFeatureVisibility: true, }; describe('#setup', () => { diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx index 2b05b8a64c92d7..fecc81077d6908 100644 --- a/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_management_app.test.tsx @@ -28,6 +28,7 @@ import { spacesManagementApp } from './spaces_management_app'; const config: ConfigType = { maxSpaces: 1000, + allowFeatureVisibility: true, }; async function mountApp(basePath: string, pathname: string, spaceId?: string) { @@ -119,7 +120,7 @@ describe('spacesManagementApp', () => {
- Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/create","search":"","hash":""}}} + Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/create","search":"","hash":""}},"allowFeatureVisibility":true}
`); @@ -151,7 +152,7 @@ describe('spacesManagementApp', () => {
- Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"spaceId":"some-space","history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/some-space","search":"","hash":""}}} + Spaces Edit Page: {"capabilities":{"catalogue":{},"management":{},"navLinks":{}},"notifications":{"toasts":{}},"spacesManager":{"onActiveSpaceChange$":{}},"spaceId":"some-space","history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/some-space","search":"","hash":""}},"allowFeatureVisibility":true}

o<>>16l5$ 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 z zX7a~?nF>0HZ1%N_%;b+j^A&VZ*|Z1On8_c5mni5Uvsvq(Ft7g%S*f6d&R*Yql6n2d zGeJQIp?y4|NG-bZL$}Ixu-r2TuMeTOb6&d@a1h#(YeSgV?S>tY>!39U<{V;P2pD=? zj)T-p9C(3wA;9ab90#QtTBi~75{TzzISxXzC1)V>5{SnwISx8AG3ahFdaVt4D91r& z4(!gwsVIz#WBZq1oV{SAT{G7UNXmZ_&dsR zP@3U+3NlBuj2R%uL1;GJp2!^0GTK9qgU*Z}lzW0+Yoom7ILOSQ+0*LN_{cGG98{+N z^R8EE+;4&uhXcJ1#>`+Q0r-Y1;Gi;7mo8%_0gRlcpo8t)tjLSZB!JPg6?D+|ozd5r zNdW#a3OY#a%AG?#(w{DY@d`Rinoiel@c343Nq3yDKgBcy#NvU!jEce5vT^7)n9)4Z{ z2ceDbdFvj1=@HlDI%rL8595Y3KIyI;2dR0tcW5e&hd+_ypfrEZO{-1gVK3x32#s0w z-19UZ`c966&b(VZu{w>1V3Ob1FoJQHqT;8eX3OcB4O3io4^uK&mTLm3tHqQ0wFIu0`Q9%ct zO>+Fxoz`ddP|!hWyB(YLiw^DVK5`u__f-k2Ptlhi?W}-<(9ZP!UY5S}Ic{S`SA z`I*MY9h2jruJ_$aSE2F1Gjbf%wcwqFX*BMCNsfcMrWs_^pz+Z+`bX`Y2 z5aVE(-?%o{kG}8`nQ|M{wQcjtCiI05do9L6Vxk8QyGYwZvc)zi%-3EGYtZ(Rewz2fMd@C+9KGigj(Opo6Z@ zJGY2=R;+s~1s%k7eNHXr89|#43OdN^vTs(*GlF(q6m$^S1?fJ_v!T806m*c-&2Ppr z&xZDKP|(31ZgxxvGsvy4tAY+PyL;&fW{{iX5Ct8CHmQARMLM+oM#y!r+^38&%uC;i za~iFHgU}AiDw<7Sy7PFs4qB6T=6pUH?-wS=L23$?I{1dhou?)p8tE=GgFkEor<@q7;V%y%Jrk zF>mzs-mZXy%B*(G$Gp*Jzehm_+quPd{g^j79S$kzpzqr{_F&%RbULY^gTzh_{m#6> z>zt;bgU0R;c*eZJ>vB~=2a(+S8Zrm1nf< zHcjhh?w~anGGAPwanC|>9Hgc|%O!Pb+@pjX2c;=zH{lG84=E?dL1^x-Fl5G~3^}PBi=%BHW-^^sr z*BdrSK?jk&ne&)AS8;@wf(|PC?prEzuA+~xf(|l!CGyfDdRO5WprC`!eu=)y400P4 zq@aV)W(7J7phG(*Lau}5ekOd^R{9@)^mGLrgtpFxTFLaK`_Gl@pfz)5KDDOtF|l$S zq^6VmqRliudbu12rRiI9tPPEiS|`UrXjXs8w}!??ZkFSqGo8XB$J4mqPB{)TGiPh| z3L5v_C&xi$e$-zzfyRA~N^v;QE7NW>a~i()X$2fq=0V3j%xU<(7Zr4{oxA3m$xJ~Q zc|$=5eShWnmzjbv`o4k=5_{UGH#7ahKSMzWjs4~2$V|Toe5Ig+$bJbeU`~Isj{BgX zgUVhBsK87;neatH2bq0WxZGL#+Jk;8=%BMV^A!!F^^p8ygg1%sK(E)%la|n-4J#_w z!E%3=>-(3!^w81@I0$XM$;Bh+OAoIo*FkIMZM!mu#=~mJagZA8&||}BJhYx12c>Z= z;2uTeAx-2s2+hjtO-Isra7#H3I%Dm!?EsAjwU^@{GxO#@w5Rcjo#i;#&RIN8W0u+k zTPY3)diBb=&&;YE-&X+#l^OT#EHkTeqKkqKwsVux7cw7h!R`t==zI4!bC{2|(BTR? zNUZPG4q5c4OZX@S9W>VQehqtCj~J(*gUGs`oY0NdCxQf`VygipOK#o<7&F`;=Z>B>xbq=19U zI0saTqV;Ld6m+ni8{}ileDO3rOF;*HALiAc`QmA2j)D#n+r#z6G5TLV`n!S-8XMsF zlNszZ$G~5Bm*(HEJcw+l-S*P-wa+W4po7YG>bP?=tuH99po7c~X>*i$z#yiqf(|F(gaG)Fql?hys&OD~Nz*CCDfnJ5vN2Su0neU^3gUXn_@eiW)h5iaU z*v_@hsmnYTzG$L?4*H(&TRY~l@Wqo9bdcC4C!?9cPH|BRI%sV9b8*aIr}#MvI*4r5 zt0z9tzjezODd?cGCifpY(fZ0|3OdNF;kxV0>p!d4D(IlIR-3Lcum7ywq@aV)db~Gy zNLPOS4!I7NdkOcX+Vqco-ChM8gmy<8f97?&gd=htw8qeQ7xO~E`crZoq~=`e3Fd`> zbr<9~D9wW-HJO({)?Sz6AT(ut`!X+qthp!0L1)gTU;jj}wbkiz9Aw7OVqGN~U-eRs zgUa~txyZakzVf{khXcJD`Rt9OE3@LW0uCxu+G}fLT3_``K?mEp3ZcK5LmSrQ3lQET z`u7hH`d%|2ojJ5&T@eKxB-Y5TFEiLFp_GCS8r!mCPiC-FVg&^qMApi+(joe{Zc}vy z9aPrPv7iC1Z>g)GgUp&VD$E?tv&~dN2c4~2)0jD&C#i*k4npg7zHv#q@;lqfb+Ft` zZ;ziy|JZkQQouoIw^tp+9EP>aMy`X_o0Hb1%La zb3{whU^xy#Q@(dNb41JbVR9UF=KQHYR`goiHd2m*%;YaK?>3EZ9V^E{WnP8%X+q;$ zLZmnx=+%EwbOX9Fnxi>r4e5Z0CkfJ~55fx6fD5LEqhGKeVFt9ZM8+ zkXZj+qc+j{u9XTpXspd4|1z|moS>kC$aY>|w*alDY*o-fWkWW%J4);Ob}Q&0vo698l0fXFVR&X9l?)IhJaS)pMGyb%o@q-`b zIOvQ+vG5EUKk!YCgUqbBU#t*~@Bb^uL1o^!dS%l1KEpuaO(HnZYkZ}?;dEv87E{1M zWqOwEd4|^a8!PBwJJ+pHrK_}lu(E;<`W}(DpdYOtuBD)Z#5%Oz%M5lp+CV`EjrD83 zl^N`G+)P0Sk@aZ!yD$AOf6_uh2bFcHk^Y9(PgyGHAhRJZ@0mevXSyorptGGFK2@Wy z{ajB49fbCKy{UQW(4Kdc>tMN$-4L^qzVx&K3OER@MfRsG`qD3W$aT<~Rgaoipz-tG zavY?_zDTE!G@dp_j)T&49=EO(jh~w!$3bZ3uD||`#?OY!anKq227OIw{LC~t4l=Xq zPt8*_etNbX2bHPS)XxA;>uzU#ak2X$?5r&1{z-*HWjgSx&n@cl;P+waP8P}gT=5+Bla-TFj~gJu5v znqe}1;fXKgHmGZSf!AjAg(tid;~+5&M#kNx?bW$r8x+PVz6>=P8=ESDT&1ii7dN~d%v#-(k2Q)r!ixh_gy)L9SWaf0v-KBto z%H*V3FmpQR?^n>lcJA9X4`xp1!ea_L==+HWVa%M)MQ0Rrkl42wmzcS{i!UkYps}~I zt}=6Z<8CVGAhJ(BO=lkckAI+`gUY`6zMOgVe|e^Y4l;Xc@?z$dkCm?#bkNz~vu84| ze5}q^&_QSu`Ymophj#5(xek{5rLfmi>FwN_KMFVqt?!iQ*Xc`NS74m%7Ev2G&?|L^ zNlhAGYb3`(YKjFpoulzJW#l+0O*O+k^=W){B{>d4bM@M(6Ewc6rW^;IDK@aXF^#XR zFULV>^E!abc zHfgF{2g`ly%cx0oXtzfz;2^Z7uhQM!HagZ9@(tW$r`1aLu z9F)d&!wC^C3A7Dw8v8 z&{7)TbW)1LfnM{ktvpXxW@DNH4l1+vK_oM$bMsXN9cnB$TU6jIPZXfrAw4x&SQsDxYx%YD}9!42uq z9xSJTgU~j;cyS?p>4&SzbTwWBn?x4Rq%m9bh>lv!#iy`?xD=vBk} zJu?YlPd^15RHmZmCuS1B-a!gF*v^#+*}#0X?e|j9LEjtt?`J;R4*DwSAh88)3tQ5k zE{6jYbkJB!Yhz~e$I&1K9YnT;ODAUX$MFaS9aOfMgF7?%6OggFzdpo7phewP(MSN_~`xek_l-8-i4^nyFPP5}p@&1}1zxn+>HS+0ZD z*p(l^Y--N!l;a>ZQO6rHo0_xxBV!n7f`$a(qiLH}*-IxA!N&Bs!gT_`#yTZ)ny^w!` z@E#E!=vD4oJTsT~Qc(pRRJQ4ZY0O;SE2R~5klAAEqnQT`u2odfL1$ZRj$He`CIkmI#}-c2Y)F_FSwgc6mSsQ^lJN<2YPO|ll?Pq54$Ne}3 z9aPrF`V}+z%bkJFc=0BO&f6})p=peK{>rXbPE1#Jx*THi4 zJiY7-y`9TAsDOjeZXCCpdEM^m3AqkhQ`~hd^Fl!8IXMneb9`Pt=7oTaD{>r^=0^5Y z<|UBy+j1O)rfR)K%u66o9?5agnd93_R;Ab4<7aXlWTtq?kX#ynlqJVOWrDsJXI>(I zm?OpEK(B6}rZ96lAADE9L1iMouV&_SJ~Egnyi4=%(!q9ad`22`Xv33&3OeX}&#arw zp$!?u6?BkTk88u2xx7!yD(IlGE)Rm3xxCM-DCi)v4yjF;xx6oHE9juIere{+T;A6W z6?BkUn_V54!+ElrDd?cH{)cKXhx5E^t)PR@`ptO%hpzkwE4dDqyLHcw>*(#=`)&$2 z2<-;@Rm@>n*}ddCXpK?0J9Ave2PZiWQgd=kQ|7pi_XFiPD9yE-SC}JO-g(M#5Sr@w zjxk5Hy!Daepfe|DwZBHMwJd)*4l-jjxMyn`e=|{zgUY0v%{@-zuO~@yIMAzY;iJqX zfLBopIH*j%eCwG>0B`0f=wLfnxbkOa62RL<3OeY!S*cgdB!KtJ6m*c-s*PO3=}(vJ zwF)|DtVzu-%;b-pO$s`QY?C&nnaLlyI}~(K+4ANkn8_bs_A2Ngvn}oNn9x7>Z$}h# z)Y*L1;U~S52cY{r5e&4q6kt z=V4nK|CKJsL23qgZM#9^KVQmmP#T-6J!3AD7G!^+@xr6zI7p34_sHrr zUTB;g2c@xVGvqIg7Yvo-AT&|$OO~T?!zpqcbjD@qqEs3$FiVbu%q&TM+K|TcFOcJ) zGMjq0nNCln$QLKY(LgV=dSjN*BWM1sl-r;&f3mAb(D<(eIS%%6@8sV@tm`A9Mmlcv}b! z^cvQz&=lIfQcP@vytK(VKa94|8;fmFmoCquX3_TP%3>SDWygrIUBV0v4F2!`E(V1S z{{MdolaJRD+GyvNS^tX9q<`%H{onOJ^u7jS8l+{lWn>g>?=lnHVBhANw}vlmZ?zEH zpywvWW2V#g21~IGk{TOcYBX)H?kcuHQeXQGo8mB1WperA&sxxn^H94%HgU#CWdN$0EGP6_#9rXO6sS`7#toeBb9c1-m`RB~A zsutH2bWqlFRlhOAs#@Ju&_P^J7D!@-l(l}Mpo6~tERoC%DQo*eK?jMwH}MGbHhTMa z3OcB4diWaVZFI|A1s#NTalxg`lPT6etI2T?nvAJw%=gqC z>d0}>nf8TkYtz4Q?HkK+keQsvZO_wqJ99Y>Dl^T^iFwMlZCfc0=dR`+zQ??+)~2HZ z4k~kL?oO4IZpuxp>@qY)qwth>%Ca6gVtoAlBI1s!bX z*0%h^3@NjHprC`kFSUBg3@PiGsi1?zrW9~shE?@`t)PR(&MDD{8CGSVt)PR*PA^~4 zj{anI_^P0T${wqlpBYl-^hZGlnO!-o2s6pWxj?A!CegpxfX*h2DbGxDaWPWRL1?eq z?CL{@c0d`q4wifD(g`!@Upm)H3OERDwN)n)=}RA2Q?7&7>`ON2N8y@|K;7MD(IlHD`TG| z(7H#of(|l!?CrHITK8J0po7j%e{qqS1^t!lswtMYuSpo8sP;{wjiN88X(3OeX}*%EflN89ip3OYz^>y|&5VO8FF z!i0Be{{7N{#^$kl8AgA$`4&>pL1c^8+r#a6%8zR#*THhHxan~s{VPAVxdIMCd#&d|=9aEqvS^gDBz$n`C}h2 zqvXc~Dd=E3SA5P~=8LC*2n8MV-D3Iz=8LDX(-m}(*h+_ME}}nO#?MvIL1Sz0ZC{_( zC&nu1AhHdTd@X4`c)5ZODqAvPVic{1u2axKW}80@W*#sI->jg6&KA8rlzG4)VyA)* zLRoBh8zc-*|V#K5B<*`{z{I6%!CZ@ z5=rA>ALKZwjLp`3%wwvdU!*vkyE?GI7G_vg$ZrK4RK~N!K4w@|SpIO~J)(b?4z_dN zmW^NZHIL3OdNFQ}?pW>p#&g6?D+qQN0Q=um8+xub_j_4!HF+jjsH> z&T<_rcejH+CFt$kTw4Vkgf=$sBIb3w`F-U&XibNv4$KPy^IYUONX@7J$J%}W_4t2r z91qFNOm>tViKJxjk&$F&rEFQrNQsOTDI*e+N_J##Qf5}N3CUhrSsD3$zQ3Pyd;W0F zUvR%&)$8$ob-l0ab$(hfF9d|T$#GDcCyP>;mq3<|mg68a4W0KfFM)(il;fZ?IT?*# z(razWG&v43)2ev8k~F^9PmY7ibYEu8yhI*6Uy8%ItFxARF{9*z7AxSOGHn-4U`EL= zUap{n?VMwDbLP;7kTnWA=)3o-I?SOBq0tIDNbIoP5zHw0Wt$ar(AY8YA5tWUd?so%#H)swKVF))>qY-l(y61DR=4 zcj6fuk0>O^L1k`sPG~{nt4m06ICr(+jGoM}s#WC_a8Q|+vwJhcsv@c==wLf%H`0h1 zQWjZ5K?i*=IjJ%;q->p~f({aE(RT+ktSYLpf({y6dDvlQSXFd01sz1TbmuH)NLfr9 z1sznjZjV3Akg~YW3OdMaQQI$%=v_s8PX!%xwn^)cqiKChUj-e6_H?rz8FXm34VLR* zxfe(cdqH3NRu2Ungto-TmNxXIZyzVuL2I_A{7t6uZByhpNX@u%p>=6|>r6QgO5^J} z@gj|HnIp$RXbzmHYEI*u1LZjA%s9K~uQVRNRE~qpY|Z*mmBu%P%W+VdbdP`^G# zSc6Ai*J*wGNd+A=*5U31Pg>u3RzU}mZIag9pVoI>R?tCZi=L}Chg0CD*}nH*ec-FMa6;J}BTIw8bx%%A+s+ z&^NgbTC@3Ox-pF({3FLfYCIdqKBw^m1?CEG6FInn()c*FGoXSW@hr2i8IA9)Ajd&wHlIsLr|~`2& zy>^Oi5SK99WBKWQx>#c$gB6}cvG4slY-)99KWH$8GD(00B|DOsv2<-;PK~L$>&iyCX!E!%Y z>f3MnPTU-$0NEX(|0<6Ldbw<{EJj~?fU#T$t@*X*-A@{yYa+)%YHY`>FHPffD$8+D znmQHzKGV3rg&YT=d2_8;1sb1SPmY7m*mexQO5=WwP%$&|S zgA{a-*i(i@nYp|H?g~0+Y*2~v%v|32V-<7|*-+DV%%lGcCoAZnvInXRVIKWoG($lL znT;6Phk4~A*k3^holTtN#JuvcWTAo%Lc4L&jD~b*mxjo7u-rGUZJ0=J=R#I0;2^Zl zM~yDfmma!Su7lS6Ty?>g#+Sy(agZ9j4u>Dnc*s^c4oXw2)qqwszGSx?2cdcQw$3dY zUwlxGgU;9ukIzTr!6)Q6$jr~fw_ekD&>1-nDs$O4yd8}%x+KNnK(Bu%=k22_6PT`m zgUXyg9K}om2)d`BgYDdv#7oR1fW?^#I_Uei&3Bne03k0GbdcD48%HyfKSHw=bkNwW z)qc$6k7ZvKbP(Bhp;pYXxhsAv=%BJUf*LW$=7#5=C%jGb-*N|;{q(Ojb6oQ3A__X_ zZ0fff>2z(@lv2<^Xzv+%$I_u)TVAe%<(`|reINSLBh3_W5L(ll1-jCgzOI&B2dzoU zOF2&CYa7UMkQ%Rg`})v$WD_|KO5-u0&psMo(_D^&&?E#{45smjc5)na#;a&-7>%#) zD#t-)k{+dxq48BtavW49by!j;jfeM_;&7nXBilhQ>B_7es(^#aJa65FnbWyyq=F8% zb02D#X6AH8cq-_i?{^y%XXbQ9PF2uBVt<*QWajd&o28(G#-6DX^N{|liwaQCL1a@6 zzca_?Mh7YApt7Gzyz`>3Jtj;+2bsMw;{|hEa@=YK9d!2H?4QhW$?;JNItcB9>TVP1 z&~Diz*THhn2w7`H|Jpb2P{2WGO@3G}q%VEzUbzlhbMnE5nKZuTh#Uv0@ivZ*rt!^5 zavYRqxc8hnG#-Cmj)TzbjxVu>#y4G+H4l;8x_wP;`kIj(dpfZNr zUNcKA=BX5i1HGn()?+3CY<#1DgUWOdvSlU##C}rH!FI0QMi1trZPO109rWF2^<3to zZF8Q24ieih@md-B(`9SH`NDfdc%avW%{Q6JAKQy7=peGAPX;oRKX#T?&_QM04o5PR zKXz48&_QPX(;}FEVG_+1bkNz3=R%l&VfNNl&_QU+-zhwjuKa#$xek{5G@G~H^n%-G zr+|ad-p}X5+%h=OO0I*}OlfeG+0^XsD96Ee?$qy8W>d4TyBr6l*%eri*~sqgBga8# zM)YxIHnMwMK?jZP)u1plm-kSlf(|0v(RLU!m-om<1szn@zjX&@F7L4|3OdNFTj!q40|qB{ zDd?cHqkHsb9xym{KtTtgE%&A7HoEeskIQwi-1{GIT!&t8Nhu0A2yI5KzRUwX$*FQ3 zv}S7I)y!9pr?1O#keU;jFPN_!lkUoKP@2Tpg3Q;7Nd+DBy=Blv=CSZ3Qw1F)w)Dwa%;b;cstP)2Y~8~n znaLk#YAWa;vKEOp%;b-A^%Znb*~*)(naLj)Y!q~mS%*jF%(G_I+C{E|<=&|J&$Cez||pg z9Hi#=!6(cM0ar%IaZsAqmkpSgKrWA$;~+G(t4v{D0=eWR$3bU)N8}Wy*IKHN90!?c z+HOG>jbEHA$3bN}q+~NMkzZIO#o<6N6Vp!2oX+#13OJ~YRh5CvoX(4@6m+nit7BM# zIke%@dIcTy-K<1e=Fo;KaSA#}Y!ll!W-jlw?Fu?*Y|++9%v|2~Vxy(!3CEolh{wbv$@2$3bdxS6pF^>$v|>j)T&? z{n&sxqUGLqISxWov)K^lh?cv5)iH2iv(}@frJR{l!299fbDc^suIMXkWR>b+Ftgxg2XmU;4|@ z3OER@QC!|b`qE!dl47cKU*%xL1q#Y8syOU(=~D&ROY^Q`-(K46)nZ#KrhEpam<{~ zCz};;P#N#ZNz9zirwIx=*v`$G`G%R(`Fy{E4*K5K|LaPo@5dB$kl2Y`Iu)e#*U1Vx zXl&n}1DUzJZ!aq7AhN^ym0;%bzE4xoL1o9dl`TvEtMO}c;G&gzVw_g3OER@;i4O*=u7{WE7w75cI_&5D2?Y7lH;H>Q}Qo(OXFWk$Z-&wQ@3*p(D>(aavXGKgxi!m zH2$fI90!@%6>QLk#y{4Ow0^p7zfKd)NoE+`ogczk=vlI84csi=?lLWD8@lzJi9zhrR~(EVjC33)H%EsZJ!Mn z+aNI4CpNi6+ez!hHt5SPzuC2E`&g{l26_2>J1svpMnsFiKfQE##3Od-m%_-;19L%x%vVsn}-lbX( z=3tIJHxzUb*YUOfG6%BkyRV>wyt-IFVGd+D@I*lefpxV%#2mzP=#_#F5<9%rPUaw< zBOerW5ZU&fHjkli2p#*Tpo7f%IUQln7CiAsK?k8dyM7{bQ|45GMY20W|AiJT_wGmT zyU{=RlSLJ95ZaPA9)VBYC&xi(_O&S0lHSx@ zJSxXQXD06re?#LJPRntSnb^_K3~2oP1vw5XvvOzrb{ao-O^U;TUPa37Vh(6Hds_hq zm1$IM4|71n`G*QR*v>UC^pZK4o@IWu40cDuEytj-MbkNy0 zLrXGqdGDAg=peN7Zg=cPhxT4&xek_l$sLov)7!bb7792Bty6y682Zxh*OTj@H7~8d zxzPB%MsggartZ(cV>Eu(UXFv(v{*E15RKnyEyqDt#Rp0z7XpfCO9LAefE^Ss#ojWqt^gd7K{v3$6F28};I zBga8$9OAk~(D<`UavX%_$8?9eH2ySQj)Trv{yVmV#rcKa=wLf{*uEF@(f0JWf)4r~*2;zX zXnUSNSa_G_zh65@?509bnX|@T7E#baW7iq~W6m0TT}nX*kzHPHdu95s?rnJm9aMIE zwF5D<{@zSM2bm2SbBy^H=0hz79dvfz#I4M~FrOMI=peMc3bk2ESN=;Axek{5{B`H= z(!ci4%@uGE+JNg$%q@eQc5)rGrrzH$W>fQ}s~iWZd1aZ$Y-&C`$#GDcuYJv!jqIoX zavX%F`GQHzM)u=SISxAWsz~-GdaZpJDaS!(>OJ1zNaNX_avW5~ZDO}w5{n(_SgUW_PO#VvixjPheklF1Y+?fXq ze(zP#L1&jgpUpgA@b`#<4no_bM%lJ><^Ltgb+FuH%2r)K|Jw7;E8rls^S_Q@9_TT+ zCf7l0>feuJzH&e9ip#sT>EPX|}aJ^ELCIH*y?w z=7m-AWO}Xr{v^jiX6paiyNJer{gC6JG8OET zy>eS6)}r-a#T9h0oy)0}%RCnTr>uew`hLm!IrCU}UL^$`B=%Lge$1Rs0}BNmH1=_| zuFRay{Ph%c5ZPOW%=XcLb%u=;bWquB;{ru!-N;@+2boQqZp^&?Q@FK)4m$gNZYk#V zpQ4=AM7=U{#O}n!T0mnU_F{PL|^!G;^mp@niBRHjnd2h2<4Mj=uh4)l6@YTPBdG6h#E;Gi-Y2c~(^dZD!nI@r#o zCs;6tHWZ0b&_Ul{Z)w9E+E8q(f({aUE-I`${gXG|t)PR({)q_xMC&CFD(E1x-^0$m zr1jD#6m(G8w1xME(t6o53OdMa_Mbb<;XLIoDd?cHx4vIy4(BPKuAqa^7Ma+*0A2Zt z_vAWQ?$7h>u%v(O6*3iY5ZVjJ9GSzgD!r8Jpf!`$gfPc-RLqv+AT=>2B*RQM{# zL2354uFM?KQvSCb2chwQbjNotce=peK!;*T=($7_$2>tMM@{*G8hUwSQ1 z1ssId%{!Hu`(9_NTnDZBKCJKs`qQ=cEIAHR(`>O%LmICYAjd&z>i>wmM&mVu-BFb=%BJIezZAE>sA>GI>_w)WsQH*y7f~99dvd{ zV1o{{-uR7z4ni9qu$q}a-sF>92h07~)Sjp5OSk!Hu9q@vg`)->j*FkH(`qnH) zf4Vj)7$Uq)1P6LG-_`dijoTELk9CW66SeMo` zZf!2dL1w^h0Y&0OU;sOyQC zqhT~&Ww;y%b)7mhbqtMH8Y9O+T@(L0?xXPvljJz4tGi|M!8C3cc zOv%&&*XZF=dC_7U^(C_hGZ!>>v)BfCX;>xf9DUti6T~*Ci%ZeudbIsZw{UitWKuvB(W=KrY!p}le^@i`sZzlG#FSnjngvX{_z z;{KFSz(Hv9=gTyvFFmiETnDY$*}yE1#{X84;~+Joeorb-<9}+%aZs8Wfnh&r{I{hX z2cbFAC(n$=e>IllpfjWH`Cq2-+-7ndWM*ecV+$Jp*+!0o$~;;+;v$Xz=q$zIK(G8J z-F|M`6sbWmCAh8>wl{|)CV=peJk{T-QCK8zMA z=%BNFr#R^$Iu$twF7vWct#J#mRNh zn(c*cY-qgbb~z4GGbXcr28|clBga8$rp3m!pz*?ouW$Z=#tUANvpa#`xh%0U9sYL5_pa{H=0#D2Jfc|X}qkn90!^C(5|LC zjh7iH$3bNxQyfERytJDXhXcJj8?|3USEkfx1sqgnZgDqePG^~k3Od-%O*bjR%;_|l zrl5nq_b@YI=5(6+Dd-@v?lm_vb9pPwSI|LY2R1yy%;l}LSV0Go?PK?WIX1V-as?e! z*0W^}b8N2J8U-C>wp+))%yG%pqZM?}*(trAFvlfZY*x@gXhTly@T5aqGeNF{<=*z_ zyqR=pYwTCRL1;U9KA2BmdaYw}9kk|s=gM9*UNc#agVb28@QkGK8W-g_C{5#!AwD#2 zktWAMX#O?(y@JNg@5ph`8H;^B9cjG!BRLK-^L|v}T{K?pxf}1SJ&S!!nQq&OVt z^(Lt?GYO#T7X=(t=K8?~%p`znxe7Yi&OO-W%Y3w%8-xk((){;>2Yr9Gbqw>-R-=%D z4ibB9!<`ZIr%SC83OZ=)k2RN>$scvfDd-@wf0u1wCV$kcqM(Dyo(&9OCV$kgp`e4z zzWf`;{0n1csi1?-X8s6g{)Mq_te}I?c6R*hL07(UGr10y`$vN>`RN7MsEq;+LL0mx zl(}VK(^;;A)|l_cWHvR8`pR)onm-jEG8yK6bS3Nv}1ladI4F#ys3Dp2izYk>j8;14=b!ZiLsLDaGMHugi9CnK_-7a};n; znJ+DWFmpN^1S;rYJNL6@Ec3-v!=(y3=zDU*6U-M+jlvalkl6Po#`g55i_JO(9W?f~ zSt({NuWhV?4kDXr)R~#fYqw272bFzUd@wVYw^^cs4l;XoT0iCigXV`6bkNzqbGkAQ z7_>a8po7qMoRq$su6*mWavd!9tBdRPrx#qS%L+IM?UJLh%mY1bZpd}eni{KyGhaEj zzAwi?YO*_&V!m>0^+b+?(&V-J#C*-%@|7G1p=tCsfccua#RoYKI+H!Tz&v`bHUB2Z zL1t)4u9l0s7xteTjnvvW(D%TW z#h61I9Cs?{AhFwwjxlq2d+bxtL1R}G-^$G8?R8W^2a#QG@|l^-+xxVF4k{aG_MVx` z+vkFU4l)}s`YCfbPv2__I_T`t3ICYGdHUa0&_QVPRsWeySAO6_xek{5;`P!0=aZO#}yeZEI+mLa(*H#&R5FW_0eL`ZVrhBF8~xmaJKSlg9g0mf~=r zSI%R1W)gt2g#r#LbLrM>W)gr)Jp~9a{N*@EO{25NPSg0vg>oE}rpB>B)oFZ0h#Uu@$)0GLO5+|Y0{?Bj9;t!RDHO9dTt_EohC5wt!fTR{h* zU4M1JKRUEizshy6-0!}gRgS)Nuipwd2yMSgbxi3?_s+jUc&Em}4YcNu{mU0LKDCG( z2dS}n5>cGSy-LY(P#W{-8SiO)N_jaBLi4ekQ9&A?Y$nG+XKc;{UZ?R%wd6R+%pa3) z4m3WofgA^wX`0+VoSsNAp@|en1HBFzw`od`oEg(xZiB}7JaBqQ%ZV-TKRMP}h{jlhSB>=ukNh>YDx|%$mjrkCfw} zuGOmNou_eEPdN_inzF;cER7GCD#t-xi~Ae@qVaySAJcEh;gvYO%vSr z(ih$98tl6>YbV65Aj!f!kX8(RQm% zVjJ}3=PBU3eC~Z>*Ojv~A%) zuP422m{Z>Bo>#y@UhWUFW=^=XysDss-P_IfvzQ|i8r)LQLD%1Q9myOI(J(_n2XVbH z^)_?LTcf86I>>9D&qY)EwuH?a1sw$T>+opilsDT?3OY#a)$t3M6YlJODCi)vAIpR? zN8vQfQ_w+X?^IaM90Sz6;7ZvIq5r22gx0=|cRo6_EsM)_u-spM{CtJ}lW$R00SBSY zeO=%+ed(<#$#u}0-se&((|AjBISx`2U1r}G8gEfoj)T&KPUusH#+zHqaS)mg$1Q%- zxPzS>2c3y-9NUn_o3)bTATzyRreC0O`;KxPRHpW*Br6)X>n_FNK(CbhZprC`yUR~dxISQxK5(OP}_Unr7 z%rQV+Rw(Eov`s6!U8O_YEmE$7<$iXwWhDJ;@48U|N1?r9U6a0a$1QRlw5Ctihr2Z1 zZI>Jesfn_SZcXD|56E#)nq^(*Jf`t3$K^N(O}mXH>}kAniW~=>i7FTRl*T)y%5jjH zJ}G~T(Rjz}avW5~z2vbt8t-sdio=0k@$Cbd390QLE8w6q8@fg^(_uTlP|(44ZcXoN z%n=El-z(^#@4E-xWR8dEnxmkD#4Z@_!AwYX{H36S#vU6#mzfURBVV}iF3o>`@*uK% zrq*L7r1mPTpo7XT_OWHA!}czzpo7frG-%Eoh117WK?j{(S+ovw3{c;y3OWewRIfqp z>CpDCDc8YrkNews6uq76S6=}Kp*^w1awmQ118n3vXid40cLQm>zk?hHsmU0!elLyp zYb(b=X)ap$In#LGE^-`%#^_tIBQ);POOAuiWXuhoNaKC_$#IaGa@&3`q;cmVavW4< zME!_KG~RoJ6o&)77F`~ePFKchyaEm?la$Dd=E3ckq5W=7JUnr}3QzVwl&K(89({g{t7k75csNNkDTmzY!D zMwU^~L1XO)-DOU=8(mRB2a#>nejanm+t}&~I;w2fDCUH_@pTk*klEUeRxOlYW} zgU(iKzKr=7W>QlH9fbDeCi5V=@>5#Mb+DbYzWSjfy`7ufK>-J$^`7R;+%oWTl9CXHHSI#zi ztxcFH$3bQu_%3Kilxe7v6&hXcKe{r=9(U>G-F0SA?_`TUNVKjFDp zK?mEpW^Yb1Up!4*uAqay=X(~zeDO4Sje-sm+u(j_W(I>-w1N&ATkd9YX8wftW(6HY zw%X-E%nXL<2?{!>Z0+PO%>0R&`xSJMS;M2%RFG?lsTAP(C$3bT94NDBAaUX-# z!uvE$-9TmDg}-JVQ=M5zio=0k6Nj&3CZx_Np@4(R^c^2`h;E!uIRzbT=Y~y9XC4dp zt)ifVzK`*_!aNo}yM}@e66@IBpP7(4$5KHDjrHz2oS6DW0ZYcoagZA4)2Yl00gI=|aZsA}r|K~; zfdtQ#;~+Fk$GI{ufdtKw{$ISw+j(RN3E8V_75$3bP@96rmuM7}Uw zio=0kPH)<|(v?}TP5}p%nelAMQ(6yr!D4nk{d)|WX9 zEAoR}2d&xAWHobK$C__)9HhqO`3vT_j)*^U9F(T*x`NCREvpMe2yYYFyMfSz^_3Oa~vof_$vX+5g9f(|NcR`1FbT8|!}po7e|bWUkQ>oLO=bkNy?gEJS> zdfX@l9fa1yVCx+^wDA+YV>ZZfl$rYl zOVRkocsUL#<2}gp7mY{nl;UupSLtFx}czg#M&KcXG80ouPNxDu_gBnSxoC&Z!72^vITb(-AL=(A1dge zvMpoE*QE8G&lGf!S+jc;J!yT{TLm3-w$2U1>$INuSwRP(9bPk}5*^yTKjk`D?&WKZ za-lDM&p!nmgm!n%?;QHl_Zh7b-X?+ry$U^UZb0LEjpaB^fJeawo z2#qIJmg68aCNU45(D-f(ISx9LYU$dP#&^||;~+DI{?>a);|Y!AIH*j%H&q(a6DfAu zOK~*N%YL)#b9&^=mez6`G$wayJ!2Y=?mkQM+iPYVHKg$v7dZ}g za-rXSe$aUIAUO`|+QGcA8I4D|%W+WG-fpk+XnfsRIS%R?9UNJn#v>=oaZuL|`75W; zc*G1j4(b|u+p|86ukx4Upsp8gpGcOrv$>XO|d#+C3OLBifzy?l zNdV*06?CwBJ9V!oGYP=+o`Md#9(1EOGYMc~rh*RQy5n^gGx=lkO9dU|HT>xxX7Yzu zwt@}fVoZX#Gmbb+Ft+rk|@w--+`ruYiNle%_pHL|^)BGr100GcefT8;$$b zlH(vX5pGke(70~{ISxt_XukXpjn8T#$3bYie}7Vr#(kR0anPBF*&|NV_{?^49AswT z&a(Ard`4F}4l2{IuKyVtpY9~Z;Xtp%4v&~Qozwa&;Gi-Q-A*%eI%f=3(7|>t$~l6W z)9Eu(K?i-`JUE1z)9LG}po7E)yEkX%^3I;Bpo7Nl^{m6p<()H2K?jjN?(M}q`X3OW zpo7ZJpEZGb^nZSkf(|kplh1>BU8;vI4wv}RC30|y!p-YdsJYF7CTxlZFjN8~stO;EuT zjc9yPk{k!2>2~AFeHsruFULV=Rt;yeW%H1_VN?#$$mkb-N4_lWR7uSc(|GRNkI7FW0RnONuMB}Sl$#IaHo26adXna*iIS#gSrzamxqVe$VavX%F#F5ng zG`_Nr90#4bY2&zn##gw?agdp+FPe|1@#VwiIH-*0=)M6ozHE#XhXcLdIgdA_D-$+J z0SA@2F?c33r*rvq1s!bX?sYI{=5(%{t)PRxXLW1I%;{XUKtTtIz2Y6p%;k+(qM(Du zew($NnadlwLO}^^i3&p9kiy}(}KP< z9+xV|L2A;QP7kN?*z0l}lqRM7YHu2kxhuy(Xo^R@SV!XuCIPJfrGSIV_&+sdCIM{7w@!GM=D$k^ z+qs#)`Y<1D8w)GwpzpmtIWZq?u_YCBkk}EI@;=d@E}KjhbkNvAr=KyCKQ>oY&_QH- z-#f@m{@7YmK?ju`cVinf`D1&11s!Cz`;INlzc4#(6m-zpsWHcye_?hxDCi)x2R}R; zM^`?vty~Aoz5Rd(E9eEcyNd!2LhI)c&fGHC(@U;{*4!}Z!)$62`^j;Tnkr{3m`%;@ zA#xm)rsT;KW+S_6gd7Kk}WBga8y z;tyCeH^R5imEv%q*J$??W=`j}MG82mjGJdBGpBP$sDci*bN##*GhaL-!QRYV z-b05KbdcF`HT;Rnf%%&G*he`I zLUX29H1jp{(eH8`bjIv#)g|;=JMveKgUnnnJ8=Y!A2wVsyh{WJdOdq=$vmcdsF)Oo z1HBA>?Pewc94w=NgUUF3+Rsb^I9yRd2iv(OuU{~ag&(c1po6{_efpDmEc|#K1sx=| z&b@BTB^@Ll=b)p;xsc{W0#=H=4ahe8vCBc&n}napfXv%jF^|m&#aN+aG;lk_jG1XXG*jJ4k}Z5 z)>vjv=h@8)I@r#Yc5lrb+HgKWK?i-W>sf<2wBh1@1sx=|pz}&*F7Ksd3OZ+To14qCH%&H(1Pjyt(> z9HeIO_BzaQ9k&glgm-G}-9Tx&-o3ya(Q>Ph90#FUWN?@{qUB}@ISx8Ac!_N)z1D7& zlj9&WtA}>1PUGoS} z(HG3*kBq(wI;gDo{-4a`k4J+QbdXu+%irJ9zxPZJ1s!yDZ1Ov2TF)A%po7qk?>VX& z9olD8(6f}=%BG4b;mMud0*aF&_QI!Hfqhx<$e7`K?jv}ZeHUv{gZ$D zNeyKj>7BKp!l7T6%X zOXT2Y146syltWee(mxlK>!39y!+(CD@lU1YI7m%$$KXOV{;`4_2c@~ueC#V4|4>bi zgV0pTu26!;vun$7(3#{h>oaKly_FmXnJKyFoehn@vz6nZG9ke=*3%Oy-nNk9XrR}i zFOxdaBWGT;m)oE*t7@4g(D<`%avbdCf(GaHpz*BUavZe1+tRSjG@dy?j)S^BiFN8v z4(i&faHboL-=84IL0xk)6A#h&U2i!K>e{ehgAp`-+gFZ* zx;~jdWC@MmoF~UYU3(r_FpaKjdaxJ=%lwy1qh$KRuPl?>pstPLu0+xoeknqXgTw?} z-ZzD|&utLfpfG(1g1sSP;c5kzEf<2zI6UkW+QDM+9$R_UMksM_o3~* zN5wX%%NUD|t7tpnwAco5nf_=rvt8eML1^2-fnI(dmdpVSTdpbKATRC5+A{|4 zEvyT3`}JreISxwm@Y7c2OSU8SavX%FOr5)b>HATKTg!3KnY3Mf>(cn4PI4S%CZBK3 zWEwx%Lym*W%*=IUzDz&hBE{iAFV}aUnFAX34^qHEWrkW6Z%E zhsP@Dpzkg@TbYA7j!st4L1O2mnlcBn9G{_}gT{6_Q;a!~<)puY4kFt#V`weExj#s5KnT5f(|m}BR)j`P12 zbdcBzeSDb%SuW<^D7;Ja-ya=ltogt(%z-SIiYVwHvh~|GW)9-HQc6Jwl`Z4gfH{cg zT6qN>WVVrw1v8iTx|xCwI$NY!8)h!=jamvi2yKn*#Ex`mZ#9tXV7WV_4Kty)b2pnP z;2^Zw%`x>p`e4# z*5CX546SGGRnS3b%~KZy)1l2eBG2 z9_Tf%&m88X?QwAh9rXRkz!A(x+mo^iI!Nqlj~mQcV^1q7=%BF)W7C+k#-5ui=peFN zrmW4S|LR`WRnS3YH~KDYPwTI(6?Bl90xgYrVy(#@`&+e{(gV0*Mj%RKeeC#9FL2E+Jjbb)6A6(@)NKL0Q<(N%P z_Ha24O4EPBH)bRIevBLkp@}>m$ZTZaO_JlFGo2b6?WWh-+v#!~WG3Y0j4m|(X0{v$ zmH9iW0&^q$^#Uml2YM|}{Vz@Vg?+B!G`w6m-zouq+d162RwO3Ob1F!rb<|=)bz00}48*?8zKA zQ(FIaTtNq!-5BD`JYeu6ML`Fh-7>ES^MFBas)7ze`=RpBo^<7ZUzh7(xkt>fa;Jao zzwRpFAhgx51Tzox{COIO2iIAu@>jejpJ$3bO|m8{AvukBx#38vEMUhndrv=b)g2$UgOG*qi>VGiaxvgUV)%ZSs!R^LJIyL1uGH zwPIfXF?3SUL1#}_s?NOrW7JvlyvWi1{uFM${Z$Z-&wN8b{dmp}>z z$#KvbgSpn(^jb3vlj9&W*S5JC(s+T@avW6VNd3mlOXT^Zq&OVtbt}WQE?t>?n-p+R zne6nA;j~_0hk_2abFWg%Fo!l2+^e92zCS)wk~y@Y&=Cb4BsM4a)OPwOUnEIE2aUay zv#AWN7dx+@gUFtK_sx*jjjt-`pt8AHuajuK4zfURVxDJzoal+d~aG+Odqfg8cEoF<#aS)o!^Z@3FmNI4KIOt6N!3E6ewN|>4 z90!@Xvef$`jh8Z)gqV-aC3Od-% zt#8t>1+AB9rJ#ep$2l|!pmmdu3OY#avI6tV)4FMQ1syc@P?3!Zv|gc)f)2KGCrYOt zqxDLz3OcB4VC7r+XuZmC1s!B|>xc)vXx(g#f(|+xJ?_FcTCYAyK?k9264i&9KW;Hy zu7l;iJ9^6u`qIs3E8rlsf4f^SbKh$$kn5l|eMdjLM1Q(kERo|NHS6|<*PwCp6>=Pu zW^tPL85*x1DaS!*x>P7&N#oTv%5l({bt?n@(YVz68n3!bj)TfroR4Ov z5mz}N#o<7&CEHG=(3PotTmc7_*&nxQ7OhuJQP9D5?&z^^lWDzLs)7#s9RnS3WR|RzZN$a&9E9fAy(UE07(0ZL03OcCl)|Dmu(R#i23OdMa z;M;taXuW=pf(|-+;z^ZQTDSV8po7phJ~D@yKW?3Glki5(e>1fjj`yBCsbAlM2Kn}1 z?mn`2_k8(H3YZuaHZU-lIU%b5((?Wm^rbf}tbl{i{+nEanfuEAxhi2ii7 zHkIQbHIb{6KGJx@s&X8ZCgh!4NgB7RDaS!*I<>TZN#hOb%W=?|$U_NDXuQ6S90!@{ z@BZ)sjaxd%aZs7Q4azc;IO?^P;%J~(f^lbmdgM&aE^-?*#^ZtADjK)wCC9;D&MW@T zG#anoPmY7OCwXt#K;vdZ98@AXuQe@IS%T2Z*ln`8m}~7j)S^h{_$fBjaTrJ z{kdFSbf|`wn1Okx>zuCLBAam+aNFJmOq(IU-zezVjI-u$fCsMwEga^*amU&UmjnC-Z#Fy zEVS+6KrhpuX3Qjj7dI4ekQeJO1(-^c{G;36Zf;4 z0uDkO<6vt*U;3}wavij$h{?Ac8qc+o;~+H`&IDGX@t?MG9F*qP$x**({6`Bp4nk9D ze7UkT{=K~%2c5a_B;q`cf9od4L1v2BzqF?Duf63ssLb30!RKf^XMhxk1HEj$&M|X3 zzYJ5rL1m2n?lE&Zzm8JS!FI0Dh%jbO=l2N;I_P`rapBCI&Y#{2I!J6;7Yk-C?=N2k z9W>U`wGA_u_s={99YnTzyK&5;|9Qa*I;d>L?$ek@{|%Na=peH#n)ouWeB@uFpo7ll zcNoLG@?jXQpo7p(xHPsF9a^K!avdypn`=fb>Fr#>1O*&~Hm+)gEA*uo+Ar5ZYl=0x z--gDGj>&P5nscwV-=Xn>$#NW&=FZw~b~J8yQI3PqROsc9N#h05~W|gjT=0d;&7l>pSRo1>B{_jtAK;bcs@D6OajRFML`GK zIrpDWnMnWzausyY_kmyjF_Qoa8f+HcrTOpI4iY>4VlQU$N1;LrI%sT<6c=XlN0AZ= zI*4rN2L+j9bBmQz&_QMAUa!C$n`>M}K?j)~y3Le1F1ch41s!yDWLz=kxa8873OWdF z{g{b6=+KsJEZ4zu@7r&DG9B77%@lAD+7~mccAziaq>Wq$t?4o7;T{?<+gXl-)XWb} zaHa7wJ>@tk&5E2JM`^rtUpWp!<5sg}ZyGN(SdN3v%-@|9NaH0vjW=>~`ISM-1&UNr|VCHm|3RKWR z-+ldRGIKi1ELG4!Vh6Na&CKOB30KfTV<&YFX6Evmu2axKWJkI@W{%CR5UZer$_{ls z!yKDiX`6x$GCSA&Dsx&$VJ!a%sGbzI5};avij$*PKtYX}tOkISx`2usvWkjaR!b$3bbr?+%|%<7Q9f zI0}tHsVEw+`bv(2&IBw8??&TQKFD#9nO;Mm#n5==Z*m+|=11}G%u=iLM~cINUYQT_ zF_Qo)7T6-ZNAw>KD)aJs6=o7Z<)R8Y*v`Gb=*WDuRV}TcgTCKR8NhtBRjZ(&gT(&) z`Enlp>0(|@K?jXZ{_>ld{86K}f({~k`Ry)d@<%Nz1szoO%ac9K4y3342SX8HFn%tqGITaJUy z^qhURExp$2`O0ySnFTu!Y^U+M^W-?F%(uD^m>c1Bf~7bd==Im-0W+tw_A&(=ROYPf z1!hiX-3SF8Z0D}ETfuzsWVt~>2Yvt1eJS(BQ-gQ~9VGUFSF79fr%S_~3OZ=)Gr#K0 zT;4|e6m$^THzQ^+b9rr!D(IlH*T;D>b9rq~E9fAzUrLW+9x$-GprC`!UasuJJYdl5 znt~2O`?7!YO?2g(-Z2wP=gU&b&e7%%jYj#Fkg|~^| zK(BerB1h49Q)4*}DzmSBCi9r8t%($e1HIN?Jj6@_Xi`}L2bGCS*~v@-XlkLLgYDe5 z2Y;Ez!tLuR=%DW_u0LTO3wLOwpo7Goc? zcX5~NV7YIYIlUXb;5v_0z(HsyzjI<Tsn_=A)vFr z90#STJlTwS38d3PISxW|`^Y5bC6JCGavXG~uuXOWdaZR>DaS!(&cE33md4w!mE)i? zdq(FlFOj#4k>YTm*U@$pnK_+pw<_SEG6CJEFmpQF?^e*kc5aDFZRXI1jt3QV(D(hW zEto?aI-gL`L1LpvEMeyIc0Hq@gT`(hw}zR^>v%~)2a(<7mCVfL?UAmagUYV*d&tb? z?R8H<2bn!o;0ALzPwz|x9dveCku>ITo<1)XbP(E270N!LE8jO;u7l;Cl()Moy`6LU zs(^#gPD~rY9ER2Jw_FFUIr}t@Ij*B`{%yiLHTG^GHAS1=V2DI&)~X)1QNVUB3& zQ%a75(ATwacY&J;CGPNUaaZ!z@@8#4ifux z?V%L<)1{x2f({y+5x$d|{4t=vf({~^9`cu&{NXxOK?jw6J?{xK`D5@%1s!DeQtpTK z^zVJBr-BYTo0F4Moz~r^D(E1zEz*~_rbFvKORj_Ee#UU+Ci>Ec2PohmwBL-L+@&ww zBS@};)(oj{UX#Y%!{j(f&B{N{S806sYB>%{GjIN0D;jr;lH(vWPW_V4()h4VavXGK zWoG-*G(L2P90!>hQrPAvjStx?$3bN*Lxz;0@xe!=I2`Ep%4P{Or*lw}0uCzkxY-(J zPUn#G3Od-%-Kw6<%;_9zbg79EwC<6ipo7NdR+_@h#G+H13LqP|fP4}%kjn*gRDd-@y z4&P3Ep+h^V;CA6%A~?`1E414W`qC#BSHMANe^^|pOkeusvT_}?W>`t%*EBw?qVWlJd;qagdo|4a{t5 zd|WFz4l47wX9G)mBE{H_QXCERN*?6(kRCZRqPyG%jVT$LuPKeY_mSgZFIOce>o$$M zxyo^{mAg@MMN1kVI$Vx}y80FAokrt>$H;L|*MpC%*QRmTNpc+2bxX|Y^E5tSx*P{} z9XoT6HI4V1EyqD!5B_cPi^g3R$Z=3tKg$kfY20~<90zr+;I;G|U00_SVjL`U_utk7 z=?iy^l-r=LqsE-6M_+i?jba=m=5~pb$+X>Ji`WK**;e6;6>YcPCAL9eCe`edLfZ}p z#5U+lS(~a2Y1{U=*amrV`ka|c+tw*!8`Q<-)$&@jZJ8>zL0nP_@BTsW8*5z`+RflV zuiv?4nP-M--c`UsUQ%*OFwYFteypH_-P^@?1DR*V>b_9WLDxTLbz+_svwW|hgSbA- z_{uyZ*dRwi2YG#w{)Tx*u;DKS9R&7cY7+BoXrp{PWOro#zu-V(@0^Kao(;7rte}I) zem$PR405wAsi1?*UfsKw8RTYXs-T0=rqAeAo(^rZs&XAH_rIO5H>U5z+1FISL1?SR zw$7t3-J!l*2dz1@^q(<}H?xuBAT>UNmp!L(dj~lVO5<5;vLTJzwUy%_G@HLv%ck+B zUF10EjE_%LGa9$;CC5Q#4kf-%r|~BJy^n$p5}Vh@nt6lQVXlG>8hc@& z4f6(Xi$w}Li0sw2Bbhh1TZJmSgwQC9N2aL#rSXpEzyX%G~WKE90#589kS;ujkkLs$3bQe zgq*HQ<88C#IH*ie=b!^L-sZIwhXcKm-o-QLZMFWWfP=~`$~wxNx7GH$f)2KGOLIRm z=d88=tDu9vAI$l}oU_)^aHsGd5gzCjnc9IlU$1j91syat_RKKme7&w^6m$^Tof(Ch za}^ycD(IlHE7Qv{=PLH7uAqa=?%7^BhTc{5s-vKT&Mw|$#0+xl-B3XXpNxem5-IVpE~(Rd$6ISx|Os@#^XH16yy z$3bZtdUozY1!XnUqJ_*-D&yAiPnc6Q_w+ZBdT0FL3o=64)n6gD9+5P z99T#J2bC$7UYeOzIjDq!4z_doQoAr8Z9~c_=%DY-&J1Ec+J;q8&_QC$<-WT|f4U5> zp`e4tHpuxtg4R7O6?72U+V5hf)B4E93OcB4wXBoOOybea6m*c;R%`b&|H6!Iqo9M% z8iwy?{)HLeSwRP(9sIV+3cB(WddhXM+-*mu9i{*1Jo_r(AhfGnO<-;rOdKrNL2Fu; z+Qn>YCV0qkkeV+S9xXZXTChYc8XqW zW9P_mkeQZEP7R>(F@bU%RK{`7b>>F+=%rE|4)iM3=dLkbnNi^iIH*j$ftL=^`j~YJ zI@r$DXdA_R@iZ=0K?i-WmNHf({aEKcx{f*lA*-f({y6!q@@k1f({~U z=;3Eh|J8Y&RM0_XTa6vPj@G@;D(E1y)k=+J9x#}GSwRP#tzBt4^MJw38wxrIt?RW$ zL+Q%Tx-ZwkayQL3$)I5ZW~r+cFRI_`Z_spf#;+=P_S7&iWw7L25od`^+&nt z)A+Q~avW5~_`z-FF;(vhQXCHSnvr_^6J439)f8}08K*N_y3_i!+6p?@&UMQ8#5@*0 z!%9I1eV?74%{&(FW2>Np#5%tl!VGruZK0rp#*WQu#|(Cw-CjWlk@d(e|B(Kxo6}7} z2bCS1Q*;ci2lQ6ZL1t%#7&5Q_%pahjgU+^{SCM)BXW=jf9fZ~_zUd9R@{2~vb+Fv0 z%_wc z{F%(*JjgRF8b9A{%yAvzM!SW#iQqu5gS+lA$91eUmgAr_TW&UEj%Zn7BF8~!#u|2I zj%Zn4S&oCw91OeMm|knkEaW)IjGycAdo&(aPmY7itg-j4PUE4Cq&OVtRrlDCN_1tG z+AH9oGNt#li>39j)(Se<&Q;!4{xGdC@1&rEzFWi z&e^TpQk~W#1}W$uvMrZtDu9-*7^C28RQl48jSCfU5L(CRxAo{tj}4LQpf%6-*MC6c zF)QUbNR8FV!A)p<<61cmO4GX1@tZUr9V5pWYY?b4nGge)?ex&iJ-Etgc z=GpRQMl`n%~a4qV@)diGlQKry;RUaWX%fH_n?3B zo3j;kP}w>~?C#V0)~^aW$ZSEcX3QYB?Y|Xt(Ak!LwXEoC--xt#^JqMBsvHM(4UXwFK&U4b~x`wS5<6xOP{f-ZyFMM&7+y-?$ z-@9=u`oe=YiE)sa84gajX?y+-u?-4S%-X<#w*B{tZ4j8NWn=Epw$Bl<4f?XD;K$~) z?VTjHL0;aUw|Yd|lg^86P?r_gJsQ*YxT|6t#N|?_2^Hym8 z9b`79ejxM8$Mi}HItcCk7E5#K(9SfM>tMMrfB5`4eJ5^4T?HJ3w*31)rRYodv6kzg zHK&qWJ)`lNc5)n~W{PRgqBK6El^h4988LR(TN`Ho6fX1hFm*b!_Q<@ID zL*w3k8KGm^qy@W-I6*vEdghGjn-;7AWYTu{%ZOB8ev z*_a2tnMeO;uTaoIW!GNs$vpZ$CsIKNnLWO(1M|v9z(xffbasB+Fy@ty`CAlp5Za7t zF-_^vF5D&8!E)c%ugxBMJGbC~0uDl3?&9@_^rZ(Lm+PQ4Ctj4crtyU-avY>)s*U@3 z8efnq$3bb_d(5j%gUp;bpFfAj=f05R zpfbyfbs9wDbKXmFIMC~c*YaI-W&Cp#a8Q|dexb}HfVsaEbg-Sv8j-I|W3RZ5XC{9HnJVZYvgg~iWRA^UTvb5_ zmHpS7(pPqo>!3Bimzl)S_=;X~9Hge{z>(c(e0e`P4oXwI_QLHn zzHEpb2cdcW`Dg${D=P^PqHJCJ+h(@ zA<5n|BO|*)R%T|hM@Cj;mc5caOI9Kg8IedyAyTrVvig3$zjJj(fHbFavW4!3Bc$LuH3`0fNb4pP%>ez)Z` zzU!472c@ZH7&L~)cfOb7AT$|q@oQ;($7eYXI@8Q`*bo{I_$kLhW^z~6J5A&Mf8{u+ zOuOf8n5DMe=&bN25gh2{+TNa-1hB1`0uCxO*1>|A1mIsvK?mEpN&ROqA8k7-DCnT? zPD7?JA8os;Dd-@vbKH`P)1NMT>L}=-vF+V&Fq1#_HBit&WF4k$W+s0eXsV!t%1)o> z!%Y4-)Jj1InRU#+lKB(na7P6lbk@B{0P`ozksb;<2yOqvFBj33Kh{^SgXKQt-|tEE zf;&1`0SBSo<#Cd^WpLb8u7lRtI!|RbHOI!vagdr{tIe5B&C$tn9F!(KE05X89+@e} zL1^mK^kp`(LG$D|=*+Jp#*Xw_JG@kmgUr}2oPUwV1AXK;s7!~yrI;Jxhc-xYIM8cB z)Ej0_=fQ0XIH*jg8~>O&oq@X*bg-T4oe;!)@f37OK?i;Jj0tAGcshDqK?jK)nqf4A z{&YEhPC*BabxWzh%;i0KNkIpZbK!{ zL2K;1Ix=55hJKUdAT>EBn=oHFUdWZ>pfn$1Vwta*Lk!Ld@6by@C!B+iKc)X7b0ywhB6EY=L>R zn8_cPyC~=&vLK-SU*{pf%GT;99S z6?9Npvy`{YT;6*r3OdNF-S!X6;XDu06m-y86ThF#;XE;)6m$?;v-^o(=*mC-A=klj zZ#!n&MtVE<=#K&pLYq+W7;_j_Z2t4Y+eFP=L2G6-o4_2`@wliQ2dTN5Qjs~X)y6ZE0HRwe;Gi<|>&{{(0o?DPpo8t)?8Y^jNdOPKE9ju_eeByX zlK>t$D(E1wqYQm})1NM}gA{bo*kOhJn8_b;E($t`Y~PYMnaLl|#wh5Zvg0d0XC{9< zpQNCJ%=Q@dtQ`G&Pn@Bkqt1@Mdz{vj<|^nQv}=t9H=skCyhN^p<=%16v4-@ezg(q& zgV1(}wY*JVdWx@H2d(+=FWr{LlefxokQxgs|0EiJxl4|N(%231YE9!w2jw^jP0r#X zPiXwbF*y!8V^MTzKa3P|!hQ+pQT;k=9e*DCnTE zUQ4<&b9rB9DCi)vGyKh&xxA@g6?9P99-9n}>7V?&90eU@cKiq9jggTnEd2WLb}S^re3=Q@}xJ+hrRSqc8nqCAkh-lb#Tn zL*tn>MyrJV|pfB?MdUwL*+Qw z%efwOK2GCFBjq?~`^Fj8ooPIAyc`F0wRg!3q4DQaTY@mOy;4(j^zsP8fwf3!x9gSy%;$eTdp5B=mgsB5D-?MKsfz3(r^ z!7{ILd{cG$!lU-eZB*ArC05ZFe(SIp2Z{MJ*kc53Uq30fL1C8kZo8JYuLO&25SXsh z_qfsag)3qk^rgk<7+=~x8zHtqUdA3SHJ-Ll+!foPE|tzWd((E%Be4zQ5*-m=e||v& zga7@%lR*)K|Nq~?B?sb#Hrly$=~3*>!vEO+{lD}7p#ze|G)PO!;hjuqd-FT74fbt+ zN2I3E_WF-v8}xkf>|@5Xy(&v=gQVJ+$EDKt(%)hmB(+zOfWovr-!MdW7sj;_Na~uV zEz)Rvb`h}+lKQjetYWn7QBrJ!q#jMVkV)GU%86}|)Mr0){$E%A*Z;q58C_LugQRw< z8nKK{s*8ox2Fp8d-J6Z{kKC!gm22pWw-)ltE6`Z9s zXv**P-ZN{*J%wl;9?>ah>ioap=bCKDBK&=tQ|tv}Ja>2w7hY}U5tPGr8mDea}8 zgP!mEKAZXKs?1^q9b|Rwo!d|7pM1HM3OXoja74mXTCcEPK?iZYmbli7)+=pM&_Q2U zJlc4J)~oDP&_QAk9@)cuO>cfcK?jxHbzmv;h(h(F3OWew`!A)KwzZ5#t??~-fO#vp<}Eo6Qqw*umU%C?#(g;sO4IK^lcw}H zch#TBaS)oFGdnV;UQ|nz4^Kf;w0vAO0foyI5`@w_0FPnRU zd9b{Ov4Rc~d$L{S#q>|UR%rztG|fEp_J*Al za1h#B`Fk_(Xf|??>!3C38u&7A1>5wK;~+I1bMu(@avKhj3H0(0H@QXI}*{hYh) z4_z6nWePZ`%+v3yyV82S)e1V;&b|2XqA#smZ&c7h-`~Evord+nHMeEHkE9juJ z&(Ad7L+dSXDCi)xC&F4X69!t}k?UZ&r*|1pnZEQ^F$y>ct(&_8GvA=iGr100bGOrK zW}-&xmvS7W#%R+oW~N1}w{jemrrgJh%xJilnQ|P2=6Q<=%*3b`-{m;yjM3@z9`uf? z`7b#RGIMvF{{b4e&lf7ZPt({HROU)*Hgf`Vv%*pw&RxCl(KCpyjGc)B4l0v1w{K}$ zw=b)pgYDeEQH2W7dW$LwI_UfD@fE{py;Us*9V9lR-!Us%Z&Ob}2aSy#9O6go?HViS zAhOTfrFheNhvo`8sBB7)zinx~Q#%D6WcEhm?;f#d-J(4Gn? z$4nUL;Uw3=a*uxK+l{{T?!y&u5ZaNw#xe5^9NgqOXie0JKxU#wj|p-dq^977r_4-? z?$hKrC{39=c9-aVMYlO}9E2vZY8Pf=RM$mv9CW7O=ExQFm3LVo$3bSIItEXr@y_ey zIH=6DQhS-D)@id8hjUj)-D#UdSEl0*1sqgnSVWDnwBC8Yf)2KGeG_LgA8lQaDCnT? z;~%**A8p-FE9fAxoj=46r+@Me7Zh~R*!iy_(`da{n1T)>J3DvNS6c5Asi1?(_W8cP z2d($Lr=Ww(PF}N^`4gsptbz_YJ7CE!=1&->1O*+0cGRSHd+Ev#dL`GvavweWPiy+u zKJdK)4nlkUvJG>~VDM+T4q8)S>sMw|Gw7!r2dRl}zl7P;4E!s{L22UKj$}5nPDU4n zw~1`gpsup-O_`1CfMRkSbS8R~pD(@E`j?X9ATtGmUyr5neih_6sLTwzwakt1zSX2S zoV(htU8)aV8OJ&bIH-(QkKD$z-migz4z_bM`ki9FcpA`DK?i;BG59R=#nZr63OY#a zxKa5F(?9va9TjxYSeNlt&(ZqO9tt{$>;R8$hiH9xUj-d(=O)i}s!HoFgB5g;**=ED zm7gVuETlf@j@u`oc6gVe08=gl0~ zv0$GZ2c_BLG@3c0Wqyzx2chY^)QmZzW!@<{4mz{8@HPW_t<4RQ;~+B~lGD;@-0P|w z2bDQ_rZzK5WX??~4(G1U37Wc_u8e220uCzEe*bg}TK9Uapo8t4!=+kHXno#u1s(K# z`swDYXnjG7f({bvx_Xs4tuIPb&_QFzF5YsG)|Y%z&_QG;ZI3uh>&t#9=%BJrelLsA z`tm;tI>@YNMobr4Uzz{1@FvlJu>qa!opS##t@{*J&_QUgKD@<@Ori%xE|t zTR9FwbH`yDGn{QzOF0fYV|Lx_CH*^J*+Gtj%p{Z@-HgUpbeH3xGRL*p%yAhNwp%fF-b4NDYsP+8AP1)OQ!ZS7x zXidE7usZao>-Mv99Hge~t$Gh=eA`7i4oXuXG`azeZw;5@AT-faFW;u|Ew|-3=uFwS z_N8ci^8+~!G85mp+ix1*6eq_)Wjr6w3!w*x`Mr?hXnL1R9j|TlWWaTAf5x)H)hpQe2LMx@H#*9Zlnl%;Y$zYu&{y&(QdSN^%_3HFc1~U>cuSLym*G zp81|Qgs!WXl^6%h{NIW?rRfWwX(P8mUGKf!986#M^k!llBxe5F3}@P&+(vAJ!sH7$ zbcVLacNW`V`*u69fD3KA^%UEnFPBdDI7{0u{lzxO%ext?oM?N=`5s|oN$(r`j2GIC;6Sfi)6AGj0KKOw;2&VA6KI*O<2dU}4!L%ifk9;J@L1~75`kF}N zBjV*a2+ii^OB&O-YqA^%o#}qgFpb7t-pO&0nU$lbm!NUyk8&JT=4)EzR2m0mqeEW?|b)9G47K?i;Rl;Y3K=^R;7 zK?jMANU&t)^178%&_QE=#WZE+@{Xyhpo7SMiE?8e{U2wcpo7ZZxv`LW^xwU{f(|nK z;gSdQ%E!be3OeZQZ#aWJn(hRe2Yb>2e%oW_df88#F$_OOAuegsiJDk;dH@OK~{RYpL4-E4nh{S1RD3 zGMC-Mm`MN=)+^{>J9lQ_w0>Xn(}lIL7g&_QR<*UQHo zmpu2Df(}A^=zH!OI<)ie%XP5ayemVk355>(YRN(90#2-{#)-LjnDZf$3bRp z)E(A~#yty!3GWiYfnMj2G(Ak?vyG)V9O$(-W6lD)GP6o6;Gi=8DPx#9ot_mHbg-S< zl+%Qn)9F=RK?i+5`mF&or*odAf({b9GHMSqmv=!!1syat?8Z`NF7F~c1sz28e8Lmv z*xV(p6?9P9buo9CV{?~vQqVzWPX*m(j!RzdprC`!Zrz{29GASZpMnmybBCYBb)`e= zGeoX~%v6JEk|35|Pil;fZ>Uaq5< zrM7Il6o&)7O!^mNCIKwnqkx0T*bOPmOakx@RM5e8u2uVX%tzab6AC)$djSV$=A&)Z zc?BIL)^b{=5B=$~`m%x!8f!Z5D>M0H?F|JTM7EOKVP^8j`a23bsB8`QOU&et4KWHj z$gF|sdFD?Tzh??M=xp;!N0>ihHosKRL1-sbU)r0l{MNT}9W3`EnNjcQ1-B(r0SBQy z`12cc%V67gxei)WJh2J0soDBVj)T-h7K~3 zTUP}gG`7jNy3AZ&|K18Zh-~wW`OIA29Zm{5sH{QCNMy}fQuN?QUljEQ?j|ciPUo-F9EXP4;Dlf@nzGmLLLym*aTrW2N z1ijYw?3d#pGbS&LJJI;=BXS&6rj@A!^O)+c(^4D`^m1r_g_#7f^MV2nDl^?-A2SJH zcbI|>wsUj(XETq5?~PQ@LEqaC$zUD}-+xa*2Z^2JHjJ74aWGav2aR=d@4`&}2ux7W zL1bO0m1HJ=1iezwL1o9zE6z;*IQm{e2bt}ZKR@&O&+*R+I_T_zB2}5!e@^~X&_QS$ zPCZtfuKel0avd!9UjG)gr?+#bjKYO?iSR(LSD}f_>vm^~$#u}0Zd)ocF9e(}CC5Q( zR&+0tq?^AgC(YH}QeX4r>c%u66A>d0}>nH3|wYS3%#cmp{OGSe-j zNHmQfYbwVDyCgF7Jhz3OdN_*wyjO;XD`TDd?cHu8Sj?!+9<*RnS3btsPcgrz?NeN3MhA zKGpMJ8G1W+WrG3^Li=WCHggzO*fzNiTGQi<9dlgA)!lL&q{e$}7v{K*D~IGbD9yI= zfy@ytmygSF5Sk$mpE5_ZTskMmL1(->JAI2iv*Y)k-px04^md=%DZBb&E5T0IsAe z=peC;OJ2E4f4YQyP|!hRi&fmmO#TS}rl5n!<}=J@CV$+>RnS3Y?F(lxlRs`6To>M^ z`ER*{%vSVB-9-Q1ZxvF|L1$~u&9$WUs1gb~2yO6EBXc^mcgx6iu-r?p+kT9`^gERm za1h#gPBVYfmmXbHu7lP*o)cVv#_!gZ;~+JaPeo?Z_?<>_9F)f7k%cjhN7>795Sr@+ zo!-*;?Y43pbf)s!r#3WxtBV{5nRz@c@Hve~_LAeEG6&(JJ~U|7fj(4l-+>+x9lC$8J*4L1*)Q zuQ8w2;{p_P5ZViYma%kbpY4X=7g`qLl<9E8?u+Ta%SrN^I=>!39;!~O5j z__Gi>4pLKfO?ovNe|lApgVGfLQ6!wk<8I1v5SoY@URE^zBwCJx&QuNh^@qk|AIou& znV3bZ%h34a=W-lW=I_Z)`RR!ik5Z&K8tB!;qqiMBa^_x|+y;&Ld$>(9jo~Wb>gr=KKbOWY)t2L+t}XpiGwHg9 zT8nY8%r`wMd6vHLbGC9D)U}KEF$4O-&$JZdATd8b#=WQQ;~m5{D9oDQ0Y5YLW- z3Oa~v+Z`+a&^Ls39aGRjW(#f%V9plYb5=nIp}jaMjkzha@1k4>%iV75@0;`wes8z} z4npgBc^h*xZ2xV!4qEea>pYIqQR z?MIs_=%BN;%C|2~>&M$D=peM0yG1jPOr7j3*THf(`&?}Ued#B9D&Qcrv-VtO9#uQl zU#^4Jyf{0Tc}VZ%P&p1#Q)*06=HbW_Bjq?KO}r}$IEdLnuqrS%F>&fV^ifg z=uD|D6(VT-=xjL-GV@}idtDkovOtc5%6uN)U>S`Ec}sCP&}(M2FLOY{;WY|4s7$Zx ze#`+4NBk6YaCffj^P9}U9LM|>bkO&OvCo-{;Bc6jSlVQM{*r3_vtfxPNuhWm*N$05ZcB+!dBClekED1gVyYbU*tvOm*2^8 zkQyfwlMOU}>7yJ6rRg&5vj>e|%#!0EG^+yl_|tgkZ#fP+<5a(LPa3~qcvE5jhSj^Kp)09~uuXDaGMHuYnx~Fb6c8FQpmarBII*4qC={d|n zJmKvXbWquObKWus@!aU9po7c~G5C;=-c{V}qo9M%jwt%`60P4FsGx(;{ww(U6dl?q zXSoiRyW`(&&FM?OJz4<=p|yGB*M+|HI}_zPXpR4${=qaJHC>K_)C{Uub2yFP_LAeE zG@YCxuF&|c#c~{kX7$o@PBb35QjUYp3@U81n8t6em*XHa{>km!X*^$N2@a$yAD1rI!E(>*l-iU2wLkfyfP>Kf ztrN-IGI*LT*FkFr6g6TtHF5vsI7m%E(oAMk^Q1te@HP<~=;d=@GqaJ6HJ0NbG+k$= zG8@^)rR6y2Ou)Z!KJ;39R8fwD%nYz9H-g4vs>^XunHopEm>b~_Eu}ad=#@DAPYzv~ z2MrZ)P?^_rUUj7P7&`?WZ0FvOxWIhz^tiQx4*LFR!cpdnrzf2hbdcCTj+K~608bqh zbkNwyp#_;q0P+14bg-R!*un7${jV-zh=L9(`?FiGskHuLgn|w-`^2Ur^MJw2aSA%< z?8g=^%mW4~QxtR%+D1?OC(xCDJxi{G<(_oEZF&0F{%XDg4nmukKb?7?=gl&?4q7v? zfhF^m;AR`kERw6_X6sO*N=>VCAIo~fXN%$_~gka_**!*>N8bau_Y#?0$KAAc$6Ahff? zcD|)6|2f|+;fY;m7?2_&-J5Zajmr>*G9|5+#3!E*OcUUi24wg29%fP>Ip>J`o$hV^%c zTnDWwJt7}-T*sgNavY>4>B2PTxQ^dPdV0Dc!NuXBy9rl;fZ>dDgMaG~%E4q&OVt^(MgcGhLYogU-f1j$2FXg-R>v zAhenNn=tdoi&T{BV7b4wIB!B21?EEU8#tS&eagdoct2Z{H zaie~698~6SkvwJ^asDAv91irlUi$cDx-y0%6mU?PoC;?QXx(U>f)2KG-}0rErS*bS z6m-z{=wiQ4(0bun3OY#ayG9NzXuars1syatx#hqmv~IjiK?jkIt7))})=R8b&_QK0 zt*X?g^^zMEbdcExeM`I1da3OSI_PZnuoCgKZnj532ciAsY0k_aFB>S=!E(QSeCjaz z(#xDsz(HuM?VZZZeJ^)ju7lS2tUFnq{&X#SS&oC$bRGIKipI;_kmH~<18TLgq;a!5 zavX#v;Ct`uG+sJJj)Ts0^}26H!KH3tI&A^H?w|F{jK=fI$Z=5DN&64~rSZR&lsDiyjpx>ti(9QqV}PS*an3e;Chr9WcIF?*am^|b1V9p9xnB2fY=6o`8=yLGZ*y5FtH8t zaxP?LDt+D0Mu}}umj`>J3e)yucd-rPvfnkb0lja$?;*6Cz=2-Q9gUeu0QWo)~~kdGtRaNI?gY?U(Ny^UBAIQwloB?8IUxnO8nu zhA8MDv}dYYJfK6Ha#gN_!3AH6E{Dh@s!7M z9HgeaacXNCPkt`PL1~IjH%g-Mmnm`_geLOPOj{aHN|WQDGvym*zoPLMpX4~m%+s8e zg=swTha3l$**h=&HH|0yk>YTm*P^@6m^q!#^WTx(6Ke7w4l2_n{4O)6GqI?G4z_bW z<99N1I+IKlbkO%%kC!lWI+M#Q=peC!-`g;Ad0&|;=%BG9Ut2SCdEeAl&_QG;{+h=; z`v2BiK?jxX_hl^e=zp56f(|n4v1&Z?%13%j1s!y@`_fs=D<2;^DCi)x=L!@tq(l3$ zyIcp$-D{RvXL>uA>8OB%&@OoF^?|+eHN(RMvK4QRdj(tZ)S# zWVUQ+Bj&i|pSKls(AkC+Dlo?-=R8o*L1?q48n2^6`zubagXM1iX-+5|+T0fkI0$Wv z(D|e3OaJ{wu7lQW+H!RpjsMD!;~+K89quor@!YR+9F(SaE9>1fo|7ZTL1-3#aQ39} z>^wORI^#U@<$fCfS@5p#HW3`?wJGGJ1C9SEF2_M--Zl;2N8?#$QXCHSY8gMmn6AwC zN(wlrjN#)2%$&|2H57EPohy8|9y6yi+e$$PeQy+Q$IR)>wNcPPVk`ez$;{>b-Aq9T zjkWj^z|7_S+eSeLk!|??9&>DNUS|azRJQEvN6fLg`FbhnAhWgs$;@%d`3ETIU^`cQ z!wu%Rtz*`<;$K^raW}kn5l|8_#SU zM&pG%)2OkX}sVnv>Amc=%DYry*e`=Z3V9?=peD@I%eh2pDu-OD(IlGtGlN&lRt_^E9fAyi~C+< zCVv<|R?tCZFAm$!O#UeGTtNq!-BI&6^CwKn6a^i0cE8mb=1-VXX$m?BZOf~k-RR1j zeUj^7x%<70@uwGD=^qL>27sHRlxE4Nfy_p>l&KsCq3P4SHnWj6EicDGXZ+3`8b`0SlIC(8WM=s2xb-w{Qd^FL z%G6D}%-jesVJ*esK(CPZQOumq;@x0nAs9)warUP?}|T=Q3Y2o9~k2 zAT+(I6lK0y_qxbT0;qgjK?mEpHzPkYkA+u#prC`kCrtdtJQiLpPC*BW&F*5MH2<_=w4Vc&M z8k)&<(3%QGJ~J-_G^ixUL2918+{3&OU|mCwqtfhM#JmJj-%5^y&=mDFVO|2MXCuc! zXP*6CTZ>+6b(_g?keLc~|Jt2S~RRA%ZCKjtNJ%g$094)pr=YY{W2vrbP198@Oy z%P3|}r&WIi9c<^Wzqe%$ZKyX?K?mEpoYz*&p$*m}6?Bl;xcKeNT;7J`6?D+p%*V@_ zxx9_0D(E1x@9xGjb9tN0R?tCZlfxe{b9tLCP|!hU|AvM$hx0V^R?tCbZ=OwJ4(DmU zMnMOmo&Rk5ZMyO;{p31W?pd9$jHb79E&LU55Zbc_hRk7Dt@g@w(3(ot5zKKNEf33a zkeaw(=a}Owf4a2FQqVzTH&|X|CV#Z~t)PR*2H1RNCV#Xu zyf3^<^WTC4l|9hn8#DQ%LlFfXWOhl1KdemW% zXuDOF>tMOBy0$ohzVxmZ3OERD-8)OZ(3jr5zFY^bS(e%^KaF>5BF8~$dNr}hpz*FP z0xS+<;+)7f#Nf)2KGdv?S!b2>XuSI|M<12;aH z!}Q%tK?jLlb8OLPTJOGCK?jXJyKfXTm)BvXf({}ZdeN4d%iC+cf(|OXl|&M4p@ zw3Z)Fw4yJ4V5nRNtyvO2=^>3fU6bP=HGRreu1(_uZpm>_n&Iw$Zqa!E`*IwF#xHDb zLmKb*M2>^b^szPhMdN)FmpzW6f&-9`3P6Zwa?+?L&UZvJ}T%qv} z#&R6g^~G=lCmL^8T8@LdKCF=vOyg}T%5hNFd_Oh}r}0+R}}+O9N0Y=gWse-_%8w#$wa z+n_F;u4iARZPO`Y8^mQuNQG#6-)KBbXxqYpUc1(pWKMZ2HeUe;c{%7^oH^mH_%a0@ z?A}i99L5}xV6s|42VLK`wF`4Rgy}{F9mMt0@oeUlx6<1cbdc9&ff?)Q+Y)8=DCi)t zK4DjwQ{Ku2D(E1wr_b+WPPnUZLO}(QY#zaiJba^KM?b`bqfzUmzX9E8@}+~)>;>D6N7I%th`<8F;;-29mw2dR1U);^xb ztG<-upfq20#M{$&mA7&ngr-f;phq-bIa7{<&b+x*&xpn=eV5}PGuEcVKGJx_UveB& zW|&{oLNs0>-$U7L8Cy8e>sp~`W(Gs~!U{O3%!=YqnfVhHO%!ynom*RGF>^#h<+2Jo z=zFmFF6MZMs#O$pkl5`O^_dwA)oLl|pt1WJHhNBfw$-Sopo7RBYc}p7t=DR-po7Z# zwVpeZ)@wIc&_QNTcb>@{g=5)HK?j}n>Eq5E15~%Gf(}C4Ei*2S4sHG3avd!9i=l<{ z)4%q5P6{{*ZOcO?=u5XAF4sY88kQaXm&WV6$#IaHSJ%zVXuRG8ISxwm?OIkAjn|zf z$3bXXjrXoX<5qLzIOxo)*M*{J+;Wi|2bpQu)U!H`*I6OQL1ilE*sP-Q+Uuk^9O(6Y z=V4|-s>Nmn98@M{>m_D7Y@HnnI@r!-tj}bQNU++kpo6~0dVgh(hp2Z%K?jNb7uJrM zkZOHeK?jY!ecqXw4%_g8f({~k|9CNGLTaNh1szm2E3hmx9kxlNf(|nK^ksSGD4eGE z6m-zp&rb?4#{e~pRnS3bO;*H=r$gI3L9T=4o?LVEKYBZ7|4IP|p}pRB?-KgbTfCR+ zpf%&?kDN~9%|FX=kea|_raNfd{-+!Vr3sGvI*-Pi{gvY&H1iCX_|dqXQH=05QDaxo znZQ+sU1_{&F*y!0Gv0OjNgB5;CC5Q!s=lb)iN>2$km7Kl*Y7g(d(f3>TulK7mAPR) z@++;|)=|*Gb}p(=Gvw0Q$$_Pq6YkodQ_#V7Zd_O==A*6S zB?TSy-R1lc=A*6ibp;(HcErE@J@}bD`?H(lNFgwP5(l29HhqGYXY;W=~qIIgVM|` zw3^w-_AMjFL1@m${9-n;j+Ny&=#2YNuch=_>r+#XgUlRWS7aiM_pU3)L1iA57{}ZQ z@6||(!+~D2EuJtl7<$?(;Gi;n8s1^%PxNl9po8sP=Vp7DFP0Rg!xVH7*->TYFf$kik5bSGzd zX6GO|4mvY&p;K>qtqngV$3bQe9kDn}$*@pnLh6v4 z3OJ~Y)%io#bmN9aE9hW5SM&IH=CN?+#|k>=d&R&{%wyrM&lPl#*k(IjnF*;QQxtU2 z*b-YiFwXZ+1B1gnCYtMN;%{Om0ow`Y;3OER@!~Ji}>vmJh%XQG2 z*C|by7Xl`m%W;sJ`pr5rF9b}gEyqD=+IBy{yaY1QT8@LzeBB+(yaY1AR*r+t)Hidy zPOmlhmU0|q=5<6hOBx^FL5_pUY;M<^d5L^ncPS1BdNpq5c7v|WSVsjMRHj(#g zM7DOJho5MD`dkGaRMx!sV<%dlxkNz+nQcAm1#>vh>{SXn=&aGA>&)Rib9@za5ZaY( zPS&6+KX&d>%5iN5r%5e~y@0aqJBU(Je9scdwj2kUNl7zKrSVx0 z!3Aritl_!<13rVagdsjgiI3}U(rU6gVG#2X#APRmv@%q zU^_Q)#{7ab?%h+4gU*EH=Ec(Zvi@=$Wu}2|3mRWKRE~qnlsNG!hQ^nSl;Uup*Q8F~ zmULwnk5|A!Wt@8ZZ=&_3Qx$ZuopT-da5=4e&sNYu-^UJr+=kXyEKtxvVjaf19ijDA z-U>Qs?DRx)p5sh1NIhRnS3a zhZ@&*pmo2)3OWdFmDqeXbZ9r9l=k%p-xgys=Yvx*= zu1n*aBjh+p&G~=f5j4K(t{exYIlQ=9O&a%mB*#H$+y^<{rSXmNavXH#d{V4Ajc-Vn z;~+D0iyrt%gt>|)|*Rt*Tv31*U|Vq3pozz>ilfhU>f(TFULV$HyIQ-L*t%J`gJF!(YC9z*am&++p1PE+8#PuY=gWM&wH0i+fEb3HmHk7`Vj-#cAPG@L0tO& zPPCx+jSgNyyD1##^~J0fGYO!_Vg(%J} zIx`8taf^Zu;`+=kf|>l$Z>NF|^7^UOOJ?%NfCCCT2yAMtRm`LR1CJ``AhAgewlI(W z4?d%ygUIF$+`+u^F*H;`2bsM!dtMP6JeIbUz7yws zUjYZ9UE9y0K7Hw~Pvkmijm4tX$u#bgD91r+J_P-;qjBfgavYQ<=V`^KG(J3Cj)TzH z<(tr!#)o~8@-~!BC-jNLzbP(BFC;Bsw{=3;J=%BKBhkG-R{*P&`po7dNCAVW<`54zp zK?j{pjdNyR`EYko&_QV1?JHM=4(-H#avd!9CpB6_()ifbavW5~Ecn}48XvP!io=0k=L>F%rYkdgy8;d>v(9)uGYMeq z9t9n2=T@4PAKRgv72hmWF~)1I26Jrg^g9YV$n51#^_k<6XT~V#ptDPRH)4)Up8ZTg2caz# zU1|j#+Bq-fI#}*!FFMwvL+klg0SBSIQ+d=>`qI5Jo0uW#)8xHdoL=V$Ym7#mwdPYNw!s#;!VimYK^tud9L%BD?fjDsyb^g5C-` zsO;t7T;|x^MNSGj$gKbUZ05M+CBqeT(AmAWGnnI&m$@nEAhZQOx9LHLcKHOk4wm}{ zn>CB*(0Wf(z(HuE?Ry`fFMY)vxei)0s*JBAjW1s$$3be2-^ja2`hv;`kjU~U;~ zGI}PwO#}yeoq7|`Y-;?9$#IaHk+wn1re2@@{ce&_QHPe0wr;dAE&K&_QMGmiJ}m^7>C!&_QO+{<<;`80?s-po7j@XLn#8 zFxWLuK?k9|+q$zaUHLsr#;v3`^OfW7-Eth1#$(E8=4<9%hvYa2P1r><=4b1 z!EXvWsH|hv*39IOz+43#WOn-4Cd}(UK?d={+cf{h26Wb8QUm7opQD8obP(EggW4I; zl|NoWu7l-1Z%3a4^mgu883i1Kw&P+O=5@OhmE}5UO~#3@%nJd>Ysztunp$(0FfRlg zt1HJrX_^_0WL^R}+DMLr(B#INGB1G~v6thZGqr~JHKf;CP+K_;GLy0X^(`7d+(nLq z%Iqw@mU)Rhu$L5v1HD{N3}WVV9vYy4gUXCO+=H3Zd3czD4z_cXu2p6ZZ8$PYK?i+z z3eLwI+HlNWK?jMQ<9nK!%X`8@K?jX(zx)I zT;6lb6?BkU$ItJX!+C<&D(IlI?r(oEhx1(6q@aV)`p%eikFNa10J#p9`;bzbv+3Kr`NKI{*6U=cPp&@b{l%{F5Ud$0K7p}^2 z5SriFt(hZQLT<`&(3#o`!rstpEjU_^gUq}?`k*L{pMNaJL1m0?ntY@2bI+wX9OzYZ z&_reuz}XZ998{*F^K51k!1*)<9c<@HcCN-u0toq}po6|!^=Zva0to$~po7F3&01?o zf4W@yqo9MvwqCT6nf!4j|8wCzqW}KMgUB`;cbl2~5mr<|2bC=`If0q{5pJrWgUr@1 z^JE(Rd%sa$K?j{JV}9o@t=}|P&_QU+UHV*#4(+Ylavdypi}yj@=}V8aR=`1MpHJTN zo4)khwsIY`#-p7}VH&^HQjUYvgl%i^ipC>5$Z=4b6X_4~(fG~oavX%ltxec_8jo<4 zk6prJ#e%me^@xLF*3>D(IlI&9;`>P3w=2 zDd-@yWp+orq(d8fR<48PUTEZuD)gm4zNmnM&?a_2*NndOC*g7(v}XF~={IRS_O=`c zskw5_(3-{{Kak^~G^g&rzE9(i;^a68&B%&=wP-x%g&YT+xw66ZD~&&VBga8zrgt4# zp2i1NK(9`943g=QGf_Em8#HG17Y{oczm+G)!CuaP{f4JB zezRbL@CFea=rw3aN?RJgQCyCLy8fG4{T_{no5^udSDOQUEoeNfk{kzht(kNtlE$yp zkmI1PAB$eEPve)YQ)T4kzO)_GUu=WIjPT65O4|p9ifs^>K!*YS zXnXfau?_l?=v*m`w*AM8ZIG9hyPprC?afogHmJ+5Ra=8;+jq9u25~7|H#PN2Q>J2E8rk6Z9~d12Q;i%qo9M`Tho&rnS(jj`6=k2>&6FNn1eZd{S|Z& z*Xp}JGY7J4+^e92yq4emjX98I(_sZ21h&-LgUmrZTTUwIAhGpUTx1U7*%qvzgUA;7 zccChML&*P%f(|lklXa9iTX08&f(}AkX@D_vQ)bs)xek`QLH_94^bdaLBLy6UHg4H` z=4ROLc)1Q*GymjO<~HE2WH}B}bJpuVbNhAYJ2?(Yv#*df^CjDkk8&J@W@?P{Gx~m1 zK$aW_ojE)7r6G;`|CZw*GxOJ-{6OQ|4HIRzW&Ybyfyxvu5zc&>zO9H9hXcK8HH~Es zXxLg(0SA?-()Iy!K*RQO3Od-%m8-LzIhZ4$s)7#s-oSb}b1=tF3k4k{Hh(!==0KL+ z^%Zo`*cMf+m;+h%Hc`+)WNiv83Zp++_qR~cL1l}WjA9PrIoMu72brzsIjIMI?Sb7C zbkNyS3#NUg^`JfqItXnAk7~>#Q%48Nb+FuPtS&j7zVsu`3OESuv%`+eqiV-S%XQG2 zg{wC*59uA9D91r+PCLJ19*#URU5*YA8Os~uLPp7AXz~dUZH?jX9vt2vK$Ll&_QE|ujtGi$a3PE zf({}(aCd3uAf8jV6m(G8shdkM2l1S_ub_j>_R2J1=JK9U57LWlOkYq<`VdneQRzVvo3BwYaqq1|xbX(fH>pgDrn$+$_3urvJzzgARA~?{i?(UhJY5csg90#4rHp^~LWpR%XgF=DfP=~mvG!sPXgJ$YK?mEp{!JS)2Xmaa zQ_w-*C$w$M9Ly2YT0sYi?OI?Nb0AA-Cj}iecA?2`=0KK94hlMm?96ge%t1U?`YGsO zJJ+j99CHv)*boIBWOnM9#5eS=B7B5`4mvw<>aD@Feq)@14njM;O_BX{Xm3uD>tMN$ z-F`TczVwJ$3OER@U%HnAed&?&!3A18-HdtHIGc>I7p5C+da&tCZ?<$2c@aEV-d5FeON_~gV4O~X~Jw| zAJmfLpfmQj)_T)x?S4Hu4l?u8^v`4(zt>ofgUT%S^J8v=M>m(^aG=-6a`!6ImATta z0SA?NQsvP;TEEv-K?mEpmjzZbUpzhNt)PRxr*`HI=JlWSVhTD4?UNOr z@9D~aC?(gya$ncPtq}cd�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 tpA#n5^cyqUy=P7n(-XH{yxd%JTKw<-XiJkVO { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('install_large_prebuilt_rules_package', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es); + }); + + afterEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es); + }); + + it('should install a package containing 15000 prebuilt rules without crashing', async () => { + // Verify that status is empty before package installation + const statusBeforePackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusBeforePackageInstallation.rules_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_installed).toBe(0); + expect(statusBeforePackageInstallation.rules_not_updated).toBe(0); + + // Install the package with 15000 prebuilt historical version of rules rules and 750 unique rules + await installPrebuiltRulesAndTimelines(supertest); + await es.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES }); + + // Verify that status is updated after package installation + const statusAfterPackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(statusAfterPackageInstallation.rules_installed).toBe(750); + expect(statusAfterPackageInstallation.rules_not_installed).toBe(0); + expect(statusAfterPackageInstallation.rules_not_updated).toBe(0); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.ts new file mode 100644 index 00000000000000..2430b8f2148d9a --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.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. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +// eslint-disable-next-line import/no-default-export +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile(require.resolve('../config.base.ts')); + + return { + ...functionalConfig.getAll(), + testFiles: [require.resolve('.')], + }; +} diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/fleet_integration.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/fleet_integration.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group1/fleet_integration.ts rename to x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/fleet_integration.ts diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prebuilt_rules_status.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/get_prebuilt_rules_status.ts similarity index 78% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prebuilt_rules_status.ts rename to x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/get_prebuilt_rules_status.ts index 2252c8317632a6..6d728e0f8d5486 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prebuilt_rules_status.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/get_prebuilt_rules_status.ts @@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createRule, deleteAllRules, + deleteRule, getPrebuiltRulesAndTimelinesStatus, getSimpleRule, installPrebuiltRulesAndTimelines, @@ -90,6 +91,20 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + it('should notify the user again that a rule is available for install after it is deleted', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(supertest); + await deleteRule(supertest, 'rule-1'); + + const body = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(body).toMatchObject({ + rules_custom_installed: 0, + rules_installed: RULES_COUNT - 1, + rules_not_installed: 1, + rules_not_updated: 0, + }); + }); + it('should return available rule updates', async () => { const ruleAssetSavedObjects = getRuleAssetSavedObjects(); await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); @@ -109,6 +124,25 @@ export default ({ getService }: FtrProviderContext): void => { rules_not_updated: 1, }); }); + + it('should not return any updates if none are available', async () => { + const ruleAssetSavedObjects = getRuleAssetSavedObjects(); + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + await installPrebuiltRulesAndTimelines(supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es); + // Recreate the rules without bumping any versions + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + + const body = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(body).toMatchObject({ + rules_custom_installed: 0, + rules_installed: RULES_COUNT, + rules_not_installed: 0, + rules_not_updated: 0, + }); + }); }); describe(`rule package with historical versions`, () => { @@ -146,7 +180,21 @@ export default ({ getService }: FtrProviderContext): void => { }); }); - it('should return available rule updates when previous historical versions available)', async () => { + it('should notify the user again that a rule is available for install after it is deleted', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(supertest); + await deleteRule(supertest, 'rule-1'); + + const body = await getPrebuiltRulesAndTimelinesStatus(supertest); + expect(body).toMatchObject({ + rules_custom_installed: 0, + rules_installed: RULES_COUNT - 1, + rules_not_installed: 1, + rules_not_updated: 0, + }); + }); + + it('should return available rule updates when previous historical versions available', async () => { await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); await installPrebuiltRulesAndTimelines(supertest); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prebuilt_timelines_status.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/get_prebuilt_timelines_status.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prebuilt_timelines_status.ts rename to x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/get_prebuilt_timelines_status.ts diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/index.ts new file mode 100644 index 00000000000000..7b376d5986040b --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/index.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. + */ + +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default ({ loadTestFile }: FtrProviderContext): void => { + describe('detection engine api security and spaces enabled - Prebuilt Rules', function () { + loadTestFile(require.resolve('./get_prebuilt_rules_status')); + loadTestFile(require.resolve('./get_prebuilt_timelines_status')); + loadTestFile(require.resolve('./install_prebuilt_rules')); + loadTestFile(require.resolve('./fleet_integration')); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/install_prebuilt_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/install_prebuilt_rules.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group1/install_prebuilt_rules.ts rename to x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/install_prebuilt_rules.ts diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index d2c8dabaa2c331..c50a5403a166c8 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -55,6 +55,11 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--home.disableWelcomeScreen=true`, // Specify which version of the detection-rules package to install // `--xpack.securitySolution.prebuiltRulesPackageVersion=8.3.1`, + // Set an inexistent directory as the Fleet bundled packages location + // in order to force Fleet to reach out to the registry to download the + // packages listed in fleet_packages.json + // See: https://elastic.slack.com/archives/CNMNXV4RG/p1683033379063079 + `--xpack.fleet.developer.bundledPackageLocation=./inexistentDir`, ], }, }; From e2ad90fbec7891d93880ce39d31d395e299ec0ed Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:09:43 -0500 Subject: [PATCH 35/98] [ML] Add functional tests for Anomaly detection job conversion (#160688) --- .../single_metric_view/settings.tsx | 5 +- .../pages/components/summary_step/summary.tsx | 5 +- .../jobs/new_job/pages/new_job/page.tsx | 6 +- .../ml/anomaly_detection_jobs/advanced_job.ts | 27 +- .../convert_jobs_to_advanced_job.ts | 796 ++++++++++++++++++ ...nvert_single_metric_job_to_multi_metric.ts | 213 +++++ .../anomaly_detection_jobs/date_nanos_job.ts | 26 +- .../apps/ml/anomaly_detection_jobs/index.ts | 2 + .../apps/ml/anomaly_detection_jobs/types.ts | 32 + .../services/ml/job_wizard_common.ts | 45 +- 10 files changed, 1101 insertions(+), 56 deletions(-) create mode 100644 x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts create mode 100644 x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts create mode 100644 x-pack/test/functional/apps/ml/anomaly_detection_jobs/types.ts diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/single_metric_view/settings.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/single_metric_view/settings.tsx index e058af6847763e..fa1ae148722eb9 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/single_metric_view/settings.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/single_metric_view/settings.tsx @@ -42,7 +42,10 @@ export const SingleMetricSettings: FC = ({ setIsValid }) => { - + = ({ setCurrentStep, isCurrentStep }) => {isAdvanced === false && ( - + = ({ existingJobsAndGroups, jobType }) => { return ( - :{' '} - {jobCreatorTitle} +

`); diff --git a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx index d898dbc69035e7..ba63168875d758 100644 --- a/x-pack/plugins/spaces/public/management/spaces_management_app.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_management_app.tsx @@ -83,6 +83,7 @@ export const spacesManagementApp = Object.freeze({ notifications={notifications} spacesManager={spacesManager} history={history} + allowFeatureVisibility={config.allowFeatureVisibility} /> ); }; @@ -108,6 +109,7 @@ export const spacesManagementApp = Object.freeze({ spaceId={spaceId} onLoadSpace={onLoadSpace} history={history} + allowFeatureVisibility={config.allowFeatureVisibility} /> ); }; diff --git a/x-pack/plugins/spaces/server/config.test.ts b/x-pack/plugins/spaces/server/config.test.ts index 995d3e44cc3f32..bc3edf8cf4e5b4 100644 --- a/x-pack/plugins/spaces/server/config.test.ts +++ b/x-pack/plugins/spaces/server/config.test.ts @@ -20,6 +20,7 @@ describe('config schema', () => { it('generates proper defaults', () => { expect(ConfigSchema.validate({})).toMatchInlineSnapshot(` Object { + "allowFeatureVisibility": true, "enabled": true, "maxSpaces": 1000, } @@ -27,6 +28,7 @@ describe('config schema', () => { expect(ConfigSchema.validate({}, { dev: false })).toMatchInlineSnapshot(` Object { + "allowFeatureVisibility": true, "enabled": true, "maxSpaces": 1000, } @@ -34,6 +36,7 @@ describe('config schema', () => { expect(ConfigSchema.validate({}, { dev: true })).toMatchInlineSnapshot(` Object { + "allowFeatureVisibility": true, "enabled": true, "maxSpaces": 1000, } @@ -53,4 +56,24 @@ describe('config schema', () => { it('should not throw error if spaces is disabled in development mode', () => { expect(() => ConfigSchema.validate({ enabled: false }, { dev: true })).not.toThrow(); }); + + it('should throw error if allowFeatureVisibility is disabled in classic offering', () => { + expect(() => ConfigSchema.validate({ allowFeatureVisibility: false }, {})).toThrow(); + }); + + it('should not throw error if allowFeatureVisibility is disabled in serverless offering', () => { + expect(() => + ConfigSchema.validate({ allowFeatureVisibility: false }, { serverless: true }) + ).not.toThrow(); + }); + + it('should not throw error if allowFeatureVisibility is enabled in classic offering', () => { + expect(() => ConfigSchema.validate({ allowFeatureVisibility: true }, {})).not.toThrow(); + }); + + it('should throw error if allowFeatureVisibility is enabled in serverless offering', () => { + expect(() => + ConfigSchema.validate({ allowFeatureVisibility: true }, { serverless: true }) + ).toThrow(); + }); }); diff --git a/x-pack/plugins/spaces/server/config.ts b/x-pack/plugins/spaces/server/config.ts index 5e9b6764e69828..e4a2852a01dc89 100644 --- a/x-pack/plugins/spaces/server/config.ts +++ b/x-pack/plugins/spaces/server/config.ts @@ -26,6 +26,22 @@ export const ConfigSchema = schema.object({ }) ), maxSpaces: schema.number({ defaultValue: 1000 }), + allowFeatureVisibility: schema.conditional( + schema.contextRef('serverless'), + true, + schema.literal(false), + schema.boolean({ + validate: (rawValue) => { + // This setting should not be configurable on-prem to avoid bugs when e.g. existing spaces + // have feature visibility customized but admins would be unable to change them back if the + // UI/APIs are disabled. + if (rawValue === false) { + return 'Feature visibility can only be disabled on serverless'; + } + }, + defaultValue: true, + }) + ), }); export function createConfig$(context: PluginInitializerContext) { diff --git a/x-pack/plugins/spaces/server/index.ts b/x-pack/plugins/spaces/server/index.ts index 6c3794f202e3c3..b7b97692f803eb 100644 --- a/x-pack/plugins/spaces/server/index.ts +++ b/x-pack/plugins/spaces/server/index.ts @@ -33,6 +33,7 @@ export const config: PluginConfigDescriptor = { schema: ConfigSchema, exposeToBrowser: { maxSpaces: true, + allowFeatureVisibility: true, }, }; diff --git a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts index 8107b6f341745f..57a724a16ece83 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts @@ -130,6 +130,7 @@ describe('Spaces Public API', () => { id: 'a-space', name: 'my updated space', description: 'with a description', + disabledFeatures: [], }; const { routeHandler } = await setup(); @@ -152,6 +153,7 @@ describe('Spaces Public API', () => { id: 'my-space-id', name: 'my new space', description: 'with a description', + disabledFeatures: [], }; const { routeValidation, routeHandler, savedObjectsRepositoryMock } = await setup(); diff --git a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts index 5c82f0dd48ed94..ac85d14989ebb1 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts @@ -175,6 +175,7 @@ describe('PUT /api/spaces/space', () => { id: 'a-new-space', name: 'my new space', description: 'with a description', + disabledFeatures: [], }; const { routeHandler } = await setup(); diff --git a/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts b/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts index ff63f71e613df6..709faff41c4779 100644 --- a/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts +++ b/x-pack/plugins/spaces/server/spaces_client/spaces_client.test.ts @@ -17,8 +17,10 @@ const createMockDebugLogger = () => { return jest.fn(); }; -const createMockConfig = (mockConfig: ConfigType = { enabled: true, maxSpaces: 1000 }) => { - return ConfigSchema.validate(mockConfig); +const createMockConfig = ( + mockConfig: ConfigType = { enabled: true, maxSpaces: 1000, allowFeatureVisibility: true } +) => { + return ConfigSchema.validate(mockConfig, { serverless: !mockConfig.allowFeatureVisibility }); }; describe('#getAll', () => { @@ -97,7 +99,7 @@ describe('#getAll', () => { mockCallWithRequestRepository.find.mockResolvedValue({ saved_objects: savedObjects, } as any); - const mockConfig = createMockConfig({ enabled: true, maxSpaces: 1234 }); + const mockConfig = createMockConfig(); const client = new SpacesClient(mockDebugLogger, mockConfig, mockCallWithRequestRepository, []); const actualSpaces = await client.getAll(); @@ -207,7 +209,7 @@ describe('#create', () => { total: maxSpaces - 1, } as any); - const mockConfig = createMockConfig({ enabled: true, maxSpaces }); + const mockConfig = createMockConfig({ enabled: true, maxSpaces, allowFeatureVisibility: true }); const client = new SpacesClient(mockDebugLogger, mockConfig, mockCallWithRequestRepository, []); @@ -233,7 +235,7 @@ describe('#create', () => { total: maxSpaces, } as any); - const mockConfig = createMockConfig({ enabled: true, maxSpaces }); + const mockConfig = createMockConfig({ enabled: true, maxSpaces, allowFeatureVisibility: true }); const client = new SpacesClient(mockDebugLogger, mockConfig, mockCallWithRequestRepository, []); @@ -248,6 +250,79 @@ describe('#create', () => { }); expect(mockCallWithRequestRepository.create).not.toHaveBeenCalled(); }); + + describe('when config.allowFeatureVisibility is disabled', () => { + test(`creates space without disabledFeatures`, async () => { + const maxSpaces = 5; + const mockDebugLogger = createMockDebugLogger(); + const mockCallWithRequestRepository = savedObjectsRepositoryMock.create(); + mockCallWithRequestRepository.create.mockResolvedValue(savedObject); + mockCallWithRequestRepository.find.mockResolvedValue({ + total: maxSpaces - 1, + } as any); + + const mockConfig = createMockConfig({ + enabled: true, + maxSpaces, + allowFeatureVisibility: false, + }); + + const client = new SpacesClient( + mockDebugLogger, + mockConfig, + mockCallWithRequestRepository, + [] + ); + + const actualSpace = await client.create(spaceToCreate); + + expect(actualSpace).toEqual(expectedReturnedSpace); + expect(mockCallWithRequestRepository.find).toHaveBeenCalledWith({ + type: 'space', + page: 1, + perPage: 0, + }); + expect(mockCallWithRequestRepository.create).toHaveBeenCalledWith('space', attributes, { + id, + }); + }); + + test(`throws bad request when creating space with disabledFeatures`, async () => { + const maxSpaces = 5; + const mockDebugLogger = createMockDebugLogger(); + const mockCallWithRequestRepository = savedObjectsRepositoryMock.create(); + mockCallWithRequestRepository.create.mockResolvedValue(savedObject); + mockCallWithRequestRepository.find.mockResolvedValue({ + total: maxSpaces - 1, + } as any); + + const mockConfig = createMockConfig({ + enabled: true, + maxSpaces, + allowFeatureVisibility: false, + }); + + const client = new SpacesClient( + mockDebugLogger, + mockConfig, + mockCallWithRequestRepository, + [] + ); + + expect( + client.create({ ...spaceToCreate, disabledFeatures: ['some-feature'] }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Unable to create Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled"` + ); + + expect(mockCallWithRequestRepository.find).toHaveBeenCalledWith({ + type: 'space', + page: 1, + perPage: 0, + }); + expect(mockCallWithRequestRepository.create).not.toHaveBeenCalled(); + }); + }); }); describe('#update', () => { @@ -298,6 +373,60 @@ describe('#update', () => { expect(mockCallWithRequestRepository.update).toHaveBeenCalledWith('space', id, attributes); expect(mockCallWithRequestRepository.get).toHaveBeenCalledWith('space', id); }); + + describe('when config.allowFeatureVisibility is disabled', () => { + test(`updates space without disabledFeatures`, async () => { + const mockDebugLogger = createMockDebugLogger(); + const mockConfig = createMockConfig({ + enabled: true, + maxSpaces: 1000, + allowFeatureVisibility: false, + }); + const mockCallWithRequestRepository = savedObjectsRepositoryMock.create(); + mockCallWithRequestRepository.get.mockResolvedValue(savedObject); + + const client = new SpacesClient( + mockDebugLogger, + mockConfig, + mockCallWithRequestRepository, + [] + ); + const id = savedObject.id; + const actualSpace = await client.update(id, spaceToUpdate); + + expect(actualSpace).toEqual(expectedReturnedSpace); + expect(mockCallWithRequestRepository.update).toHaveBeenCalledWith('space', id, attributes); + expect(mockCallWithRequestRepository.get).toHaveBeenCalledWith('space', id); + }); + + test(`throws bad request when updating space with disabledFeatures`, async () => { + const mockDebugLogger = createMockDebugLogger(); + const mockConfig = createMockConfig({ + enabled: true, + maxSpaces: 1000, + allowFeatureVisibility: false, + }); + const mockCallWithRequestRepository = savedObjectsRepositoryMock.create(); + mockCallWithRequestRepository.get.mockResolvedValue(savedObject); + + const client = new SpacesClient( + mockDebugLogger, + mockConfig, + mockCallWithRequestRepository, + [] + ); + const id = savedObject.id; + + expect( + client.update(id, { ...spaceToUpdate, disabledFeatures: ['some-feature'] }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Unable to update Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled"` + ); + + expect(mockCallWithRequestRepository.update).not.toHaveBeenCalled(); + expect(mockCallWithRequestRepository.get).not.toHaveBeenCalled(); + }); + }); }); describe('#delete', () => { diff --git a/x-pack/plugins/spaces/server/spaces_client/spaces_client.ts b/x-pack/plugins/spaces/server/spaces_client/spaces_client.ts index f1d7c271353a2b..a09ddf8ad3f38f 100644 --- a/x-pack/plugins/spaces/server/spaces_client/spaces_client.ts +++ b/x-pack/plugins/spaces/server/spaces_client/spaces_client.ts @@ -124,6 +124,12 @@ export class SpacesClient implements ISpacesClient { ); } + if (space.disabledFeatures.length > 0 && !this.config.allowFeatureVisibility) { + throw Boom.badRequest( + 'Unable to create Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled' + ); + } + this.debugLogger(`SpacesClient.create(), using RBAC. Attempting to create space`); const id = space.id; @@ -136,6 +142,12 @@ export class SpacesClient implements ISpacesClient { } public async update(id: string, space: v1.Space) { + if (space.disabledFeatures.length > 0 && !this.config.allowFeatureVisibility) { + throw Boom.badRequest( + 'Unable to update Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled' + ); + } + const attributes = this.generateSpaceAttributes(space); await this.repository.update('space', id, attributes); const updatedSavedObject = await this.repository.get('space', id); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/spaces.ts b/x-pack/test_serverless/api_integration/test_suites/common/spaces.ts index 0998d4cdb317d0..3184423411e474 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/spaces.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/spaces.ts @@ -15,7 +15,7 @@ export default function ({ getService }: FtrProviderContext) { describe('spaces', function () { it('rejects request to create a space', async () => { const { body, status } = await supertest - .post(`/api/spaces/space`) + .post('/api/spaces/space') .set(svlCommonApi.getCommonRequestHeader()) .send({ id: 'custom', @@ -32,5 +32,25 @@ export default function ({ getService }: FtrProviderContext) { }); expect(status).toBe(400); }); + + it('rejects request to update a space with disabledFeatures', async () => { + const { body, status } = await supertest + .put('/api/spaces/space/default') + .set(svlCommonApi.getCommonRequestHeader()) + .send({ + id: 'custom', + name: 'Custom', + disabledFeatures: ['some-feature'], + }); + + // in a non-serverless environment this would succeed with a 200 + expect(body).toEqual({ + statusCode: 400, + error: 'Bad Request', + message: + 'Unable to update Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled', + }); + expect(status).toBe(400); + }); }); } From f923e9ddc707f9211707536d1836642a73a4024b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Mon, 3 Jul 2023 18:50:47 -0300 Subject: [PATCH 38/98] [Profiling] fetching latest package version to use in instructions (#160498) Screenshot 2023-06-26 at 10 44 41 AM --- .../plugins/profiling/public/views/no_data_view/index.tsx | 2 +- .../profiling/server/lib/setup/get_setup_instructions.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/profiling/public/views/no_data_view/index.tsx b/x-pack/plugins/profiling/public/views/no_data_view/index.tsx index a6bd9159d8c7d5..99580891939318 100644 --- a/x-pack/plugins/profiling/public/views/no_data_view/index.tsx +++ b/x-pack/plugins/profiling/public/views/no_data_view/index.tsx @@ -329,7 +329,7 @@ docker.elastic.co/observability/profiling-agent:${hostAgentVersion} /root/pf-hos iconType="gear" fill href={`${core.http.basePath.prepend( - '/app/integrations/detail/profiler_agent-8.8.0-preview/overview?prerelease=true' + `/app/integrations/detail/profiler_agent-${data?.profilerAgent.version}/overview?prerelease=true` )}`} > {i18n.translate('xpack.profiling.tabs.elasticAgentIntegrarion.step2.button', { diff --git a/x-pack/plugins/profiling/server/lib/setup/get_setup_instructions.ts b/x-pack/plugins/profiling/server/lib/setup/get_setup_instructions.ts index df6da32a11b867..569c60a9e58a9e 100644 --- a/x-pack/plugins/profiling/server/lib/setup/get_setup_instructions.ts +++ b/x-pack/plugins/profiling/server/lib/setup/get_setup_instructions.ts @@ -7,6 +7,7 @@ import { SavedObjectsClientContract } from '@kbn/core/server'; import { PackagePolicyClient } from '@kbn/fleet-plugin/server'; +import { fetchFindLatestPackageOrThrow } from '@kbn/fleet-plugin/server/services/epm/registry'; import { getCollectorPolicy } from './fleet_policies'; export interface SetupDataCollectionInstructions { @@ -17,6 +18,9 @@ export interface SetupDataCollectionInstructions { symbolizer: { host?: string; }; + profilerAgent: { + version: string; + }; } export async function getSetupInstructions({ @@ -28,6 +32,7 @@ export async function getSetupInstructions({ soClient: SavedObjectsClientContract; apmServerHost?: string; }): Promise { + const profilerAgent = await fetchFindLatestPackageOrThrow('profiler_agent', { prerelease: true }); const collectorPolicy = await getCollectorPolicy({ packagePolicyClient, soClient }); if (!collectorPolicy) { @@ -46,5 +51,8 @@ export async function getSetupInstructions({ symbolizer: { host: symbolizerHost, }, + profilerAgent: { + version: profilerAgent.version, + }, }; } From f516756f2dfb02ea162b30d9f9a78cf63edf7efd Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 4 Jul 2023 01:03:05 -0400 Subject: [PATCH 39/98] [api-docs] 2023-07-04 Daily api_docs build (#161142) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/388 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/ess_security.mdx | 2 +- api_docs/event_annotation.devdocs.json | 32 +++ api_docs/event_annotation.mdx | 4 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...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.devdocs.json | 12 +- 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 | 8 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- 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 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- .../kbn_deeplinks_management.devdocs.json | 4 +- api_docs/kbn_deeplinks_management.mdx | 4 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.devdocs.json | 71 +++++ api_docs/lens.mdx | 4 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 14 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 252 +++++++++++++++++- api_docs/security_solution.mdx | 4 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.devdocs.json | 28 +- api_docs/unified_histogram.mdx | 4 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 550 files changed, 945 insertions(+), 570 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 6e7c474cacd7aa..ad17a9658141de 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-03 +date: 2023-07-04 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 fd3ff9831d794b..d34f6b34e8a88c 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index ef98513eae8af9..5d81becf0cec87 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-03 +date: 2023-07-04 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 15a204ae04874b..83e91fe75b1de3 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-03 +date: 2023-07-04 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 c14f27ab3bedc5..db7a984011e21b 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index e6f19ae5a0655d..f40dd137025257 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-03 +date: 2023-07-04 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 897a78bb219c36..7d6e5adc83ee91 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-03 +date: 2023-07-04 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 44c2cbb782545a..2a2fb8a2a57987 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-03 +date: 2023-07-04 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 75b92e187bcf1b..a87c0da4c59a76 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-03 +date: 2023-07-04 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 c6dd67e43d07e9..6a2cd6b1983233 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-03 +date: 2023-07-04 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 479c3cdeca6463..48885ef8148b90 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-03 +date: 2023-07-04 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 554372c5a7ed30..2700c0dafcff8e 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 4de2551a154c69..9f18be8b202d44 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index d1205180fca8e1..6506992af3dbb0 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index c2dc31f4d57a0a..7fabe7cee93bd6 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-03 +date: 2023-07-04 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 55ba6908278021..bc999ca7a36e4d 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-03 +date: 2023-07-04 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 d9730ff4cf9e81..73b6bdc2b3fedb 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-03 +date: 2023-07-04 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 19be173117b071..6a25bf5adb97a5 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-03 +date: 2023-07-04 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 176380ce83ac14..2529761f7d5dd0 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-03 +date: 2023-07-04 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 b22e9513e94dbf..2318d55651cf42 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 2268e61817c725..040339a1919688 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-03 +date: 2023-07-04 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 299103af8c7ece..409fc55ae8097c 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-03 +date: 2023-07-04 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 16a417cacb7a5f..2d9cce85dce5a1 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-03 +date: 2023-07-04 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 9ff6f2330f88b0..7a9159bc2af6ca 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-03 +date: 2023-07-04 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 9551b7cebe961d..e102c339d573da 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-03 +date: 2023-07-04 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 9bb77627bfcaa7..ce23f808c4b9ba 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-03 +date: 2023-07-04 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 0f93446b3f05aa..5ecdb2c2554a4a 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-03 +date: 2023-07-04 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 3e737d288086ca..d8be969b12b09d 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-03 +date: 2023-07-04 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 1ae9fad417e5d2..937820ce7b3329 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-03 +date: 2023-07-04 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 37f9b4946d837c..b01a33cf59a807 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 fa611f10b8e361..c1758ac2dd8050 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-03 +date: 2023-07-04 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 bda216ec621756..e5645a3a53631d 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 550f6f68163095..06e28d8a7044ca 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index db32045f128177..1b374e702fef3b 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 6c7f4a1b499f3a..4bcdd17947c739 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 96ffcfe43d38d0..52b9af51f2c7b2 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-03 +date: 2023-07-04 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 c1d76eb83346c8..418852fb9f6533 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-03 +date: 2023-07-04 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 2b842e492a9b67..e2972d0dfd69aa 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-03 +date: 2023-07-04 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 04d584f7282f90..c7bac8be8e9b6a 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 9f214e29aca76c..ff9c75066c3b26 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-03 +date: 2023-07-04 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 c657b333104096..ddce516c012ff4 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-03 +date: 2023-07-04 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 87bec77293be6d..b30797a3f95f06 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-03 +date: 2023-07-04 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 0757a18e10a19e..7572712578fac8 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-03 +date: 2023-07-04 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 8dcd203f43d13b..1585b322a90b5d 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 856ed0b67c624d..6eb352855c17e2 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.devdocs.json b/api_docs/event_annotation.devdocs.json index 3b205ea85a4728..98e46a80595620 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -310,6 +310,38 @@ ], "returnComment": [] }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.groupExistsWithTitle", + "type": "Function", + "tags": [], + "label": "groupExistsWithTitle", + "description": [], + "signature": [ + "(title: string) => Promise" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.groupExistsWithTitle.$1", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "eventAnnotation", "id": "def-public.EventAnnotationServiceType.findAnnotationGroupContent", diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index a6ba105b7a6a2a..ebcaea8eb22de8 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.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 | |-------------------|-----------|------------------------|-----------------| -| 234 | 30 | 234 | 4 | +| 236 | 30 | 236 | 4 | ## Client diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index bfd0d8f64ebfee..44e2bd875b10fb 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-03 +date: 2023-07-04 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 0e550c333dc305..7bc6143ad981f4 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-03 +date: 2023-07-04 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 62c5aed54bee29..a7de02f274013b 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-03 +date: 2023-07-04 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 25ca29169fd792..cc271283bf0984 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-03 +date: 2023-07-04 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 aa3ecef0635b6b..9f75050ead27a9 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-03 +date: 2023-07-04 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 cb9cf1e79b81e1..6028515124c6fa 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-03 +date: 2023-07-04 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 bd845b069beefe..15a537e2d51f6e 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-03 +date: 2023-07-04 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 4790a1440a31ca..270077e1f90a40 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-03 +date: 2023-07-04 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 a5fda431f88e6d..c9c25bfb55849e 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-03 +date: 2023-07-04 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 6dc2d107f845cd..8fc7a7e9ed4fa5 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-03 +date: 2023-07-04 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 c4b99bdb1cd89a..2d1a7bc8c5c67c 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-03 +date: 2023-07-04 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 b4e92499d5a597..3b8c50f4f716cd 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-03 +date: 2023-07-04 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 a8212bf8743583..7c787d2e5ffdb6 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-03 +date: 2023-07-04 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 05d7b916e4d527..1ebeebd4806c9a 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-03 +date: 2023-07-04 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 2f41edf8ec7287..9c29344ace5f46 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-03 +date: 2023-07-04 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 4f29157f0d332b..70bb1c475558ba 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-03 +date: 2023-07-04 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 f6d4c24f36bb96..324fcd2d3e1d89 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-03 +date: 2023-07-04 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 2838e587f6f9fc..e629b0856dfdc6 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-03 +date: 2023-07-04 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 dba63ce83efd06..e4a966fdb1ab75 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-03 +date: 2023-07-04 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 6db8d183a55ce4..b098d802536707 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-03 +date: 2023-07-04 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 cc9fa3ccf98951..b5ed85ea0dcec3 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 e3561ff67f72fb..809ab35271d07d 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-03 +date: 2023-07-04 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 7fecdc4a0cf484..fe8c108d89c198 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-03 +date: 2023-07-04 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 693fb5e1bc6a2f..f54b3f1c9193f7 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-03 +date: 2023-07-04 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 066cbf18f7bfec..ae22c32d050c67 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-03 +date: 2023-07-04 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 292d0a0ee2565e..3fa952261dfced 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-03 +date: 2023-07-04 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 489440e7892eed..a34f0e49250b81 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 13174c35a62988..b312a6e5805457 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 520d1eb1b99cfd..a5fa5320a15ad6 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index c669489aceb7b2..3016167dbadc96 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-03 +date: 2023-07-04 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 ace377408281a5..92db3f9f5a869d 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-03 +date: 2023-07-04 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 3510ccb3026ed0..4447e5cac6cdf8 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index d8b747beb9973c..c7881e6db0d4dc 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-03 +date: 2023-07-04 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 073c7ad634370d..892fe8b449a2b1 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 3b07e03c7e8f7a..0383b8294e7412 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index a89fadba6b9052..09c8ce2b54e616 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 f8116af96a29c8..b1cc6337c8b886 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-03 +date: 2023-07-04 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 6549daceac9df8..05db7cccba3ee5 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-03 +date: 2023-07-04 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 487971dc0824d5..eaa250a5ecc478 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index b84ca2a9ae3d61..29edbaff662f9b 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 d835ce46020aaa..a8b8deafa8651b 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-03 +date: 2023-07-04 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 d8ef06e92a2d4c..1020205dc4822e 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-03 +date: 2023-07-04 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 34aae13e5f9090..05c90d17d081d4 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 5903db6c22eb47..86a3dde84ae357 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index ff477d2694ad9f..f7dc2dc3b5cd97 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-03 +date: 2023-07-04 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 d7c82e20ac2043..ffd76f5befb0ad 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-03 +date: 2023-07-04 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 ddecff7dcdc3a0..4ff52a33cd1063 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-03 +date: 2023-07-04 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 dfe6f14649adf7..e0e3d648396ed8 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 7cf209d3a67e8f..08eb9822b39929 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 929302a536fb96..6af0298297db23 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-03 +date: 2023-07-04 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 5d822ead90c1bb..ee145317c7a156 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-03 +date: 2023-07-04 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 2634b8ff3bd297..0e1ff6a18c03d4 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-03 +date: 2023-07-04 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 8ede10441d779e..09d08081ede2d3 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-03 +date: 2023-07-04 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 52f8c815893b1a..5a8b540b7afd0e 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-03 +date: 2023-07-04 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 b4c0a5bc34885a..c0d60d4e438b3e 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-03 +date: 2023-07-04 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 086ac5b45494a0..f5fec23312d66e 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-03 +date: 2023-07-04 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 414873ca5e0c22..be02de2cfa2b66 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-03 +date: 2023-07-04 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 ed494fbbffdbea..e2c1441169e548 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index a8fcbb433416be..7f96b467760a90 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 8a8436cfca4f55..e8a553cc9d3e83 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-03 +date: 2023-07-04 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 fb82faf4a7a276..dfb0fc4bea1af1 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-03 +date: 2023-07-04 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 3455e1e02089c8..5840134a950a8a 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 c62ef76a639b59..04a87e07837bf2 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-03 +date: 2023-07-04 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 e31d1f88a6d910..1b1f33770ba25b 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-03 +date: 2023-07-04 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 22d2d4f11a7036..f1cf58b40fe784 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-03 +date: 2023-07-04 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 385c8b7b370620..6637ae18de157b 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index feded3fb5194ac..86878d5639e57f 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-03 +date: 2023-07-04 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 db392a7e558a2d..830c118143e970 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 f04fb919cc799c..008651ac785257 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 9b4fc1de7b3580..e96413c1a76ee1 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 9b46410b4c5d5d..38c692ab092815 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f6024026e107b0..c38f0f22c5c57a 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-03 +date: 2023-07-04 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 ea4cd542ba79fc..4646a442f6da23 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 7b7474182acccb..09a807b53a682b 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 45eafb44bfc209..edc0fe763f88f1 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 2ef325b1161b0e..2cc6de17e6ab87 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 dc7c24e327b29e..538e6d007d3613 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 8a4c00d3d5b3d3..6043c0fc6355c3 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-03 +date: 2023-07-04 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 db198460df5562..019640cbbcc4e4 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 d3179020d8a577..cc2727a24e0ab2 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 c57aa5a6b905f4..8a63df9777762d 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 5a5bafaad26479..e0903c7183424b 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f35498753f0dcc..d002fd41f7ec5f 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-03 +date: 2023-07-04 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 20ba41af78b051..3de35a97b476ae 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 72e523cd3bfccc..619ca6aeb9bc82 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 8bc58dcf9a0b16..b97664c086f8f2 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 49770b82a23170..bb705fe5edb525 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-03 +date: 2023-07-04 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 80a41f737d7a8b..295e6df862d871 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-03 +date: 2023-07-04 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 43feccb9120762..e93d15505034b5 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.devdocs.json b/api_docs/kbn_core_chrome_browser.devdocs.json index 5d48630ad5476d..250961d874a727 100644 --- a/api_docs/kbn_core_chrome_browser.devdocs.json +++ b/api_docs/kbn_core_chrome_browser.devdocs.json @@ -3104,19 +3104,19 @@ "section": "def-common.AppId", "text": "AppId" }, - " | \"serverlessElasticsearch\" | ", + " | ", { - "pluginId": "@kbn/deeplinks-observability", + "pluginId": "@kbn/deeplinks-management", "scope": "common", - "docId": "kibKbnDeeplinksObservabilityPluginApi", + "docId": "kibKbnDeeplinksManagementPluginApi", "section": "def-common.AppId", "text": "AppId" }, - " | ", + " | \"serverlessElasticsearch\" | ", { - "pluginId": "@kbn/deeplinks-management", + "pluginId": "@kbn/deeplinks-observability", "scope": "common", - "docId": "kibKbnDeeplinksManagementPluginApi", + "docId": "kibKbnDeeplinksObservabilityPluginApi", "section": "def-common.AppId", "text": "AppId" } diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index d18ed9db795ccc..cb9f0af5035f85 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 3f904a46cf2156..0009d47b8a4a58 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 36f2c3f8d4211c..59d0fa8660c8c6 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 b13cbd06d06ae6..4fb5fd22aad52f 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 07255a61ef8eea..c45e9944816bba 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 d43b547f61936c..7b6f25d3a912a0 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 574213ae5c3c51..e972c6cf04c961 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-03 +date: 2023-07-04 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 d3f84a72783724..110cd4e3f07f6e 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-03 +date: 2023-07-04 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 ea12c1ad4746a6..6a268409b8b8ef 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 a40642519f3735..fff01280c1b7e0 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f4e6020861c2c3..1d2525ad461f4a 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 4aad2c2eb3045e..2c6f2cb0c9f056 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 d6ea7c1ad09985..2244941546c14e 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 c9f3ffa34e4202..a62a6b4eab1c2b 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-03 +date: 2023-07-04 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 a1746de33122b8..e8a9f111eefc13 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-03 +date: 2023-07-04 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 79c322f80b0d5b..ef32238172fc39 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 a816923aade617..ce299f14629b85 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 1672f37050fded..1b51cdc26d7cc6 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 9b4d14ae1b7cd7..f14ea8fedf2e3b 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 0565c0ab62ed24..c68c1db4cd4d67 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-03 +date: 2023-07-04 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 8389ce52496569..ab05459266b273 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 dd0d1aaad67dd9..acdad0a739f8fa 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 0f5abe010369c1..9cc3421ef11d93 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 5bfec1ca6c4b36..24e834d41a22c5 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-03 +date: 2023-07-04 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 e7feab4db21181..a64e41ba3731ef 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 b78a3adba13971..35f51d36937d6b 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 84154ebfde0891..06577c4bfedef3 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 e47082f7c1934d..5b05d23cf4e75c 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 36e70d152ebfbc..611747b140e5a6 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 80282eb1ff5fc4..54ca347bac7b25 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 60d57dd5e3e387..61bd3b7cf44ca4 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 3f958fd4c0e4a1..680e61cedd9f9f 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-03 +date: 2023-07-04 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 5f493fcce34cd6..744c2f429b0bc7 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-03 +date: 2023-07-04 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 d6aad01e676eb2..7f7f44f139808d 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 cd4b201905a621..c62e6d381bcf74 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 4eefbbc1a62122..54d4aae2e008ec 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 7202e3113edc7b..b37260cd832445 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 35333e04959760..2865f4b8275ad6 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 53697d0e06fa51..00847cf8ece377 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 99d48d422df00b..ea3dc9f8213d17 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 fffc5966c181f1..886e0eb03817b7 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-03 +date: 2023-07-04 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 6b1abf77a61ad0..7c3941e3a4b955 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 e2d870af2bd905..72c13da6384d70 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-03 +date: 2023-07-04 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 558e64209ae587..d05e402eba6db5 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-03 +date: 2023-07-04 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 9302f4d7edfb9a..59b93a42e3f51a 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 b49b267aa07d35..185c261cb8f1a3 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 ff78a784afc473..70cdc4c6b44af9 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 44e99bcd360f1a..be0d486c3c14c8 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 cdc4974ac790f3..dfbbfb44b2ab6e 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -3739,10 +3739,6 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/vulnerabilities_dashboard.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/server/routes/status/status.ts" - }, { "plugin": "indexManagement", "path": "x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts" @@ -14026,6 +14022,10 @@ "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts" }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/server/routes/status/status.ts" + }, { "plugin": "cloudSecurityPosture", "path": "x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 9c8f8292e92038..b2eeca5f96d65c 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-03 +date: 2023-07-04 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 fc90a923127ec2..697be80a43bd1a 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 fca10b2470a7bc..91dab3c567922d 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 da45a2b7a3937f..5e29c1c8d5d5c6 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 b16574938c4967..96f5bbfc54ed85 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 e3e029d65d6d66..6e11aee7bff50d 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-03 +date: 2023-07-04 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 6d281f60d24b68..8bfa1abdea3cfb 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 df1e020523f62b..c3531b95057c4f 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 0ad4d0f2ec0ed9..71b2a0188555ac 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 9a81492fe19754..1cda5852cfb3a4 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 3ec3daae38115c..c948050d4aae75 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 212298f954c989..b7e43c6383f0ea 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 626ce47187eac6..1487d3a5b95c7e 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 e2830ae5cf0168..e3bbfe6ae80413 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-03 +date: 2023-07-04 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 64e32ba8edc671..764e031107a698 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 e461b3fb20f9ab..f3425b129afa09 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 34b1a1178c5d74..9d145940a1d4cf 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 f3236e8121fdd3..63cf0b9ae89e98 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-03 +date: 2023-07-04 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 73adce21cdcf7c..2d6c7ea659c6e2 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 d28da30ecdd5d0..47f3b699358690 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 96963764a6763d..f097b5f4ae190d 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 8c75dde632791c..92e83e107aa3cf 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 52153d6ff57daf..d074354d8bfccc 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-03 +date: 2023-07-04 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 00a6e9c8ad6d01..436361e3a98bab 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 a4c20122cb118b..6afd1424146c43 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 7f21472bb92e0b..ce03c4ed395ea4 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 909233cc5ab6f8..01213c660eb388 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-03 +date: 2023-07-04 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 bef05ac9357c3e..21153e4c20214e 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 8d3df740e56ffe..22032b4cf15e8d 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 bb98f55ea0c41d..04543a86d0f185 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 8e6d151c4d659f..1e02cdc66bcb0a 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 313654df45a85b..cb6065df415aaa 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 772ceeee94c362..57d8eab0e24600 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 50f5127ccc679d..cd77277ba20553 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 efe823a173a128..e421f830fefc87 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 d9e879a748dc37..00d6841616eaf5 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 602278778c3e6e..b72c13a2524dc3 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 15fadabe771b35..a2e52feb035fda 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-03 +date: 2023-07-04 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 ecd45f7308de09..f20f940bcb4b30 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 8ce163e2665096..bbce5ccf2f3960 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-03 +date: 2023-07-04 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 054389789e925b..482591c15c5d57 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 18d62db4cc7869..fce578a024807d 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f2bff07a801801..ca72a5e33e755b 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 f55cdab569d6bb..971e6c1d5ad5cd 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 7bcc25af5e6807..e0424e272d2236 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 dc2c8b47d9168a..3242bd32717d1c 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 678967576150b1..a56edb7348e00c 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-03 +date: 2023-07-04 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 fa67962a4b5693..b0f0185d613a56 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 9dffcf9fef3f81..46e56a4600a34f 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 6b9dbfe06b4c3d..c30924e5d49445 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 ee12e8cc98ddbe..ecee99ce6b8e66 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 f6fdabf1d65679..e7a62377c54902 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 3e05cafa5ddd4c..17d7b701c8ae6b 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 149fbedfff6a9a..c24e300c7ae767 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-03 +date: 2023-07-04 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 ea4258f65d0d38..0d038a4d8c4a2b 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 a037d82b405490..4caf846a211cbe 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f50bbb8616046a..a3dae1157c7b6a 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 a478edb3197517..37a950cf4a1e68 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 35596d4d833c9c..d3b76b217c0416 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-03 +date: 2023-07-04 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 b0b5255227a364..7041c9e794c0b2 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 7a0b0f68d5d320..aafe67cbc77e32 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 8d295836a6cf86..c961a02353ad9d 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-03 +date: 2023-07-04 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 768599b5053bb9..3e982bcdcdfbc7 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-03 +date: 2023-07-04 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 511a84babbe8fc..3f9b8ea6277ca6 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 2fc2797f45d100..4ef72b8729839c 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-03 +date: 2023-07-04 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 37cc2281c42be8..b31a27d321c667 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 baf2f79e049531..8846edb7c118fa 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 92205214d635ca..85d8cad3d4b1e3 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-03 +date: 2023-07-04 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 beb474f595f4f3..7bd36413cff198 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 b6e914193798eb..5a10893b25f65a 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 7dbe9a90426e31..e1172bfcf5736d 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-03 +date: 2023-07-04 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 0d6ecf679c5b01..932f78c36e2f5b 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 0e6f51e1c3309a..9ce1c80941fc06 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 142f6035898c26..8fbb1d68a59d95 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index f7d9767b813e17..d6270e822e583e 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 e39273566fa65d..c6c9e9db5e2e80 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 5057dd29a20de6..5e61152ee78c7f 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 ee79b6d1f903ba..ed527423205b08 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 f9b62b1dc92ce0..4f3505d61acb46 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-03 +date: 2023-07-04 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 bec01eeeb70339..4901fa31e1eef0 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-03 +date: 2023-07-04 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 cffe5df4a856ad..0261a6753fd871 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 9bb9dc64916f28..59aad9446a7855 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 b5e3493f82751e..c9eff7e0783263 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-03 +date: 2023-07-04 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 0ca51dd533610d..290460ff397721 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 d8aee8bf1a7f9a..ef72203c9a2492 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 39a86e004ef48c..eab0737161af4b 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-03 +date: 2023-07-04 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 f851a352f922dc..5bd975ff079a06 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-03 +date: 2023-07-04 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 81e97a47315f89..a9c9b44293c5b5 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 83d77c684910f5..df2549a2dbd250 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-03 +date: 2023-07-04 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 e39edeea0c06cf..ca331bc0f110fa 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 5bb1ef01346fe8..cd7a2d468959a4 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 7d2b146ae217be..e0432f0678d1d4 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index e39f50ec0a1771..367754dce9395a 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-03 +date: 2023-07-04 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 8e46553951fd4b..3080e419eacc59 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-03 +date: 2023-07-04 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 b12bd067253025..68575f9ab12326 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.devdocs.json b/api_docs/kbn_deeplinks_management.devdocs.json index 9132a4b8b38099..4d6cf71eb42eb0 100644 --- a/api_docs/kbn_deeplinks_management.devdocs.json +++ b/api_docs/kbn_deeplinks_management.devdocs.json @@ -45,9 +45,7 @@ "label": "DeepLinkId", "description": [], "signature": [ - "IntegrationsDeepLinkId", - " | ", - "ManagementDeepLinkId" + "\"fleet\" | \"monitoring\" | \"management\" | \"integrations\" | \"osquery\" | \"management:transform\" | \"management:watcher\" | \"management:cases\" | \"management:tags\" | \"management:settings\" | \"management:dataViews\" | \"management:spaces\" | \"management:reporting\" | \"management:rollup_jobs\" | \"management:snapshot_restore\" | \"management:api_keys\" | \"management:cross_cluster_replication\" | \"management:index_lifecycle_management\" | \"management:index_management\" | \"management:ingest_pipelines\" | \"management:jobsListLink\" | \"management:objects\" | \"management:pipelines\" | \"management:remote_clusters\" | \"management:triggersActions\" | \"management:triggersActionsConnectors\"" ], "path": "packages/deeplinks/management/deep_links.ts", "deprecated": false, diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index d8de57ea9eb71c..074598f2cea122 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_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 | |-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 4 | 2 | +| 4 | 0 | 4 | 0 | ## Common diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 3970bdf914e056..0c09bc615d5076 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-03 +date: 2023-07-04 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 24d30e69b89e7f..fc254f18c31215 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-03 +date: 2023-07-04 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 5ee03ee5870e73..b74ffd6153fd1e 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-03 +date: 2023-07-04 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 d5b977c5cdee8b..b8dd1b16c1afec 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-03 +date: 2023-07-04 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 b9c31f0d9e983b..ae70bde03b62e3 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-03 +date: 2023-07-04 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 7a6ec8b0b24184..e24b1368c737ca 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-03 +date: 2023-07-04 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 2a63690175ac15..8a8b442215eb1d 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-03 +date: 2023-07-04 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 0c5e55f1530a3d..2f3ae44f970cc1 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-03 +date: 2023-07-04 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 bc8cfc1ec87ad1..6636b5c1150fbe 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-03 +date: 2023-07-04 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 2ccea747389a6e..36f13e19990f54 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-03 +date: 2023-07-04 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 c57740608bdd12..d27aaf7f123775 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index b5e4d8524be67c..f8bb2a0756f610 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-03 +date: 2023-07-04 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 73419b45a76af3..9ee7f091de121b 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 4b6d0775c4b0e0..525fe1ea499488 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-03 +date: 2023-07-04 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 2eb3f2d9143d3b..a1badcff4047a3 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-03 +date: 2023-07-04 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 c7a18913894110..9a21b359569416 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-03 +date: 2023-07-04 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 6a512056beced2..1380a5ce236068 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 2f2101d15abd1c..fe13918be2778d 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 1239f4f1c5e005..4c00487d2c921f 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-03 +date: 2023-07-04 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 37873c856d57f9..e130b85df50f81 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-03 +date: 2023-07-04 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 78131a2926647a..37ed6764d9d110 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-03 +date: 2023-07-04 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 6c30bc36e3c11a..8cc7f32862d753 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-03 +date: 2023-07-04 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 596300c1b5913a..9993297aecd478 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-03 +date: 2023-07-04 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 570b75b9240641..c6221cdd52fd8f 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 6cbe0e1c4e47cc..13039abc93aeef 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-03 +date: 2023-07-04 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 dca9f7d611e9c7..a780a047abf91a 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 762218ef04c432..a3ec886292f862 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-03 +date: 2023-07-04 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 ee52ceb039d68a..4cd3a8ffd83214 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 614a3fc288bb29..460933a2bda731 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-03 +date: 2023-07-04 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 f5948cfc5773dd..1f0558a5682813 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-03 +date: 2023-07-04 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 67f03a9e45bc87..93c368ed8344d9 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 797b415e2da5f1..19055b5175f5be 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 0d95afc4efd7f9..6962f103e5e3a1 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-03 +date: 2023-07-04 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 60231ea44d3060..ca311d4625ffc8 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-03 +date: 2023-07-04 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 71a44612532b07..980f8dae553bb1 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 a19ad26316f301..0995e7249e78aa 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-03 +date: 2023-07-04 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 a569f10bf7bd99..c70a2b6524a908 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-03 +date: 2023-07-04 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 6daa232d8b9b0e..35ddd71105f386 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-03 +date: 2023-07-04 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 347792b5678fab..581a1ee645ad70 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-03 +date: 2023-07-04 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 bb21d9c01981e8..1d7212b47abc29 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-03 +date: 2023-07-04 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 65ff9f51736291..9992c13c43ead5 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-03 +date: 2023-07-04 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 a7c683a49990d3..87b444509c4857 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-03 +date: 2023-07-04 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 77cd989c028427..3c57cadc78fe70 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-03 +date: 2023-07-04 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 d2fa70c64ec432..f85b14c96f908a 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 38fdd3c2e61d64..3a09e78df1cbfe 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-03 +date: 2023-07-04 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 d687e871dc6980..689b4dcace1963 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-03 +date: 2023-07-04 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 e2c176c38744ef..03cfccc40e4ef7 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-03 +date: 2023-07-04 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 b8bd537cdf4b16..5f8335522f806b 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-03 +date: 2023-07-04 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 eef98288dea02f..24e0a861e8aea9 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 150f581c087441..bd1a52c6f2b565 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-03 +date: 2023-07-04 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 f9231eb985b6cd..ab60eff2f410e0 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index f035ae091252d0..f858ddf4a4fe8b 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-03 +date: 2023-07-04 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 1031ad4ffaa31b..e6575c26fe7ddf 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 6be3e936cde506..25143b05f015d0 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-03 +date: 2023-07-04 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 7c38ff1a3d33bd..b431413f651d2e 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-03 +date: 2023-07-04 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 4441d8cfe1704f..c2964e6dd24df4 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 257ba4e7fc4e54..998583b2ee74ca 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 bd1e1501481cd1..681d57a9343f91 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 67992c1e250739..5028d47a4a19ae 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 9639238308b58f..ee8cc92bd5d331 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-03 +date: 2023-07-04 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 8ae9d959e5c41f..eeb84e42534a40 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-03 +date: 2023-07-04 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 d6a6621ffa99ce..4da916714865da 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 f73cb8fb9678ff..855a5375ffb9dd 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 4a3a0ec674c29a..72e71f0f709969 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-03 +date: 2023-07-04 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 6a39f28206866e..805fff1032625c 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-03 +date: 2023-07-04 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 e074cff2362f11..02574a65870d16 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-03 +date: 2023-07-04 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 c612dde0333f7c..10d1a665a71ac7 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-03 +date: 2023-07-04 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 0588bf88fca635..55c743966dff97 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-03 +date: 2023-07-04 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 6efe0f92bf6696..aded4faf4a8d22 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 4c9d14a51e53ad..7174d6886a240a 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 1b34b0a238b16b..c1a1e0e7e81769 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 42d7a07ebc6d50..d278a62e866909 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 a16555eb88815d..d5d4f8d961ad4f 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 22e457a4ebcf25..ae87a6216452b0 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-03 +date: 2023-07-04 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 2ec62c0170c423..a8ed779b2ecbc5 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 85b4f63b897b43..621b0bfebb6a99 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index f302e95a34e306..1e0d3e09b97a0e 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-03 +date: 2023-07-04 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 1d18012d3d06e7..c48dbe35421137 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-03 +date: 2023-07-04 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 ab0be9166607a5..dda91509afd319 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index dcfab0f732e8d5..6722f507bb655a 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-03 +date: 2023-07-04 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 8de49e90a12190..c1489e0cc7527f 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-03 +date: 2023-07-04 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 e96708f0d7deeb..b2f7f21f2f32bd 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index a698699823a0b8..9dfba7cb472a7c 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 6d31f2d49b3990..d3f5e78d048a1f 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-03 +date: 2023-07-04 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 8f18fcc306e781..5c0f830b0546c3 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index cb2c76074f3d9f..fb47d883a1cce9 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-03 +date: 2023-07-04 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 fbc5385de83c67..acced4c06f26ae 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index b10707fad90a5a..96e1bdc0aa3af2 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-03 +date: 2023-07-04 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 1a5fba09feb55b..46dad8550374e5 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-03 +date: 2023-07-04 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 a9e4810644cab9..ed5855fa5b5c79 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-03 +date: 2023-07-04 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 1a20fb5676183e..87cc3d28fa85d0 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-03 +date: 2023-07-04 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 d9b27d4ae9f9c4..3a09f1e40d2a31 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index f4386f74487ed7..124a5c2af1f1a0 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 7fe59eb4f55533..d64728cc9b7743 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-03 +date: 2023-07-04 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 6e4d33e4c9fd96..62d73252b3566d 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 b259e39c97e001..b64ddbbe16878a 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 3c3c34c2c8d237..169d5449fb4f8f 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-03 +date: 2023-07-04 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 ae75ed838a5fb4..952785cc2c82bc 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-03 +date: 2023-07-04 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 c469670905c4ef..c486fcc009901c 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-03 +date: 2023-07-04 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 239a7da01e2ba8..1f971f26a38b1f 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-03 +date: 2023-07-04 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 bdcac24385621d..eb8c16f7f01892 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-03 +date: 2023-07-04 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 286bafc4be8ae5..a876fa751d1e32 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 ced451bf44cf89..499d71419f5493 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-03 +date: 2023-07-04 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 134ded89594125..e3bb28518da107 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-03 +date: 2023-07-04 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 0f5e65cdca82d7..f0f7cdb095b8ba 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 243de472d8d169..965e0e6582db44 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-03 +date: 2023-07-04 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 20c322ba723417..e420ba825040dd 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-03 +date: 2023-07-04 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 86f58857a5b887..9b1257fc1aede7 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-03 +date: 2023-07-04 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 fe7aafdde510ae..1a37c07efd5778 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 9351ba6a822743..3bf2b2919ac108 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-03 +date: 2023-07-04 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 bed2d7ceb892a0..454b191ee9481d 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-03 +date: 2023-07-04 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 8864c0556d09c3..edcdff4b435264 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-03 +date: 2023-07-04 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 b771b4233129c8..7cb9ee7927615d 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 48dd017d21cd81..2af94107cbe1bc 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-03 +date: 2023-07-04 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 e017156293a510..ed5633cdb8ccc4 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-03 +date: 2023-07-04 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 ccd098e0cce091..d69dccadae991c 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-03 +date: 2023-07-04 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 b4937bf6ce69ec..f8cca2f10e94b3 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-03 +date: 2023-07-04 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 60bf1fc183a501..8dcac28c3bccc6 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index eb5254b30807c0..c2ca97af14a74f 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 3050200b77926f..5f1c36c201878d 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-03 +date: 2023-07-04 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 43a79bb804df9d..c66885af1fee0a 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-03 +date: 2023-07-04 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 365d3827958518..320ec0d432116a 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index e3f3bc58ab2e3e..5b7045a8d9f67e 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index bbf239c1a54f55..062ba46d30075f 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index c2ffcbecd4cbfb..a71ec43d86a100 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 0adfb9feb12003..f8a35e8e438bb1 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-03 +date: 2023-07-04 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 4318ee625009d0..aed464bdb5c766 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-03 +date: 2023-07-04 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 81ce0412163142..2e90743efdc207 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 c4513f09502731..fceef20809889c 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 8822612effecf1..6d3a402bf7d5c2 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-03 +date: 2023-07-04 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 b8e314847b7d20..d65184508e8298 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-03 +date: 2023-07-04 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 54002fd5e231aa..6336eb2c934832 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 4833a17b136461..de2e8566a93b2e 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 69bf1ba9714c0e..0711650d3ce910 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-03 +date: 2023-07-04 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 603f55f21452cf..cb38e442dde465 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-03 +date: 2023-07-04 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 9d35e93e55d588..9e0a8eceb50476 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-03 +date: 2023-07-04 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 aea6d9ca9c9441..b97db006473182 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-03 +date: 2023-07-04 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 73a24de7c582ed..9b3c6030a21c76 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-03 +date: 2023-07-04 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 8d4e9f253a7404..0de696514c58ca 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 3259792fa8a3e8..8c9583a40f46c0 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-03 +date: 2023-07-04 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 47995a01be9407..99b7dbc36a0691 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 94ce217ad52512..cefe9776163d16 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-03 +date: 2023-07-04 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 b4208bdb934ebf..158776fd378f5a 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 a60e61262df8ac..c736fbcbb0e4a9 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-03 +date: 2023-07-04 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 c34c48ba5a2c40..0e76431df5ff9f 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 5625062922f682..b7e573b04a18bb 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-03 +date: 2023-07-04 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 ae72e8f25ece2d..6e0970a5b0986e 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 cd7f501ef59bdd..24c3e122857c89 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-03 +date: 2023-07-04 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 fb7deaf5ef3df6..f024d4dc85e0bc 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-03 +date: 2023-07-04 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 bf6a8f93ab49e7..6724eb0caa46b3 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 43cfd25a4b3a9e..8bd4211647a70b 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 176160b9a96137..eb04cd0d0e7f9c 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-03 +date: 2023-07-04 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 7ec40f853f6234..fbb6a42471c952 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-03 +date: 2023-07-04 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 7606162f3db6b4..6694f28ec422b2 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 926fcbffc93e8e..758b8583895363 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-03 +date: 2023-07-04 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 e0e6eb404306db..1a564ec4b5f56a 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-03 +date: 2023-07-04 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 8ab5f358d30b96..792465bfb77348 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-03 +date: 2023-07-04 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 c40f63fd15ba6f..658b9eaec33b3d 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-03 +date: 2023-07-04 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 9c12c13d09d0e7..aa88d77fe73888 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-03 +date: 2023-07-04 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 b6b5e86ea67e02..5d0d84ee986631 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-03 +date: 2023-07-04 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 5bde2ad8365f7e..8f9700fc1cc019 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-03 +date: 2023-07-04 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 66f26519d1ab6a..44039e8d97ff6f 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 815a97c1dfffe1..84ffa7a7b6cc71 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-03 +date: 2023-07-04 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 9507e46669d509..49574d65569d35 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-03 +date: 2023-07-04 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 96b4e7cb42636f..867a30b1fde6db 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-03 +date: 2023-07-04 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 e10964750f681c..847ce7296955cc 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-03 +date: 2023-07-04 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 16e559f3cd948a..de2b67b4228fec 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 5386812542a2d4..e4ab96c56f975e 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-03 +date: 2023-07-04 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 d8c75ae07419a8..7e1e26e6cdfff9 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-03 +date: 2023-07-04 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 f37190ddc1e0f0..246752490577ad 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-03 +date: 2023-07-04 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 101042ea6c065d..8d47a3e0cf55a1 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index b4fcaea9aecd0f..4794a40ac7e2c7 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-03 +date: 2023-07-04 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 0bf8cb2d6e0393..cc6b8a96809070 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-03 +date: 2023-07-04 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 23560795684df9..dc397f344d19e2 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-03 +date: 2023-07-04 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 07cd8dbb085fff..26094e3a601e99 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-03 +date: 2023-07-04 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 c445dd46160a88..34523e2dff591b 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 5fbabd339666d3..cd932d9d6849e2 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index e8551189096d53..29541b076aea1f 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index fde8c7f3edeb7f..f09da062ff82e9 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-03 +date: 2023-07-04 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 d911e61e165d33..bf4ca46684de00 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-03 +date: 2023-07-04 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 d322837209b81b..d23d2f88684eb6 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-03 +date: 2023-07-04 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 d48c3e8f348b15..e6b5c16156af8b 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index d9e75497bad3f0..c465ac339244b2 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index ee7ba8f9abebf4..4164af8d68a6bb 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-03 +date: 2023-07-04 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 c5ff29da175eaf..a470737c641856 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-03 +date: 2023-07-04 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 28a0faf0b7a932..f140aac1e0ac7f 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-03 +date: 2023-07-04 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 ac0766b2756c19..b429f306614848 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index e151c4ab1fe459..54a301cad20ec6 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -3183,6 +3183,28 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "lens", + "id": "def-public.LensPublicStart.EditLensConfigPanelApi", + "type": "Function", + "tags": [ + "experimental" + ], + "label": "EditLensConfigPanelApi", + "description": [ + "\nReact component which can be used to embed a Lens Visualization Config Panel Component.\n\nThis API might undergo breaking changes even in minor versions.\n" + ], + "signature": [ + "() => Promise<", + "EditLensConfigPanelComponent", + ">" + ], + "path": "x-pack/plugins/lens/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.LensPublicStart.navigateToPrefilledEditor", @@ -5884,6 +5906,55 @@ ], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getCustomRemoveLayerText", + "type": "Function", + "tags": [], + "label": "getCustomRemoveLayerText", + "description": [ + "\nThis method is a clunky solution to the problem, but I'm banking on the confirm modal being removed\nwith undo/redo anyways" + ], + "signature": [ + "((layerId: string, state: T) => { title?: string | undefined; description?: string | undefined; } | undefined) | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getCustomRemoveLayerText.$1", + "type": "string", + "tags": [], + "label": "layerId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getCustomRemoveLayerText.$2", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [], + "signature": [ + "T" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.Visualization.getLayerType", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 0a1c3bae111042..374bac01d12b7d 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 622 | 0 | 527 | 58 | +| 626 | 0 | 529 | 59 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 9225b262dbe9f2..6083771d6cefea 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-03 +date: 2023-07-04 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 8de872753892ac..23419ef04718ad 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 047070d494b974..9cae783d8749ca 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index bbaaad6c45db51..38ce8789989f10 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 6f730945cc4ad1..68bfbf4918408f 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-03 +date: 2023-07-04 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 7dce59669f358a..6a1ed8133255c9 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-03 +date: 2023-07-04 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 254967debb785b..299ade9e71af26 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index a7c468d0acbdfd..16e46d18ead560 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index ca697dc1cc9ec2..4133dfde906efe 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-03 +date: 2023-07-04 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 f7df9e858e7687..97288b7b95e6d7 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-03 +date: 2023-07-04 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 40c69346b94456..530ffc11c7b280 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-03 +date: 2023-07-04 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 a381c4195c2d95..31f20cff3b9e47 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 72fe7e558062f4..53f267fa0477e4 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-03 +date: 2023-07-04 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 19b04cca8047c6..62e58fc3dc2cd6 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 7cccdcb4a8c98d..e7f3a62632dfaa 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-03 +date: 2023-07-04 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 45d01be1c6443f..ae30125da3bbd5 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-03 +date: 2023-07-04 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 0c3e65f60d78ae..4bdeb7094a5e8c 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 713bd0c62c1e21..aeab64a07c161d 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70960 | 544 | 60773 | 1410 | +| 70982 | 544 | 60792 | 1409 | ## Plugin Directory @@ -73,7 +73,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 10 | 0 | 10 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 115 | 3 | 111 | 3 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 234 | 30 | 234 | 4 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 236 | 30 | 236 | 4 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 116 | 0 | 116 | 11 | | | [@elastic/uptime](https://github.com/orgs/elastic/teams/uptime) | - | 141 | 1 | 141 | 14 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 | @@ -117,7 +117,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 609 | 3 | 416 | 9 | | | [@elastic/sec-cloudnative-integrations](https://github.com/orgs/elastic/teams/sec-cloudnative-integrations) | - | 5 | 0 | 5 | 1 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 622 | 0 | 527 | 58 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 626 | 0 | 529 | 59 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 8 | 0 | 8 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -155,7 +155,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 5 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 283 | 0 | 94 | 1 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 159 | 2 | 115 | 30 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 174 | 2 | 130 | 30 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | The core Serverless plugin, providing APIs to Serverless Project plugins. | 17 | 0 | 16 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Serverless customizations for observability. | 6 | 0 | 6 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Serverless customizations for search. | 6 | 0 | 6 | 0 | @@ -180,7 +180,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 547 | 11 | 521 | 50 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 144 | 2 | 102 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 206 | 0 | 140 | 9 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 52 | 0 | 23 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 53 | 0 | 23 | 2 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 137 | 2 | 100 | 20 | | upgradeAssistant | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | uptime | [@elastic/uptime](https://github.com/orgs/elastic/teams/uptime) | This plugin visualizes data from Heartbeat, and integrates with other Observability solutions. | 0 | 0 | 0 | 0 | @@ -410,7 +410,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 44 | 0 | 43 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 5 | 0 | 5 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 5 | 0 | 5 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 2 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 3 | 0 | 3 | 0 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 3 | 0 | 3 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 4 | 0 | 4 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 18f78a4ea24275..45a4cedff2e771 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-03 +date: 2023-07-04 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 ae042466b51ee0..44ddb29e58bb11 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index cdf5e69b2a7bfa..8151486dacb731 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-03 +date: 2023-07-04 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 bde1754b6d36b6..462db023b77c87 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 666e74dc24ee14..8c2c6bb90afea8 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 56ef3a6a083b19..ec70b4249c6d37 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-03 +date: 2023-07-04 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 0e2f5fa7c3ca24..ec82ecc994b0a1 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-03 +date: 2023-07-04 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 4b755988ed70fc..6de928bdb20374 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-03 +date: 2023-07-04 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 745cc7089a5f75..7c1875319e7390 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-03 +date: 2023-07-04 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 24f360208256f5..075b7695f7562e 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-03 +date: 2023-07-04 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 31ca9217da8fae..b67fe7179270e0 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-03 +date: 2023-07-04 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 e6213821875828..7a4501f01b6ba9 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-03 +date: 2023-07-04 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 ca16449b6e8bd6..f3f2361a11ecef 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-03 +date: 2023-07-04 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 ddd11a2636676e..a62e45f86b8880 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-03 +date: 2023-07-04 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 f273270e2ac701..494e76c3cf65ed 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-03 +date: 2023-07-04 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 eeecae3ee29db6..1368ee6cbb76d1 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-03 +date: 2023-07-04 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 57a720991cc393..c1d5c218edbf2b 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 226389e31e6b9f..072b0392348c3d 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -634,6 +634,230 @@ ], "functions": [], "interfaces": [ + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink", + "type": "Interface", + "tags": [], + "label": "NavigationLink", + "description": [], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.categories", + "type": "Object", + "tags": [], + "label": "categories", + "description": [], + "signature": [ + "readonly ", + { + "pluginId": "@kbn/security-solution-side-nav", + "scope": "common", + "docId": "kibKbnSecuritySolutionSideNavPluginApi", + "section": "def-common.LinkCategory", + "text": "LinkCategory" + }, + "<", + { + "pluginId": "securitySolution", + "scope": "common", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-common.SecurityPageName", + "text": "SecurityPageName" + }, + ">[] | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.disabled", + "type": "CompoundType", + "tags": [], + "label": "disabled", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.id", + "type": "Enum", + "tags": [], + "label": "id", + "description": [], + "signature": [ + { + "pluginId": "securitySolution", + "scope": "common", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-common.SecurityPageName", + "text": "SecurityPageName" + } + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.landingIcon", + "type": "CompoundType", + "tags": [], + "label": "landingIcon", + "description": [], + "signature": [ + "IconType", + " | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.landingImage", + "type": "string", + "tags": [], + "label": "landingImage", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.links", + "type": "Array", + "tags": [], + "label": "links", + "description": [], + "signature": [ + { + "pluginId": "securitySolution", + "scope": "public", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-public.NavigationLink", + "text": "NavigationLink" + }, + "[] | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.sideNavIcon", + "type": "CompoundType", + "tags": [], + "label": "sideNavIcon", + "description": [], + "signature": [ + "IconType", + " | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.skipUrlState", + "type": "CompoundType", + "tags": [], + "label": "skipUrlState", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.unauthorized", + "type": "CompoundType", + "tags": [], + "label": "unauthorized", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.isBeta", + "type": "CompoundType", + "tags": [], + "label": "isBeta", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.NavigationLink.betaOptions", + "type": "Object", + "tags": [], + "label": "betaOptions", + "description": [], + "signature": [ + "{ text: string; } | undefined" + ], + "path": "x-pack/plugins/security_solution/public/common/links/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "securitySolution", "id": "def-public.TimelineModel", @@ -1679,7 +1903,13 @@ "() => ", "Observable", "<", - "NavigationLink", + { + "pluginId": "securitySolution", + "scope": "public", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-public.NavigationLink", + "text": "NavigationLink" + }, "[]>" ], "path": "x-pack/plugins/security_solution/public/types.ts", @@ -1751,6 +1981,26 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.PluginStart.getBreadcrumbsNav$", + "type": "Function", + "tags": [], + "label": "getBreadcrumbsNav$", + "description": [], + "signature": [ + "() => ", + "Observable", + "<", + "BreadcrumbsNav", + ">" + ], + "path": "x-pack/plugins/security_solution/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "lifecycle": "start", diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 5a543aeb6ccf5a..7e53e37b906f84 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-solution](https://github.com/orgs/elastic/teams/secur | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 159 | 2 | 115 | 30 | +| 174 | 2 | 130 | 30 | ## Client diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 2442708db81a7f..41752046e3e9cb 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-03 +date: 2023-07-04 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 3c8c535fcfdf68..a598a191324439 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-03 +date: 2023-07-04 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 f9592d2e853098..a9e04358d9ee4c 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index f3c01d3ce60216..1d9f4d95772716 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index d2fde45c2ea697..d8872d809c0410 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-03 +date: 2023-07-04 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 7e960f24720514..e5a6e44040e8f1 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-03 +date: 2023-07-04 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 a0b069f790b58d..961944a41153d6 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-03 +date: 2023-07-04 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 6bd068ccfb441c..4f3d26414eeab0 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-03 +date: 2023-07-04 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 871a33484bd3d5..c19398e23ad5e2 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-03 +date: 2023-07-04 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 26dd11a63e5195..51df18fc67a84f 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-03 +date: 2023-07-04 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 06ea30b7ee13ab..4768f6de5c0ef2 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-03 +date: 2023-07-04 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 cbc4dcc9297069..3f755385b93f64 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-03 +date: 2023-07-04 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 a175d612a4e7b3..462e3f94420701 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-03 +date: 2023-07-04 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 18a82f1b71edf2..091a41712240d1 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-03 +date: 2023-07-04 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 79a860406a302a..b2382d3b1b3748 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-03 +date: 2023-07-04 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 50dc9a5316727a..fe1ce3fbd05763 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-03 +date: 2023-07-04 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 34394247d19ceb..bdacfa3854af80 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-03 +date: 2023-07-04 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 b0de367357e961..4ce06eb6edb6c2 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-03 +date: 2023-07-04 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 e7f9632f008611..50af3624ae3d87 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-03 +date: 2023-07-04 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 cbcb2011869cf8..5ddab506cf1ed0 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-03 +date: 2023-07-04 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 cad6c4aca0a0d7..01839cd14fff61 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-03 +date: 2023-07-04 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 2756ee9783a4fb..15f1205fe4731a 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.devdocs.json b/api_docs/unified_histogram.devdocs.json index 39768585d6aa50..5b5b6d13ef809e 100644 --- a/api_docs/unified_histogram.devdocs.json +++ b/api_docs/unified_histogram.devdocs.json @@ -468,7 +468,7 @@ }, " | undefined; } & Pick<", "UnifiedHistogramLayoutProps", - ", \"children\" | \"className\" | \"query\" | \"filters\" | \"columns\" | \"timeRange\" | \"services\" | \"dataView\" | \"relativeTimeRange\" | \"resizeRef\" | \"appendHitsCounter\"> & React.RefAttributes<", + ", \"children\" | \"className\" | \"query\" | \"filters\" | \"columns\" | \"timeRange\" | \"dataView\" | \"services\" | \"relativeTimeRange\" | \"resizeRef\" | \"appendHitsCounter\"> & React.RefAttributes<", { "pluginId": "unifiedHistogram", "scope": "public", @@ -892,6 +892,30 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "unifiedHistogram", + "id": "def-public.UnifiedHistogramState.lensTablesAdapter", + "type": "Object", + "tags": [], + "label": "lensTablesAdapter", + "description": [ + "\nThe current Lens request table" + ], + "signature": [ + "Record | undefined" + ], + "path": "src/plugins/unified_histogram/public/container/services/state_service.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "unifiedHistogram", "id": "def-public.UnifiedHistogramState.timeInterval", @@ -1154,7 +1178,7 @@ }, " | undefined; } & Pick<", "UnifiedHistogramLayoutProps", - ", \"children\" | \"className\" | \"query\" | \"filters\" | \"columns\" | \"timeRange\" | \"services\" | \"dataView\" | \"relativeTimeRange\" | \"resizeRef\" | \"appendHitsCounter\">" + ", \"children\" | \"className\" | \"query\" | \"filters\" | \"columns\" | \"timeRange\" | \"dataView\" | \"services\" | \"relativeTimeRange\" | \"resizeRef\" | \"appendHitsCounter\">" ], "path": "src/plugins/unified_histogram/public/container/container.tsx", "deprecated": false, diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index a937258c3abb8f..97d02724e627da 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.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 | |-------------------|-----------|------------------------|-----------------| -| 52 | 0 | 23 | 2 | +| 53 | 0 | 23 | 2 | ## Client diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 0fee1d0bb852af..93fc2b40d9f5c8 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-03 +date: 2023-07-04 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 4c7e6ec585f92f..e9a3fe63e40f59 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 52ea956af61732..8d01c6f9a2659b 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-03 +date: 2023-07-04 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 28fda03e4c7b04..75e9132aae821b 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-03 +date: 2023-07-04 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 35e49857602257..ae8e52c16d8980 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-03 +date: 2023-07-04 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 c46d34717bc975..a9a0ab3cf7a196 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-03 +date: 2023-07-04 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 963e602c35be5d..453adeccb22d72 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-03 +date: 2023-07-04 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 23040c12a4a17c..788974c703c980 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-03 +date: 2023-07-04 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 3ab7c3e7f5eb47..156f48abffdbdd 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-03 +date: 2023-07-04 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 7efbd34be21d7a..ab0cfaedd26d55 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-03 +date: 2023-07-04 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 74a5b9517cec4f..27d898573845b7 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-03 +date: 2023-07-04 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 20d1d82c6f814e..bfc80aa1193e36 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-03 +date: 2023-07-04 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 3446f042583a13..d5c328ee070e7b 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-03 +date: 2023-07-04 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 937a47e7be8c44..dca311a74be707 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-03 +date: 2023-07-04 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 e4ab55019da23f..49b2ee08dababb 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 4df3e47fce1b6a..66ffdc6dac8dad 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index b208bb40e55e7b..3b8f2591a11f08 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-03 +date: 2023-07-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From c1eacbabfe25bc841b57cb110ae8ead6bde46926 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Tue, 4 Jul 2023 09:00:43 +0200 Subject: [PATCH 40/98] [Infrastructure UI] Fix disk space usage chart Y axis (#161084) closes: [#161083](https://github.com/elastic/kibana/issues/161083) ## Summary This PR fixes the Disk Space Usage Y axis to display the percentage range from 0% to 100% image ### How to test - Start a local Kibana instance - Navigate to `Infrastructure` > `Hosts` - Check the Disk Space Usage chart in the metrics tab --- .../lens/formulas/host/disk_space_usage.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/common/visualizations/lens/formulas/host/disk_space_usage.ts b/x-pack/plugins/infra/public/common/visualizations/lens/formulas/host/disk_space_usage.ts index 20a0e1f2dc9836..9599e65d4de9b9 100644 --- a/x-pack/plugins/infra/public/common/visualizations/lens/formulas/host/disk_space_usage.ts +++ b/x-pack/plugins/infra/public/common/visualizations/lens/formulas/host/disk_space_usage.ts @@ -5,9 +5,19 @@ * 2.0. */ -import type { LensChartConfig } from '../../../types'; +import type { LensChartConfig, LensLineChartConfig } from '../../../types'; import { getFilters } from './utils'; +export const diskSpaceUsageLineChart: LensLineChartConfig = { + extraVisualizationState: { + yLeftExtent: { + mode: 'custom', + lowerBound: 0, + upperBound: 1, + }, + }, +}; + export const diskSpaceUsage: LensChartConfig = { title: 'Disk Space Usage', formula: { @@ -20,4 +30,5 @@ export const diskSpaceUsage: LensChartConfig = { }, }, getFilters, + lineChartConfig: diskSpaceUsageLineChart, }; From be4a4d74d3692b1ec41c5b884dcc630ac06cafb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Tue, 4 Jul 2023 09:04:27 +0200 Subject: [PATCH 41/98] [APM] Diagnostics: show both doc count and event count (#160973) Adds support for showing both doc count and event count for metrics, and improve number formatting for large numbers image --- .../utils/formatters/formatters.test.ts | 51 ++++++++++++- .../apm/common/utils/formatters/formatters.ts | 20 ++++++ .../app/diagnostics/apm_documents_tab.tsx | 66 ++++++++++++----- .../diagnostics/bundle/get_apm_events.ts | 34 ++++++--- .../tests/diagnostics/apm_events.spec.ts | 72 ++++++++++++++++++- 5 files changed, 213 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/apm/common/utils/formatters/formatters.test.ts b/x-pack/plugins/apm/common/utils/formatters/formatters.test.ts index f876b639c923dc..b04a746fa54371 100644 --- a/x-pack/plugins/apm/common/utils/formatters/formatters.test.ts +++ b/x-pack/plugins/apm/common/utils/formatters/formatters.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { asPercent, asDecimalOrInteger } from './formatters'; +import { asPercent, asDecimalOrInteger, asBigNumber } from './formatters'; describe('formatters', () => { describe('asPercent', () => { @@ -73,3 +73,52 @@ describe('formatters', () => { }); }); }); + +describe('asBigNumber', () => { + [ + { + input: 0, + output: '0', + }, + { + input: 999, + output: '999', + }, + { + input: 999.999, + output: '1,000', + }, + { + input: 449900, + output: '450k', + }, + { + input: 450000, + output: '450k', + }, + { + input: 450010, + output: '450k', + }, + { + input: 2.4991e7, + output: '25m', + }, + { + input: 9e9, + output: '9b', + }, + { + input: 1e12, + output: '1t', + }, + { + input: 1e15, + output: '1,000t', + }, + ].forEach(({ input, output }) => { + it(`${input} becomes ${output}`, () => { + expect(asBigNumber(input)).toBe(output); + }); + }); +}); diff --git a/x-pack/plugins/apm/common/utils/formatters/formatters.ts b/x-pack/plugins/apm/common/utils/formatters/formatters.ts index 67a259caa25341..5093f22ee7542c 100644 --- a/x-pack/plugins/apm/common/utils/formatters/formatters.ts +++ b/x-pack/plugins/apm/common/utils/formatters/formatters.ts @@ -62,3 +62,23 @@ export function asDecimalOrInteger(value: number, threshold = 10) { } return asDecimal(value); } + +export function asBigNumber(value: number): string { + if (value < 1e3) { + return asInteger(value); + } + + if (value < 1e6) { + return `${asInteger(value / 1e3)}k`; + } + + if (value < 1e9) { + return `${asInteger(value / 1e6)}m`; + } + + if (value < 1e12) { + return `${asInteger(value / 1e9)}b`; + } + + return `${asInteger(value / 1e12)}t`; +} diff --git a/x-pack/plugins/apm/public/components/app/diagnostics/apm_documents_tab.tsx b/x-pack/plugins/apm/public/components/app/diagnostics/apm_documents_tab.tsx index 9fcb9c10e148ff..d4776c8995c43b 100644 --- a/x-pack/plugins/apm/public/components/app/diagnostics/apm_documents_tab.tsx +++ b/x-pack/plugins/apm/public/components/app/diagnostics/apm_documents_tab.tsx @@ -10,26 +10,20 @@ import { EuiBasicTable, EuiBasicTableColumn, EuiSpacer, + EuiText, + EuiToolTip, } from '@elastic/eui'; import React, { useState, useMemo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { orderBy } from 'lodash'; import { useApmParams } from '../../../hooks/use_apm_params'; -import { asInteger } from '../../../../common/utils/formatters'; +import { asBigNumber, asInteger } from '../../../../common/utils/formatters'; import { APM_STATIC_DATA_VIEW_ID } from '../../../../common/data_view_constants'; import type { ApmEvent } from '../../../../server/routes/diagnostics/bundle/get_apm_events'; import { useDiagnosticsContext } from './context/use_diagnostics'; import { ApmPluginStartDeps } from '../../../plugin'; import { SearchBar } from '../../shared/search_bar/search_bar'; -function formatDocCount(count?: number) { - if (count === undefined) { - return '-'; - } - - return asInteger(count); -} - export function DiagnosticsApmDocuments() { const { diagnosticsBundle, isImported } = useDiagnosticsContext(); const { discover } = useKibana().services; @@ -46,7 +40,9 @@ export function DiagnosticsApmDocuments() { legacy === true && docCount === 0 && intervals && - Object.values(intervals).every((interval) => interval === 0); + Object.values(intervals).every( + (interval) => interval.eventDocCount === 0 + ); return !isLegacyAndUnused; }) ?? [] @@ -57,36 +53,40 @@ export function DiagnosticsApmDocuments() { { name: 'Name', field: 'name', - width: '40%', + width: '30%', }, { name: 'Doc count', field: 'docCount', - render: (_, { docCount }) => asInteger(docCount), + render: (_, { docCount }) => ( + +
{asBigNumber(docCount)}
+
+ ), sortable: true, }, { name: '1m', field: 'intervals.1m', render: (_, { intervals }) => { - const docCount = intervals?.['1m']; - return formatDocCount(docCount); + const interval = intervals?.['1m']; + return ; }, }, { name: '10m', field: 'intervals.10m', render: (_, { intervals }) => { - const docCount = intervals?.['10m']; - return formatDocCount(docCount); + const interval = intervals?.['10m']; + return ; }, }, { name: '60m', field: 'intervals.60m', render: (_, { intervals }) => { - const docCount = intervals?.['60m']; - return formatDocCount(docCount); + const interval = intervals?.['60m']; + return ; }, }, { @@ -159,3 +159,33 @@ export function DiagnosticsApmDocuments() { ); } + +function IntervalDocCount({ + interval, +}: { + interval?: { + metricDocCount: number; + eventDocCount: number; + }; +}) { + if (interval === undefined) { + return <>-; + } + + return ( + +
+ {asBigNumber(interval.metricDocCount)}  + + ({asBigNumber(interval.eventDocCount)} events) + +
+
+ ); +} diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts index 5c700d1b24945b..b1dd52e6307836 100644 --- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts +++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts @@ -13,6 +13,7 @@ import { METRICSET_NAME, METRICSET_INTERVAL, TRANSACTION_DURATION_SUMMARY, + INDEX, } from '../../../../common/es_fields/apm'; import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices'; import { getTypedSearch, TypedSearch } from '../create_typed_es_client'; @@ -24,7 +25,7 @@ export interface ApmEvent { kuery: string; index: string[]; docCount: number; - intervals?: Record; + intervals?: Record; } export async function getApmEvents({ @@ -93,19 +94,19 @@ export async function getApmEvents({ }), getEventWithMetricsetInterval({ ...commonProps, - name: 'Metric: Span breakdown', + name: 'Metric: Service summary', index: getApmIndexPatterns([apmIndices.metric]), kuery: mergeKueries( - `${PROCESSOR_EVENT}: "metric" AND ${METRICSET_NAME}: "span_breakdown"`, + `${PROCESSOR_EVENT}: "metric" AND ${METRICSET_NAME}: "service_summary"`, kuery ), }), - getEventWithMetricsetInterval({ + getEvent({ ...commonProps, - name: 'Metric: Service summary', + name: 'Metric: Span breakdown', index: getApmIndexPatterns([apmIndices.metric]), kuery: mergeKueries( - `${PROCESSOR_EVENT}: "metric" AND ${METRICSET_NAME}: "service_summary"`, + `${PROCESSOR_EVENT}: "metric" AND ${METRICSET_NAME}: "span_breakdown"`, kuery ), }), @@ -165,20 +166,33 @@ async function getEventWithMetricsetInterval({ size: 1000, field: METRICSET_INTERVAL, }, + aggs: { + metric_doc_count: { + value_count: { + field: INDEX, + }, + }, + }, }, }, }); - const defaultIntervals = { '1m': 0, '10m': 0, '60m': 0 }; + const defaultIntervals = { + '1m': { metricDocCount: 0, eventDocCount: 0 }, + '10m': { metricDocCount: 0, eventDocCount: 0 }, + '60m': { metricDocCount: 0, eventDocCount: 0 }, + }; const foundIntervals = res.aggregations?.metricset_intervals.buckets.reduce< - Record + Record >((acc, item) => { - acc[item.key] = item.doc_count; + acc[item.key] = { + metricDocCount: item.metric_doc_count.value, + eventDocCount: item.doc_count, + }; return acc; }, {}); const intervals = merge(defaultIntervals, foundIntervals); - return { legacy, name, diff --git a/x-pack/test/apm_api_integration/tests/diagnostics/apm_events.spec.ts b/x-pack/test/apm_api_integration/tests/diagnostics/apm_events.spec.ts index b09a37416024ff..e5c2d205f1405b 100644 --- a/x-pack/test/apm_api_integration/tests/diagnostics/apm_events.spec.ts +++ b/x-pack/test/apm_api_integration/tests/diagnostics/apm_events.spec.ts @@ -7,6 +7,8 @@ import expect from '@kbn/expect'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; +import { sumBy } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; export default function ApiTest({ getService }: FtrProviderContext) { @@ -88,15 +90,83 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'processor.event: "metric" AND metricset.name: "transaction" AND transaction.duration.summary :* ', docCount: 21, }, - { kuery: 'processor.event: "metric" AND metricset.name: "span_breakdown"', docCount: 15 }, { kuery: 'processor.event: "metric" AND metricset.name: "service_summary"', docCount: 21, }, + { kuery: 'processor.event: "metric" AND metricset.name: "span_breakdown"', docCount: 15 }, { kuery: 'processor.event: "transaction"', docCount: 450 }, ]); }); + describe('transactions', async () => { + let body: APIReturnType<'GET /internal/apm/diagnostics'>; + + const expectedDocCount = 450; + + beforeEach(async () => { + const res = await apmApiClient.adminUser({ + endpoint: 'GET /internal/apm/diagnostics', + params: { + query: { start: new Date(start).toISOString(), end: new Date(end).toISOString() }, + }, + }); + + body = res.body; + }); + + it('raw transaction events', () => { + const rawTransactions = body.apmEvents.find(({ kuery }) => + kuery.includes('processor.event: "transaction"') + ); + + expect(rawTransactions?.docCount).to.be(expectedDocCount); + }); + + it('transaction metrics', () => { + const transactionMetrics = body.apmEvents.find(({ kuery }) => + kuery.includes('metricset.name: "transaction"') + ); + + const intervalDocCount = sumBy( + Object.values(transactionMetrics?.intervals ?? {}), + ({ metricDocCount }) => metricDocCount + ); + expect(transactionMetrics?.docCount).to.be(intervalDocCount); + expect(transactionMetrics?.docCount).to.be(21); + + expect(transactionMetrics?.intervals).to.eql({ + '1m': { metricDocCount: 15, eventDocCount: expectedDocCount }, + '10m': { metricDocCount: 4, eventDocCount: expectedDocCount }, + '60m': { metricDocCount: 2, eventDocCount: expectedDocCount }, + }); + }); + + it('service transactions', () => { + const serviceTransactionMetrics = body.apmEvents.find(({ kuery }) => + kuery.includes('metricset.name: "service_transaction"') + ); + + const intervalDocCount = sumBy( + Object.values(serviceTransactionMetrics?.intervals ?? {}), + ({ metricDocCount }) => metricDocCount + ); + + expect(serviceTransactionMetrics?.docCount).to.be(intervalDocCount); + expect(serviceTransactionMetrics?.docCount).to.be(21); + + expect(serviceTransactionMetrics?.kuery).to.be( + 'processor.event: "metric" AND metricset.name: "service_transaction" AND transaction.duration.summary :* ' + ); + + expect(serviceTransactionMetrics?.intervals).to.eql({ + '1m': { metricDocCount: 15, eventDocCount: expectedDocCount }, + '10m': { metricDocCount: 4, eventDocCount: expectedDocCount }, + '60m': { metricDocCount: 2, eventDocCount: expectedDocCount }, + }); + }); + }); + it('returns zero doc_counts when filtering by a non-existing service', async () => { const { body } = await apmApiClient.adminUser({ endpoint: 'GET /internal/apm/diagnostics', From b9e2fdb6a50c8f8db3ea9ca5b9c5ecd30bf16e72 Mon Sep 17 00:00:00 2001 From: Marco Antonio Ghiani Date: Tue, 4 Jul 2023 09:10:05 +0200 Subject: [PATCH 42/98] [Logs+] Add All entry for DatasetSelector (#160971) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📓 Summary Closes #160146 This PR adds the entry to allow users to select a dataset that creates a `logs-*-*` dataview. Although the presentational and UX changes are minimal for the user, this work lays the foundation for [restoring the dataset selection from the URL](https://github.com/elastic/kibana/issues/160425) and for the [dataset multi-selection feature](https://github.com/elastic/observability-dev/issues/2744). The core changes for this implementation consist of: - Update DatasetSelector state machine to manage two parallel states: a `popover` one to manage the navigation on the selector and a `selection` state that handles the selection modes (currently only `all` and `single`, but ready to also implement `multi`) state-machine - DatasetSelector is now a controlled component regarding the selection value: it will react to the injected `datasetSelection` property, and notify the parent component of any change with the `onSelectionChange` event handler. This will allow us to always reinitialize the DatasetSelector state machine from the URL state and fall back to the chosen selection in case there is no one to restore. https://github.com/elastic/kibana/assets/34506779/4887b1d4-63ba-476b-a74f-5b4a9504f939 ## Architectural choices - The state machine will handle the two states in parallel such that we can switch to available selection modes depending on the interactions without clashing with the independent selector navigation. - The `DatasetSelection` data structure is now what represents the state selection in different modes. The three available modes (counting also `multi`, but not implemented yet), differs in mostly any aspect: - Internal data structure shape - DataViewSpecs composition - Payload to encode into a URL state - Extraction of the presentational values (title, icons, and with `multi` also the datasets which are currently selected) With all these differences but the same final purposes of creating an ad-hoc DataView and storing encoding a URL state to store, applying the concepts for the Strategy pattern seemed the most sensed option to me. This allows us to scale and add new selection modes (`multi`) respecting the existing strategies contract and encapsulating all the concerned transformations and parsing. Encoding and decoding of the Dataview id that will be used for restoring from the URL are already created and will be handy for the upcoming tasks. --------- Co-authored-by: Marco Antonio Ghiani Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../common/datasets/models/dataset.ts | 38 ++++- .../dataset_selector.stories.tsx | 21 +-- .../dataset_selector/dataset_selector.tsx | 52 +++--- .../state_machine/defaults.ts | 2 + .../state_machine/state_machine.ts | 148 ++++++++++-------- .../dataset_selector/state_machine/types.ts | 38 +++-- .../state_machine/use_dataset_selector.ts | 16 +- .../sub_components/datasets_popover.tsx | 16 +- .../integrations_list_status.tsx | 2 +- .../components/dataset_selector/types.ts | 11 +- .../components/dataset_selector/utils.tsx | 44 +++++- .../custom_dataset_selector.tsx | 42 +++-- .../all_dataset_selection.ts | 43 +++++ .../utils/dataset_selection/encoding.test.ts | 100 ++++++++++++ .../utils/dataset_selection/encoding.ts | 40 +++++ .../public/utils/dataset_selection/errors.ts | 14 ++ .../hydrate_dataset_selection.ts.ts | 19 +++ .../public/utils/dataset_selection/index.ts | 18 +++ .../single_dataset_selection.ts | 62 ++++++++ .../public/utils/dataset_selection/types.ts | 47 ++++++ .../discover_log_explorer/tsconfig.json | 1 + 21 files changed, 629 insertions(+), 145 deletions(-) create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/all_dataset_selection.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.test.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/errors.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/hydrate_dataset_selection.ts.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/index.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/single_dataset_selection.ts create mode 100644 x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/types.ts diff --git a/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts b/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts index 2fd4e883485986..38a6024de277c2 100644 --- a/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts +++ b/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts @@ -5,19 +5,26 @@ * 2.0. */ +import { IconType } from '@elastic/eui'; import { DataViewSpec } from '@kbn/data-views-plugin/common'; +import { IndexPattern } from '@kbn/io-ts-utils'; import { DatasetId, DatasetType, IntegrationType } from '../types'; type IntegrationBase = Pick; +interface DatasetDeps extends DatasetType { + iconType?: IconType; +} export class Dataset { id: DatasetId; + iconType?: IconType; name: DatasetType['name']; - title: DatasetType['title']; + title: string; parentIntegration?: IntegrationBase; - private constructor(dataset: DatasetType, parentIntegration?: IntegrationType) { + private constructor(dataset: DatasetDeps, parentIntegration?: IntegrationBase) { this.id = `dataset-${dataset.name}` as DatasetId; + this.iconType = dataset.iconType; this.name = dataset.name; this.title = dataset.title ?? dataset.name; this.parentIntegration = parentIntegration && { @@ -26,16 +33,37 @@ export class Dataset { }; } + getFullTitle(): string { + return this.parentIntegration?.name + ? `[${this.parentIntegration.name}] ${this.title}` + : this.title; + } + toDataviewSpec(): DataViewSpec { // Invert the property because the API returns the index pattern as `name` and a readable name as `title` return { id: this.id, - name: this.title, - title: this.name, + name: this.getFullTitle(), + title: this.name as string, }; } - public static create(dataset: DatasetType, parentIntegration?: IntegrationType) { + toPlain() { + return { + name: this.name, + title: this.title, + }; + } + + public static create(dataset: DatasetDeps, parentIntegration?: IntegrationBase) { return new Dataset(dataset, parentIntegration); } + + public static createAllLogsDataset() { + return new Dataset({ + name: 'logs-*-*' as IndexPattern, + title: 'All log datasets', + iconType: 'editorChecklist', + }); + } } diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx index ddd47351b99179..d96cdc07bd9bc1 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.stories.tsx @@ -13,11 +13,12 @@ import type { Meta, Story } from '@storybook/react'; import { IndexPattern } from '@kbn/io-ts-utils'; import { Dataset, Integration } from '../../../common/datasets'; import { DatasetSelector } from './dataset_selector'; +import { DatasetSelectorProps, DatasetsSelectorSearchParams } from './types'; import { - DatasetSelectionHandler, - DatasetSelectorProps, - DatasetsSelectorSearchParams, -} from './types'; + AllDatasetSelection, + DatasetSelection, + DatasetSelectionChange, +} from '../../utils/dataset_selection'; const meta: Meta = { component: DatasetSelector, @@ -37,7 +38,9 @@ const meta: Meta = { export default meta; const DatasetSelectorTemplate: Story = (args) => { - const [selected, setSelected] = useState(() => mockIntegrations[0].datasets[0]); + const [datasetSelection, setDatasetSelection] = useState(() => + AllDatasetSelection.create() + ); const [search, setSearch] = useState({ sortOrder: 'asc', @@ -51,8 +54,8 @@ const DatasetSelectorTemplate: Story = (args) => { } }; - const onDatasetSelected: DatasetSelectionHandler = (dataset) => { - setSelected(dataset); + const onSelectionChange: DatasetSelectionChange = (newSelection) => { + setDatasetSelection(newSelection); }; const filteredIntegrations = integrations.filter((integration) => @@ -72,14 +75,14 @@ const DatasetSelectorTemplate: Story = (args) => { diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.tsx index 19718e580d049b..aa1fb057bbd322 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/dataset_selector.tsx @@ -22,7 +22,12 @@ import { DatasetsPopover } from './sub_components/datasets_popover'; import { DatasetSkeleton } from './sub_components/datasets_skeleton'; import { SearchControls } from './sub_components/search_controls'; import { DatasetSelectorProps } from './types'; -import { buildIntegrationsTree } from './utils'; +import { + buildIntegrationsTree, + createAllLogDatasetsItem, + createUnmanagedDatasetsItem, + createIntegrationStatusItem, +} from './utils'; /** * Lazy load hidden components @@ -30,12 +35,11 @@ import { buildIntegrationsTree } from './utils'; const DatasetsList = dynamic(() => import('./sub_components/datasets_list'), { fallback: , }); -const IntegrationsListStatus = dynamic(() => import('./sub_components/integrations_list_status')); export function DatasetSelector({ datasets, datasetsError, - initialSelected, + datasetSelection, integrations, integrationsError, isLoadingIntegrations, @@ -46,7 +50,7 @@ export function DatasetSelector({ onIntegrationsSort, onIntegrationsStreamsSearch, onIntegrationsStreamsSort, - onDatasetSelected, + onSelectionChange, onStreamsEntryClick, onUnmanagedStreamsReload, onUnmanagedStreamsSearch, @@ -56,16 +60,16 @@ export function DatasetSelector({ isOpen, panelId, search, - selected, closePopover, changePanel, scrollToIntegrationsBottom, searchByName, + selectAllLogDataset, selectDataset, sortByOrder, togglePopover, } = useDatasetSelector({ - initialContext: { selected: initialSelected }, + initialContext: { selection: datasetSelection }, onIntegrationsLoadMore, onIntegrationsReload, onIntegrationsSearch, @@ -75,32 +79,26 @@ export function DatasetSelector({ onUnmanagedStreamsSearch, onUnmanagedStreamsSort, onUnmanagedStreamsReload, - onDatasetSelected, + onSelectionChange, }); const [setSpyRef] = useIntersectionRef({ onIntersecting: scrollToIntegrationsBottom }); const { items: integrationItems, panels: integrationPanels } = useMemo(() => { - const datasetsItem = { - name: uncategorizedLabel, - onClick: onStreamsEntryClick, - panel: UNMANAGED_STREAMS_PANEL_ID, - }; - - const createIntegrationStatusItem = () => ({ - disabled: true, - name: ( - - ), - }); + const allLogDatasetsItem = createAllLogDatasetsItem({ onClick: selectAllLogDataset }); + const unmanagedDatasetsItem = createUnmanagedDatasetsItem({ onClick: onStreamsEntryClick }); if (!integrations || integrations.length === 0) { return { - items: [datasetsItem, createIntegrationStatusItem()], + items: [ + allLogDatasetsItem, + unmanagedDatasetsItem, + createIntegrationStatusItem({ + error: integrationsError, + integrations, + onRetry: onIntegrationsReload, + }), + ], panels: [], }; } @@ -112,12 +110,13 @@ export function DatasetSelector({ }); return { - items: [datasetsItem, ...items], + items: [allLogDatasetsItem, unmanagedDatasetsItem, ...items], panels, }; }, [ integrations, integrationsError, + selectAllLogDataset, selectDataset, onIntegrationsReload, onStreamsEntryClick, @@ -150,7 +149,7 @@ export function DatasetSelector({ return ( ); diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/defaults.ts b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/defaults.ts index a0fce7ed567304..a818c6645bda78 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/defaults.ts +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/defaults.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { AllDatasetSelection } from '../../../utils/dataset_selection'; import { HashedCache } from '../../../../common/hashed_cache'; import { INTEGRATION_PANEL_ID } from '../constants'; import { DatasetsSelectorSearchParams } from '../types'; @@ -16,6 +17,7 @@ export const defaultSearch: DatasetsSelectorSearchParams = { }; export const DEFAULT_CONTEXT: DefaultDatasetsSelectorContext = { + selection: AllDatasetSelection.create(), searchCache: new HashedCache(), panelId: INTEGRATION_PANEL_ID, search: defaultSearch, diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/state_machine.ts b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/state_machine.ts index a315e4925726df..aea09e7c6f2e76 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/state_machine.ts +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/state_machine.ts @@ -6,6 +6,7 @@ */ import { actions, assign, createMachine, raise } from 'xstate'; +import { AllDatasetSelection, SingleDatasetSelection } from '../../../utils/dataset_selection'; import { UNMANAGED_STREAMS_PANEL_ID } from '../constants'; import { defaultSearch, DEFAULT_CONTEXT } from './defaults'; import { @@ -19,83 +20,107 @@ import { export const createPureDatasetsSelectorStateMachine = ( initialContext: Partial = DEFAULT_CONTEXT ) => - /** @xstate-layout N4IgpgJg5mDOIC5QBECGAXVsztgZTABswBjdAewCcA6Ew87CAYgBUB5AcQ4BkBRAbQAMAXUSgADgwCW6KeQB2YkAA9EAVgBMAGhABPRAA4AjNTWDzggJxqjAFgODbANicBfVzrSZsuAsTJU1OTiYPJMAMLcbHgCIkqSsDJyikgqiEZGLtTO9hrWBgZqThpqOvoItraC1EYA7E6CdgYAzIJFghrN7p4YWDj4RKQUNMGhrJw8saKpCUkKSqoIGQ3ULrWWjU6WzbW2dmXqzbbZarUaxmZqzoJuHiBefb6DASMh8tSEUrCy8lAAkvJ0GAoJQMMlYBEABIAQQAchxeAB9AAKcN43CE0wk0lk81Si1szRMLTU2xsTk0RksBgOCEstQM1B2Ng6jlsGnOtW6916PgG-mGQTeHy+P3+gOBoNx8gh4Rh8KRqNh6P4RixIFm0oWiEJxOapP1mUp1NpRUs1BuGlqzX1DnaGm5Dz5fiGgVG70+3ykvwBQJBYIUELw4QASmxuNxEexEX9YSxeBwQ9CWH82LC8IiAEJsFjsACymPiOOS2oQBlqFosVerzVp9Q0NVqVJtnWpxiMjt5-RdLyFoRFXp9Ev90qDvGhIblWYAmojYdC81Mi4ktfj0ldVpY7OZ2fTbKcaXpEE5moz6mpSQyjESbAZO95u89Be6B2LfZKAzKmHg2CGWDPEV-ZBeBDQsZmLPFQEWTIGxaDRBCJKwMlOIxTSMNQmVJDRilPJx2Ww+9Hn5V1Xn7T032HKVkjwdBKDAVAAFtZXlBEUTRDE4nAlcSzXBBigwqk1COWp1gMSx6UPcpb1MYomy2NoXEI50nzdYVyO9cU-SohQaLoxixz4cJ-2QZNoRiFgwOxbjILSJZr0ZJx1kcm1TyKEpaQpBtLXqLZWmaJwOzuJ1HwFVSyNFDT3xHajaPopjv3HSdIQA+dF0sjUIJSKDDCqahsKKIwEJbIw8lpZpLGOdCT1k7YGXLLogq7J5QtIj0IqHLTP10uKg1-f9M1nICQPSzUeOyst7ErcrCo6ToOUsWkrWqWozA6a1HLaCqGp6B9mpIvs2sHKAAFV5AY1B5FQGAIG6-SoThVilRVTirLmLLbP4mprGE0TxIZWlLCtahyzMQp-O2c5bh2oie2fNT2pOs6LquyBbvimJDOM0zzJGzLSwyU9Vic60bUKfiAcqbINCpdkXBaOxbCUkL9pfdTflO87LuutGxwnKcBrnBcly4t7SwMXLGgK6m5v82paQcZpsicMTsLsalKi5RrduI3tWYRjnke52K7p-P8AKG0CXoy6z3sWcWKwMeCrWw2oOjpjyHAtWSyfQsw8ncO55HICA4CUYK9peZdRd4gBaRlxITxPE7OWkY4wpPHEKQSjiZiPBToBhICj1dxuvQkvqEuoxNw6wPMcGSrT9i9rihnltdhsL3tGmzFnKytqwH2sjyWFo8tWq1Zc2wlc51uH+wAC1FYuxtswqnAb+w6lPHYjEd2l92OfVtgCtp1gvQLoeUlqDtfSLKM-eARZL1ebg34xrRaJtxflk9VhKRwSpbAZCJGeHdWq3w6h+aUPNl490MIICslhlZnAaMsfUpoOQNy2I7eCt4L5txhipcBbNEacxRjdY2TFYG23gYg5B2FGiZHQcPbYxIVo3DpnsAwFIA6uCAA */ + /** @xstate-layout N4IgpgJg5mDOIC5QBECGAXVsztgZTABswBjdAewCcA6AB3PoDcwaTDzsIBiAFQHkA4gIAyAUQDaABgC6iUPVgBLdIvIA7OSAAeiALQBmAKzUALAEZDAdgBslk4ckAmEwA5HhkwBoQAT0T6LakdHFzMLMLN9dzsAXxjvNExsXAJiMio6BnJmGgYwNS4AYWE+PAkZTQVlVQ0kbUQzSQBOY0szd31zE0lrJutrbz8EVxdTM0solya3YP64hIwsHHwiUgoaeiYWajyC-iExKVk6qpV1TR0ERr7qa0cwx0lJE0tLF0l9QcQTbtveyXa1gB+j6LnmIESSxSq3SGyyOR2tHy1EIilgKjUUAAkmp0GAoJQMDVYEUABIAQQAcgJRAB9AAKVNEwiOlQ41XOdUu+iit0MhjMtgsnQFjgGvkQTQBQV6YXMhncj0c4MhyRWaXWmS2uSRahRaIx2Nx+MJZzUJMKFOpdMZlOZ4jMx3k7LNF0QhiBpn6Hh+7kMTU+EoQ70s1EkHmBjiM+ksTWV8QhizVqTWGU22W2u316MUmJxeIJRPUJLwhQASnxhMJafxaVjKTxRAIy+SeFi+JS8LSAEJ8Hj8ACyrJOLpqboQujMJn01Bad2e7m6Fi8QcsYuoCpMTXGTl9thVSeWKdhWozOuRqJzeeNhbNJdE5LLlp7AE1aZTyQPyk6QKcx1y9DMJomlnBxHDjacWhcCZLC+YN3GoSwekkN4106awpgPJIjxhTV0wRLNL0NfMTSLc0uDwPgyx4V9aSo5BRDLYdnSUV0AInMJjHuCYxSaJDgiQww4MaZ5Z3MZxXHcFwFUsLCoXVVM4W1RELwNXMjQLU1iQo5lREKGjySrWkSgELtkFbckyh4Zjf1HTlQEuRobDDGwjG3cwzCmcUhhcEEgj6R4XGsF5DDk5NcLTeFM11bNiJvLT1DwdBKDAVAAFsLStGkGSZFkKhHVj-wc-wFWoRoRRE-QAUMFw4N6UNrE8qwWgmHkarCnCNUi5TCLU69NLIpKUvS+9H2fbs3w-L8bL-ez6gQBwTFMKMozXUIPSqoSgy3JbBOA-R-iicZQoTVVOsU08CJioj1JI28aiG1KMooqiaImuiywYpj8pYjlamKhBYyW7pmmeMIWhMZw4J2xDkMkKYtzCeGOuhLqlLPFS9Ru-rSLNR6Rp0sR9NpcyeEs0RrJ+2zCrmxz4eMH4mheYCXmeWqgwwyRqCCtdGtsD0ejBU7D1Ri78Oi1SrygABVNQ0tQNRUBgCB8eey0qWy217Sp2b-vmzpHGoEE7n5qMQ1goNGnMI2mYO6YpJklGFJPcXzyxvqZblhWlcgVXRqfUlaKm782RpvXLhko2nPpxwkMFQMhk44wHHCaN-T4kwnePPCord2L1Nl+XFeVv2Xuo2j6MYma7PDxA3FGPjt1trcmYmYSLGT6rIkMNyM6ziL0auyXDUL72S+Sp77yJmjSfJymf118cnOsMNIZMDC1wcBUtsT54QKlF4tysRH1-7tHqGwDUagv9TiEJvSDKMkyzIsqzq7D8cMKCbpIOcRqgpQnBAUG43BAm6Hbe4LghYLGwqLE8l81jXyUJiO+ZRp4k1fhTd+f1xy6D-rDDwrVRS2G8noA6MpBRAjXNuAB8YYHyWzhkBBZBr6oEIIQe+xNZ5vx1jXcc25uYBACL5VwUppgJz0K8bm1gapRgBFOeucQExqHIBAOAmgzpwPWKHHB7EDDTlAk4CCIIap2Dgng0qQVZEfGnAEV40DEywOdjnbUOi2IAzwS0Qx4FnAmOgiuIYAlEIhGXLxHunQz5i1ztQNgHBIBuKKvNSIRhubTFavYSIHw4IxlDN0f+bwarhkaNYSJLtom7ASbTPQzhQwtCMb4qCMFoY9GkeBKc0xXABBKcLJxjDB4Sz1AACwNJU2uE4lpPHlL5HofRmqOGhkzI2dxtwHQcHYbcpSXEY16lLO6CVzSjKXlzIw9gpRVTuCCdmPlgE2G3FOCwionCbO6ts66Hs9mDQniNQ57F-SG3kSEIK3EXD2DqlORCnk2gRBsSEZ5-S87Y09kXH2KsvkZR+QDGqS0oFM39HYFOUxhJPC5j-dZx93LdPoeFc+zD3HU10R48Cu1wwvDaoCGwATAIyKWbIwUrwQawp6QwgeF9cJINvmADF81dC2EQrGEFTgeRFLaHBN4phtz+k2h6DCvk4WiqvuoagbDCBSu5NymMwV3BOCsDGTlwYubAQsAGcM2qoH6CUTEIAA */ createMachine( { context: { ...DEFAULT_CONTEXT, ...initialContext }, preserveActionOrder: true, predictableActionArguments: true, id: 'DatasetsSelector', - initial: 'closed', + type: 'parallel', states: { - closed: { - id: 'closed', - on: { - TOGGLE: 'open.hist', - }, - }, - open: { - initial: 'listingIntegrations', - on: { - CLOSE: 'closed', - TOGGLE: 'closed', - }, + popover: { + initial: 'closed', states: { - hist: { - type: 'history', + closed: { + id: 'closed', + on: { + TOGGLE: 'open.hist', + }, }, - listingIntegrations: { - entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + open: { + initial: 'listingIntegrations', on: { - CHANGE_PANEL: [ - { - cond: 'isUnmanagedStreamsId', - target: 'listingUnmanagedStreams', - }, - { - target: 'listingIntegrationStreams', + CLOSE: 'closed', + TOGGLE: 'closed', + }, + states: { + hist: { + type: 'history', + }, + listingIntegrations: { + entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + on: { + CHANGE_PANEL: [ + { + cond: 'isUnmanagedStreamsId', + target: 'listingUnmanagedStreams', + }, + { + target: 'listingIntegrationStreams', + }, + ], + SCROLL_TO_INTEGRATIONS_BOTTOM: { + actions: 'loadMoreIntegrations', + }, + SEARCH_BY_NAME: { + actions: ['storeSearch', 'searchIntegrations'], + }, + SORT_BY_ORDER: { + actions: ['storeSearch', 'sortIntegrations'], + }, + SELECT_ALL_LOGS_DATASET: '#closed', }, - ], - SCROLL_TO_INTEGRATIONS_BOTTOM: { - actions: 'loadMoreIntegrations', }, - SEARCH_BY_NAME: { - actions: ['storeSearch', 'searchIntegrations'], + listingIntegrationStreams: { + entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + on: { + CHANGE_PANEL: 'listingIntegrations', + SEARCH_BY_NAME: { + actions: ['storeSearch', 'searchIntegrationsStreams'], + }, + SORT_BY_ORDER: { + actions: ['storeSearch', 'sortIntegrationsStreams'], + }, + SELECT_DATASET: '#closed', + }, }, - SORT_BY_ORDER: { - actions: ['storeSearch', 'sortIntegrations'], + listingUnmanagedStreams: { + entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + on: { + CHANGE_PANEL: 'listingIntegrations', + SEARCH_BY_NAME: { + actions: ['storeSearch', 'searchUnmanagedStreams'], + }, + SORT_BY_ORDER: { + actions: ['storeSearch', 'sortUnmanagedStreams'], + }, + SELECT_DATASET: '#closed', + }, }, }, }, - listingIntegrationStreams: { - entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + }, + }, + selection: { + initial: 'single', + states: { + single: { on: { - CHANGE_PANEL: 'listingIntegrations', - SELECT_DATASET: { - actions: ['storeSelected', 'selectStream'], - target: '#closed', - }, - SEARCH_BY_NAME: { - actions: ['storeSearch', 'searchIntegrationsStreams'], + SELECT_ALL_LOGS_DATASET: { + actions: ['storeAllSelection', 'notifySelectionChanged'], + target: 'all', }, - SORT_BY_ORDER: { - actions: ['storeSearch', 'sortIntegrationsStreams'], + SELECT_DATASET: { + actions: ['storeSingleSelection', 'notifySelectionChanged'], }, }, }, - listingUnmanagedStreams: { - entry: ['storePanelId', 'retrieveSearchFromCache', 'maybeRestoreSearchResult'], + all: { on: { - CHANGE_PANEL: 'listingIntegrations', SELECT_DATASET: { - actions: ['storeSelected', 'selectStream'], - target: '#closed', - }, - SEARCH_BY_NAME: { - actions: ['storeSearch', 'searchUnmanagedStreams'], - }, - SORT_BY_ORDER: { - actions: ['storeSearch', 'sortUnmanagedStreams'], + actions: ['storeSingleSelection', 'notifySelectionChanged'], + target: 'single', }, }, }, @@ -118,8 +143,11 @@ export const createPureDatasetsSelectorStateMachine = ( } return {}; }), - storeSelected: assign((_context, event) => - 'dataset' in event ? { selected: event.dataset } : {} + storeAllSelection: assign((_context) => ({ + selection: AllDatasetSelection.create(), + })), + storeSingleSelection: assign((_context, event) => + 'dataset' in event ? { selection: SingleDatasetSelection.create(event.dataset) } : {} ), retrieveSearchFromCache: assign((context, event) => 'panelId' in event @@ -150,15 +178,13 @@ export const createDatasetsSelectorStateMachine = ({ onIntegrationsStreamsSort, onUnmanagedStreamsSearch, onUnmanagedStreamsSort, - onDatasetSelected, + onSelectionChange, onUnmanagedStreamsReload, }: DatasetsSelectorStateMachineDependencies) => createPureDatasetsSelectorStateMachine(initialContext).withConfig({ actions: { - selectStream: (_context, event) => { - if ('dataset' in event) { - return onDatasetSelected(event.dataset); - } + notifySelectionChanged: (context) => { + return onSelectionChange(context.selection); }, loadMoreIntegrations: onIntegrationsLoadMore, relaodIntegrations: onIntegrationsReload, diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/types.ts b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/types.ts index 4dc717acdfc4b0..17e526aea87f94 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/types.ts +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/types.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { DatasetSelection, DatasetSelectionChange } from '../../../utils/dataset_selection'; import { Dataset } from '../../../../common/datasets/models/dataset'; import { ReloadDatasets, SearchDatasets } from '../../../hooks/use_datasets'; import { @@ -12,10 +13,10 @@ import { SearchIntegrations, } from '../../../hooks/use_integrations'; import type { IHashedCache } from '../../../../common/hashed_cache'; -import { DatasetSelectionHandler, DatasetsSelectorSearchParams, PanelId } from '../types'; +import { DatasetsSelectorSearchParams, PanelId } from '../types'; export interface DefaultDatasetsSelectorContext { - selected?: Dataset; + selection: DatasetSelection; panelId: PanelId; searchCache: IHashedCache; search: DatasetsSelectorSearchParams; @@ -23,27 +24,43 @@ export interface DefaultDatasetsSelectorContext { export type DatasetsSelectorTypestate = | { - value: 'closed'; + value: 'popover'; context: DefaultDatasetsSelectorContext; } | { - value: 'open'; + value: 'popover.closed'; context: DefaultDatasetsSelectorContext; } | { - value: { open: 'hist' }; + value: 'popover.open'; context: DefaultDatasetsSelectorContext; } | { - value: { open: 'listingIntegrations' }; + value: 'popover.open.hist'; context: DefaultDatasetsSelectorContext; } | { - value: { open: 'listingIntegrationStreams' }; + value: 'popover.open.listingIntegrations'; context: DefaultDatasetsSelectorContext; } | { - value: { open: 'listingUnmanagedStreams' }; + value: 'popover.open.listingIntegrationStreams'; + context: DefaultDatasetsSelectorContext; + } + | { + value: 'popover.open.listingUnmanagedStreams'; + context: DefaultDatasetsSelectorContext; + } + | { + value: 'selection'; + context: DefaultDatasetsSelectorContext; + } + | { + value: 'selection.single'; + context: DefaultDatasetsSelectorContext; + } + | { + value: 'selection.all'; context: DefaultDatasetsSelectorContext; }; @@ -64,6 +81,9 @@ export type DatasetsSelectorEvent = type: 'SELECT_DATASET'; dataset: Dataset; } + | { + type: 'SELECT_ALL_LOGS_DATASET'; + } | { type: 'SCROLL_TO_INTEGRATIONS_BOTTOM'; } @@ -84,7 +104,7 @@ export interface DatasetsSelectorStateMachineDependencies { onIntegrationsSort: SearchIntegrations; onIntegrationsStreamsSearch: SearchIntegrations; onIntegrationsStreamsSort: SearchIntegrations; - onDatasetSelected: DatasetSelectionHandler; + onSelectionChange: DatasetSelectionChange; onUnmanagedStreamsReload: ReloadDatasets; onUnmanagedStreamsSearch: SearchDatasets; onUnmanagedStreamsSort: SearchDatasets; diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/use_dataset_selector.ts b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/use_dataset_selector.ts index d2556809302e88..ec6090cd29edd7 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/use_dataset_selector.ts +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/state_machine/use_dataset_selector.ts @@ -24,9 +24,9 @@ export const useDatasetSelector = ({ onIntegrationsSort, onIntegrationsStreamsSearch, onIntegrationsStreamsSort, + onSelectionChange, onUnmanagedStreamsSearch, onUnmanagedStreamsSort, - onDatasetSelected, onUnmanagedStreamsReload, }: DatasetsSelectorStateMachineDependencies) => { const datasetsSelectorStateService = useInterpret(() => @@ -38,18 +38,19 @@ export const useDatasetSelector = ({ onIntegrationsSort, onIntegrationsStreamsSearch, onIntegrationsStreamsSort, + onSelectionChange, onUnmanagedStreamsSearch, onUnmanagedStreamsSort, - onDatasetSelected, onUnmanagedStreamsReload, }) ); - const isOpen = useSelector(datasetsSelectorStateService, (state) => state.matches('open')); + const isOpen = useSelector(datasetsSelectorStateService, (state) => + state.matches('popover.open') + ); const panelId = useSelector(datasetsSelectorStateService, (state) => state.context.panelId); const search = useSelector(datasetsSelectorStateService, (state) => state.context.search); - const selected = useSelector(datasetsSelectorStateService, (state) => state.context.selected); const changePanel = useCallback( (panelDetails) => @@ -70,6 +71,11 @@ export const useDatasetSelector = ({ [datasetsSelectorStateService] ); + const selectAllLogDataset = useCallback( + () => datasetsSelectorStateService.send({ type: 'SELECT_ALL_LOGS_DATASET' }), + [datasetsSelectorStateService] + ); + const selectDataset = useCallback( (dataset) => datasetsSelectorStateService.send({ type: 'SELECT_DATASET', dataset }), [datasetsSelectorStateService] @@ -95,12 +101,12 @@ export const useDatasetSelector = ({ isOpen, panelId, search, - selected, // Actions closePopover, changePanel, scrollToIntegrationsBottom, searchByName, + selectAllLogDataset, selectDataset, sortByOrder, togglePopover, diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx index 333fe27166f3ce..0ed65b4e50d8b1 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiButton, EuiHorizontalRule, + EuiIcon, EuiPanel, EuiPopover, EuiPopoverProps, @@ -17,7 +18,7 @@ import { } from '@elastic/eui'; import styled from '@emotion/styled'; import { PackageIcon } from '@kbn/fleet-plugin/public'; -import { Dataset } from '../../../../common/datasets/models/dataset'; +import { DatasetSelection } from '../../../utils/dataset_selection'; import { DATA_VIEW_POPOVER_CONTENT_WIDTH, POPOVER_ID, selectDatasetLabel } from '../constants'; import { getPopoverButtonStyles } from '../utils'; @@ -25,16 +26,17 @@ const panelStyle = { width: DATA_VIEW_POPOVER_CONTENT_WIDTH }; interface DatasetsPopoverProps extends Omit { children: React.ReactNode; onClick: () => void; - selected?: Dataset; + selection: DatasetSelection['selection']; } export const DatasetsPopover = ({ children, onClick, - selected, + selection, ...props }: DatasetsPopoverProps) => { - const { title, parentIntegration } = selected ?? {}; + const { iconType, parentIntegration } = selection.dataset; + const title = selection.dataset.getFullTitle(); const isMobile = useIsWithinBreakpoints(['xs', 's']); const buttonStyles = getPopoverButtonStyles({ fullWidth: isMobile }); @@ -52,14 +54,16 @@ export const DatasetsPopover = ({ onClick={onClick} fullWidth={isMobile} > - {hasIntegration && ( + {iconType ? ( + + ) : hasIntegration ? ( - )} + ) : null} {title} } diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/integrations_list_status.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/integrations_list_status.tsx index 84f5c6cb418de8..418ccbefffd000 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/integrations_list_status.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/integrations_list_status.tsx @@ -17,7 +17,7 @@ import { noIntegrationsLabel, } from '../constants'; -interface IntegrationsListStatusProps { +export interface IntegrationsListStatusProps { integrations: Integration[] | null; error: Error | null; onRetry: ReloadIntegrations; diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/types.ts b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/types.ts index 970c8d60ae274f..50cbcf6c1c5bac 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/types.ts +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/types.ts @@ -15,18 +15,19 @@ import { SearchIntegrations, } from '../../hooks/use_integrations'; import { INTEGRATION_PANEL_ID, UNMANAGED_STREAMS_PANEL_ID } from './constants'; +import type { DatasetSelection, DatasetSelectionChange } from '../../utils/dataset_selection'; export interface DatasetSelectorProps { /* The generic data stream list */ datasets: Dataset[] | null; /* Any error occurred to show when the user preview the generic data streams */ datasetsError?: Error | null; - /* The integrations list, each integration includes its data streams */ - initialSelected: Dataset; + /* The current selection instance */ + datasetSelection: DatasetSelection; /* The integrations list, each integration includes its data streams */ integrations: Integration[] | null; /* Any error occurred to show when the user preview the integrations */ - integrationsError?: Error | null; + integrationsError: Error | null; /* Flags for loading/searching integrations or data streams*/ isLoadingIntegrations: boolean; isLoadingStreams: boolean; @@ -45,8 +46,8 @@ export interface DatasetSelectorProps { onUnmanagedStreamsReload: ReloadDatasets; /* Triggered when the uncategorized streams entry is selected */ onStreamsEntryClick: LoadDatasets; - /* Triggered when a data stream entry is selected */ - onDatasetSelected: DatasetSelectionHandler; + /* Triggered when the selection is updated */ + onSelectionChange: DatasetSelectionChange; } export type PanelId = diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx index d6f563ace89074..b135c0c22202b8 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx @@ -6,11 +6,24 @@ */ import React, { RefCallback } from 'react'; -import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui'; +import { + EuiContextMenuPanelDescriptor, + EuiContextMenuPanelItemDescriptor, + EuiIcon, +} from '@elastic/eui'; import { PackageIcon } from '@kbn/fleet-plugin/public'; -import { Integration } from '../../../common/datasets'; -import { DATA_VIEW_POPOVER_CONTENT_WIDTH } from './constants'; +import { Dataset, Integration } from '../../../common/datasets'; +import { + DATA_VIEW_POPOVER_CONTENT_WIDTH, + uncategorizedLabel, + UNMANAGED_STREAMS_PANEL_ID, +} from './constants'; import { DatasetSelectionHandler } from './types'; +import { LoadDatasets } from '../../hooks/use_datasets'; +import { dynamic } from '../../utils/dynamic'; +import type { IntegrationsListStatusProps } from './sub_components/integrations_list_status'; + +const IntegrationsListStatus = dynamic(() => import('./sub_components/integrations_list_status')); export const getPopoverButtonStyles = ({ fullWidth }: { fullWidth?: boolean }) => ({ maxWidth: fullWidth ? undefined : DATA_VIEW_POPOVER_CONTENT_WIDTH, @@ -67,3 +80,28 @@ export const buildIntegrationsTree = ({ { items: [], panels: [] } ); }; + +export const createAllLogDatasetsItem = ({ onClick }: { onClick(): void }) => { + const allLogDataset = Dataset.createAllLogsDataset(); + return { + name: allLogDataset.title, + icon: allLogDataset.iconType && , + onClick, + }; +}; + +export const createUnmanagedDatasetsItem = ({ onClick }: { onClick: LoadDatasets }) => { + return { + name: uncategorizedLabel, + icon: , + onClick, + panel: UNMANAGED_STREAMS_PANEL_ID, + }; +}; + +export const createIntegrationStatusItem = (props: IntegrationsListStatusProps) => { + return { + disabled: true, + name: , + }; +}; diff --git a/x-pack/plugins/discover_log_explorer/public/customizations/custom_dataset_selector.tsx b/x-pack/plugins/discover_log_explorer/public/customizations/custom_dataset_selector.tsx index 0c689752cc7315..78c70a1e5e3656 100644 --- a/x-pack/plugins/discover_log_explorer/public/customizations/custom_dataset_selector.tsx +++ b/x-pack/plugins/discover_log_explorer/public/customizations/custom_dataset_selector.tsx @@ -5,28 +5,37 @@ * 2.0. */ -import React from 'react'; +/* eslint-disable react-hooks/exhaustive-deps */ + +import React, { useState } from 'react'; import { DiscoverStateContainer } from '@kbn/discover-plugin/public'; -import { IndexPattern } from '@kbn/io-ts-utils'; -import { Dataset } from '../../common/datasets/models/dataset'; -import { DatasetSelectionHandler, DatasetSelector } from '../components/dataset_selector'; +import { DatasetSelector } from '../components/dataset_selector'; import { DatasetsProvider, useDatasetsContext } from '../hooks/use_datasets'; -import { InternalStateProvider, useDataView } from '../hooks/use_data_view'; +import { InternalStateProvider } from '../hooks/use_data_view'; import { IntegrationsProvider, useIntegrationsContext } from '../hooks/use_integrations'; import { IDatasetsClient } from '../services/datasets'; +import { + AllDatasetSelection, + DatasetSelection, + DatasetSelectionChange, +} from '../utils/dataset_selection'; interface CustomDatasetSelectorProps { stateContainer: DiscoverStateContainer; } export const CustomDatasetSelector = withProviders(({ stateContainer }) => { - // Container component, here goes all the state management and custom logic usage to keep the DatasetSelector presentational. - const dataView = useDataView(); + /** + * TOREMOVE: This is a temporary workaround to control the datasetSelection value + * until we handle the restore/initialization of the dataview with https://github.com/elastic/kibana/issues/160425, + * where this value will be used to control the DatasetSelector selection with a top level state machine. + */ + const [datasetSelection, setDatasetSelection] = useState(() => + AllDatasetSelection.create() + ); - const initialSelected: Dataset = Dataset.create({ - name: dataView.getIndexPattern() as IndexPattern, - title: dataView.getName(), - }); + // Restore All dataset selection on refresh until restore from url is not available + React.useEffect(() => handleStreamSelection(datasetSelection), []); const { error: integrationsError, @@ -54,15 +63,18 @@ export const CustomDatasetSelector = withProviders(({ stateContainer }) => { * TODO: this action will be abstracted into a method of a class adapter in a follow-up PR * since we'll need to handle more actions from the stateContainer */ - const handleStreamSelection: DatasetSelectionHandler = (dataset) => { - return stateContainer.actions.onCreateDefaultAdHocDataView(dataset.toDataviewSpec()); + const handleStreamSelection: DatasetSelectionChange = (nextDatasetSelection) => { + setDatasetSelection(nextDatasetSelection); + return stateContainer.actions.onCreateDefaultAdHocDataView( + nextDatasetSelection.toDataviewSpec() + ); }; return ( { onIntegrationsSort={sortIntegrations} onIntegrationsStreamsSearch={searchIntegrationsStreams} onIntegrationsStreamsSort={sortIntegrationsStreams} - onDatasetSelected={handleStreamSelection} + onSelectionChange={handleStreamSelection} onStreamsEntryClick={loadDatasets} onUnmanagedStreamsReload={reloadDatasets} onUnmanagedStreamsSearch={searchDatasets} diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/all_dataset_selection.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/all_dataset_selection.ts new file mode 100644 index 00000000000000..ebe3254968fb03 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/all_dataset_selection.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Dataset } from '../../../common/datasets'; +import { encodeDatasetSelection } from './encoding'; +import { DatasetSelectionStrategy } from './types'; + +export class AllDatasetSelection implements DatasetSelectionStrategy { + selectionType: 'all'; + selection: { + dataset: Dataset; + }; + + private constructor() { + this.selectionType = 'all'; + this.selection = { + dataset: Dataset.createAllLogsDataset(), + }; + } + + toDataviewSpec() { + const { name, title } = this.selection.dataset.toDataviewSpec(); + return { + id: this.toURLSelectionId(), + name, + title, + }; + } + + toURLSelectionId() { + return encodeDatasetSelection({ + selectionType: this.selectionType, + }); + } + + public static create() { + return new AllDatasetSelection(); + } +} diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.test.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.test.ts new file mode 100644 index 00000000000000..d88d939858d0e5 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.test.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IndexPattern } from '@kbn/io-ts-utils'; +import { encodeDatasetSelection, decodeDatasetSelectionId } from './encoding'; +import { DatasetEncodingError } from './errors'; +import { DatasetSelectionPlain } from './types'; + +describe('DatasetSelection', () => { + const allDatasetSelectionPlain: DatasetSelectionPlain = { + selectionType: 'all', + }; + const encodedAllDatasetSelection = 'BQZwpgNmDGAuCWB7AdgFQJ4AcwC4CGEEAlEA'; + + const singleDatasetSelectionPlain: DatasetSelectionPlain = { + selectionType: 'single', + selection: { + name: 'azure', + version: '1.5.23', + dataset: { + name: 'logs-azure.activitylogs-*' as IndexPattern, + title: 'activitylogs', + }, + }, + }; + const encodedSingleDatasetSelection = + 'BQZwpgNmDGAuCWB7AdgLmAEwIay+W6yWAtmKgOQSIDmIAtFgF4CuATmAHRZzwBu8sAJ5VadAFTkANAlhRU3BPyEiQASklFS8lu0m8wrEEjTkAjBwCsHAEwBmcuvBQeKACqCADmSPJqUVUA=='; + + const invalidDatasetSelectionPlain = { + selectionType: 'single', + selection: { + dataset: { + // Missing mandatory `name` property + title: 'activitylogs', + }, + }, + }; + const invalidCompressedId = 'random'; + const invalidEncodedDatasetSelection = 'BQZwpgNmDGAuCWB7AdgFQJ4AcwC4T2QHMoBKIA=='; + + describe('#encodeDatasetSelection', () => { + test('should encode and compress a valid DatasetSelection plain object', () => { + // Encode AllDatasetSelection plain object + expect(encodeDatasetSelection(allDatasetSelectionPlain)).toEqual(encodedAllDatasetSelection); + // Encode SingleDatasetSelection plain object + expect(encodeDatasetSelection(singleDatasetSelectionPlain)).toEqual( + encodedSingleDatasetSelection + ); + }); + + test('should throw a DatasetEncodingError if the input is an invalid DatasetSelection plain object', () => { + const encodingRunner = () => + encodeDatasetSelection(invalidDatasetSelectionPlain as DatasetSelectionPlain); + + expect(encodingRunner).toThrow(DatasetEncodingError); + expect(encodingRunner).toThrow(/^The current dataset selection is invalid/); + }); + }); + + describe('#decodeDatasetSelectionId', () => { + test('should decode and decompress a valid encoded string', () => { + // Decode AllDatasetSelection plain object + expect(decodeDatasetSelectionId(encodedAllDatasetSelection)).toEqual( + allDatasetSelectionPlain + ); + // Decode SingleDatasetSelection plain object + expect(decodeDatasetSelectionId(encodedSingleDatasetSelection)).toEqual( + singleDatasetSelectionPlain + ); + }); + + test('should throw a DatasetEncodingError if the input is an invalid compressed id', () => { + expect(() => decodeDatasetSelectionId(invalidCompressedId)).toThrow( + new DatasetEncodingError('The stored id is not a valid compressed value.') + ); + }); + + test('should throw a DatasetEncodingError if the decompressed value is an invalid DatasetSelection plain object', () => { + const decodingRunner = () => decodeDatasetSelectionId(invalidEncodedDatasetSelection); + + expect(decodingRunner).toThrow(DatasetEncodingError); + expect(decodingRunner).toThrow(/^The current dataset selection is invalid/); + }); + }); + + test('encoding and decoding should restore the original DatasetSelection plain object', () => { + // Encode/Decode AllDatasetSelection plain object + expect(decodeDatasetSelectionId(encodeDatasetSelection(allDatasetSelectionPlain))).toEqual( + allDatasetSelectionPlain + ); + // Encode/Decode SingleDatasetSelection plain object + expect(decodeDatasetSelectionId(encodeDatasetSelection(singleDatasetSelectionPlain))).toEqual( + singleDatasetSelectionPlain + ); + }); +}); diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.ts new file mode 100644 index 00000000000000..5a84c398e7d4e5 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/encoding.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { decode, encode, RisonValue } from '@kbn/rison'; +import * as lz from 'lz-string'; +import { decodeOrThrow } from '../../../common/runtime_types'; +import { DatasetEncodingError } from './errors'; +import { DatasetSelectionPlain, datasetSelectionPlainRT } from './types'; + +export const encodeDatasetSelection = (datasetSelectionPlain: DatasetSelectionPlain) => { + const safeDatasetSelection = decodeOrThrow( + datasetSelectionPlainRT, + (message: string) => + new DatasetEncodingError(`The current dataset selection is invalid: ${message}"`) + )(datasetSelectionPlain); + + return lz.compressToBase64(encode(safeDatasetSelection)); +}; + +export const decodeDatasetSelectionId = (datasetSelectionId: string): DatasetSelectionPlain => { + const risonDatasetSelection: RisonValue = lz.decompressFromBase64(datasetSelectionId); + + if (risonDatasetSelection === null || risonDatasetSelection === '') { + throw new DatasetEncodingError('The stored id is not a valid compressed value.'); + } + + const decodedDatasetSelection = decode(risonDatasetSelection); + + const datasetSelection = decodeOrThrow( + datasetSelectionPlainRT, + (message: string) => + new DatasetEncodingError(`The current dataset selection is invalid: ${message}"`) + )(decodedDatasetSelection); + + return datasetSelection; +}; diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/errors.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/errors.ts new file mode 100644 index 00000000000000..748a4b91b246c9 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/errors.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export class DatasetEncodingError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + this.name = 'DatasetEncodingError'; + } +} diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/hydrate_dataset_selection.ts.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/hydrate_dataset_selection.ts.ts new file mode 100644 index 00000000000000..8a855a46412f3d --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/hydrate_dataset_selection.ts.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AllDatasetSelection } from './all_dataset_selection'; +import { SingleDatasetSelection } from './single_dataset_selection'; +import { DatasetSelectionPlain } from './types'; + +export const hydrateDatasetSelection = (datasetSelection: DatasetSelectionPlain) => { + if (datasetSelection.selectionType === 'all') { + return AllDatasetSelection.create(); + } + if (datasetSelection.selectionType === 'single') { + return SingleDatasetSelection.fromSelection(datasetSelection.selection); + } +}; diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/index.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/index.ts new file mode 100644 index 00000000000000..24a3bad6605e30 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/index.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. + */ + +import { AllDatasetSelection } from './all_dataset_selection'; +import { SingleDatasetSelection } from './single_dataset_selection'; + +export type DatasetSelection = AllDatasetSelection | SingleDatasetSelection; +export type DatasetSelectionChange = (datasetSelection: DatasetSelection) => void; + +export * from './all_dataset_selection'; +export * from './single_dataset_selection'; +export * from './encoding'; +export * from './hydrate_dataset_selection.ts'; +export * from './types'; diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/single_dataset_selection.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/single_dataset_selection.ts new file mode 100644 index 00000000000000..ce64a3a45084c4 --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/single_dataset_selection.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Dataset } from '../../../common/datasets'; +import { encodeDatasetSelection } from './encoding'; +import { DatasetSelectionStrategy, SingleDatasetSelectionPayload } from './types'; + +export class SingleDatasetSelection implements DatasetSelectionStrategy { + selectionType: 'single'; + selection: { + name?: string; + version?: string; + dataset: Dataset; + }; + + private constructor(dataset: Dataset) { + this.selectionType = 'single'; + this.selection = { + name: dataset.parentIntegration?.name, + version: dataset.parentIntegration?.version, + dataset, + }; + } + + toDataviewSpec() { + const { name, title } = this.selection.dataset.toDataviewSpec(); + return { + id: this.toURLSelectionId(), + name, + title, + }; + } + + toURLSelectionId() { + return encodeDatasetSelection({ + selectionType: this.selectionType, + selection: { + name: this.selection.name, + version: this.selection.version, + dataset: this.selection.dataset.toPlain(), + }, + }); + } + + public static fromSelection(selection: SingleDatasetSelectionPayload) { + const { name, version, dataset } = selection; + + // Attempt reconstructing the integration object + const integration = name && version ? { name, version } : undefined; + const datasetInstance = Dataset.create(dataset, integration); + + return new SingleDatasetSelection(datasetInstance); + } + + public static create(dataset: Dataset) { + return new SingleDatasetSelection(dataset); + } +} diff --git a/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/types.ts b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/types.ts new file mode 100644 index 00000000000000..6608a29acc821c --- /dev/null +++ b/x-pack/plugins/discover_log_explorer/public/utils/dataset_selection/types.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { DataViewSpec } from '@kbn/data-views-plugin/common'; +import * as rt from 'io-ts'; +import { datasetRT } from '../../../common/datasets'; + +export const allDatasetSelectionPlainRT = rt.type({ + selectionType: rt.literal('all'), +}); + +const integrationNameRT = rt.partial({ + name: rt.string, +}); + +const integrationVersionRT = rt.partial({ + version: rt.string, +}); + +const singleDatasetSelectionPayloadRT = rt.intersection([ + integrationNameRT, + integrationVersionRT, + rt.type({ + dataset: datasetRT, + }), +]); + +export const singleDatasetSelectionPlainRT = rt.type({ + selectionType: rt.literal('single'), + selection: singleDatasetSelectionPayloadRT, +}); + +export const datasetSelectionPlainRT = rt.union([ + allDatasetSelectionPlainRT, + singleDatasetSelectionPlainRT, +]); + +export type SingleDatasetSelectionPayload = rt.TypeOf; +export type DatasetSelectionPlain = rt.TypeOf; + +export interface DatasetSelectionStrategy { + toDataviewSpec(): DataViewSpec; + toURLSelectionId(): string; +} diff --git a/x-pack/plugins/discover_log_explorer/tsconfig.json b/x-pack/plugins/discover_log_explorer/tsconfig.json index 8844db22796e5f..babab6c97b029e 100644 --- a/x-pack/plugins/discover_log_explorer/tsconfig.json +++ b/x-pack/plugins/discover_log_explorer/tsconfig.json @@ -13,6 +13,7 @@ "@kbn/kibana-utils-plugin", "@kbn/io-ts-utils", "@kbn/data-views-plugin", + "@kbn/rison", ], "exclude": ["target/**/*"] } From ff0f1217a0dd0946a1029b9c3233da4daaa456e0 Mon Sep 17 00:00:00 2001 From: Janki Salvi <117571355+js-jankisalvi@users.noreply.github.com> Date: Tue, 4 Jul 2023 09:14:37 +0200 Subject: [PATCH 43/98] [Cases] update API schema params as object (#161108) This PR addresses the comment mentioned in this [PR](https://github.com/elastic/kibana/pull/160844/files#r1246816012) --- x-pack/plugins/cases/common/api/cases/case.ts | 86 +++++++++++++------ .../cases/common/api/cases/comment/files.ts | 7 +- .../plugins/cases/common/schema/index.test.ts | 67 ++++++++++----- x-pack/plugins/cases/common/schema/index.ts | 20 +++-- 4 files changed, 123 insertions(+), 57 deletions(-) diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index fd734c943de0ec..a4bd4b016d955e 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -144,20 +144,24 @@ export const CasePostRequestRt = rt.intersection([ /** * Description of the case */ - description: limitedStringSchema('description', 1, MAX_DESCRIPTION_LENGTH), + description: limitedStringSchema({ + fieldName: 'description', + min: 1, + max: MAX_DESCRIPTION_LENGTH, + }), /** * Identifiers for the case. */ - tags: limitedArraySchema( - limitedStringSchema('tag', 1, MAX_LENGTH_PER_TAG), - 0, - MAX_TAGS_PER_CASE, - 'tags' - ), + tags: limitedArraySchema({ + codec: limitedStringSchema({ fieldName: 'tag', min: 1, max: MAX_LENGTH_PER_TAG }), + fieldName: 'tags', + min: 0, + max: MAX_TAGS_PER_CASE, + }), /** * Title of the case */ - title: limitedStringSchema('title', 1, MAX_TITLE_LENGTH), + title: limitedStringSchema({ fieldName: 'title', min: 1, max: MAX_TITLE_LENGTH }), /** * The external configuration for the case */ @@ -186,7 +190,10 @@ export const CasePostRequestRt = rt.intersection([ /** * The category of the case. */ - category: rt.union([limitedStringSchema('category', 1, MAX_CATEGORY_LENGTH), rt.null]), + category: rt.union([ + limitedStringSchema({ fieldName: 'category', min: 1, max: MAX_CATEGORY_LENGTH }), + rt.null, + ]), }) ), ]); @@ -224,7 +231,15 @@ export const CasesFindRequestRt = rt.exact( /** * Tags to filter by */ - tags: rt.union([limitedArraySchema(rt.string, 0, MAX_TAGS_FILTER_LENGTH, 'tags'), rt.string]), + tags: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'tags', + min: 0, + max: MAX_TAGS_FILTER_LENGTH, + }), + rt.string, + ]), /** * The status of the case (open, closed, in-progress) */ @@ -237,14 +252,24 @@ export const CasesFindRequestRt = rt.exact( * The uids of the user profiles to filter by */ assignees: rt.union([ - limitedArraySchema(rt.string, 0, MAX_ASSIGNEES_FILTER_LENGTH, 'assignees'), + limitedArraySchema({ + codec: rt.string, + fieldName: 'assignees', + min: 0, + max: MAX_ASSIGNEES_FILTER_LENGTH, + }), rt.string, ]), /** * The reporters to filter by */ reporters: rt.union([ - limitedArraySchema(rt.string, 0, MAX_REPORTERS_FILTER_LENGTH, 'reporters'), + limitedArraySchema({ + codec: rt.string, + fieldName: 'reporters', + min: 0, + max: MAX_REPORTERS_FILTER_LENGTH, + }), rt.string, ]), /** @@ -306,12 +331,12 @@ export const CasesFindRequestRt = rt.exact( }) ); -export const CasesDeleteRequestRt = limitedArraySchema( - NonEmptyString, - 1, - MAX_DELETE_IDS_LENGTH, - 'ids' -); +export const CasesDeleteRequestRt = limitedArraySchema({ + codec: NonEmptyString, + min: 1, + max: MAX_DELETE_IDS_LENGTH, + fieldName: 'ids', +}); export const CasesByAlertIDRequestRt = rt.exact( rt.partial({ @@ -370,7 +395,11 @@ export const CasePatchRequestRt = rt.intersection([ /** * The description of the case */ - description: limitedStringSchema('description', 1, MAX_DESCRIPTION_LENGTH), + description: limitedStringSchema({ + fieldName: 'description', + min: 1, + max: MAX_DESCRIPTION_LENGTH, + }), /** * The current status of the case (open, closed, in-progress) */ @@ -378,16 +407,16 @@ export const CasePatchRequestRt = rt.intersection([ /** * The identifying strings for filter a case */ - tags: limitedArraySchema( - limitedStringSchema('tag', 1, MAX_LENGTH_PER_TAG), - 0, - MAX_TAGS_PER_CASE, - 'tags' - ), + tags: limitedArraySchema({ + codec: limitedStringSchema({ fieldName: 'tag', min: 1, max: MAX_LENGTH_PER_TAG }), + min: 0, + max: MAX_TAGS_PER_CASE, + fieldName: 'tags', + }), /** * The title of a case */ - title: limitedStringSchema('title', 1, MAX_TITLE_LENGTH), + title: limitedStringSchema({ fieldName: 'title', min: 1, max: MAX_TITLE_LENGTH }), /** * The external system that the case can be synced with */ @@ -411,7 +440,10 @@ export const CasePatchRequestRt = rt.intersection([ /** * The category of the case. */ - category: rt.union([limitedStringSchema('category', 1, MAX_CATEGORY_LENGTH), rt.null]), + category: rt.union([ + limitedStringSchema({ fieldName: 'category', min: 1, max: MAX_CATEGORY_LENGTH }), + rt.null, + ]), }) ), /** diff --git a/x-pack/plugins/cases/common/api/cases/comment/files.ts b/x-pack/plugins/cases/common/api/cases/comment/files.ts index 04b46876d5188b..38d70cdc455553 100644 --- a/x-pack/plugins/cases/common/api/cases/comment/files.ts +++ b/x-pack/plugins/cases/common/api/cases/comment/files.ts @@ -25,7 +25,12 @@ export type FileAttachmentMetadata = rt.TypeOf; const MIN_DELETE_IDS = 1; export const BulkDeleteFileAttachmentsRequestRt = rt.strict({ - ids: limitedArraySchema(NonEmptyString, MIN_DELETE_IDS, MAX_DELETE_FILES, 'ids'), + ids: limitedArraySchema({ + codec: NonEmptyString, + min: MIN_DELETE_IDS, + max: MAX_DELETE_FILES, + fieldName: 'ids', + }), }); export type BulkDeleteFileAttachmentsRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/schema/index.test.ts b/x-pack/plugins/cases/common/schema/index.test.ts index 826ee6ffbcd31a..1a810c8003ff79 100644 --- a/x-pack/plugins/cases/common/schema/index.test.ts +++ b/x-pack/plugins/cases/common/schema/index.test.ts @@ -14,8 +14,11 @@ describe('schema', () => { const fieldName = 'foobar'; it('fails when given an empty string', () => { - expect(PathReporter.report(limitedArraySchema(NonEmptyString, 1, 1, fieldName).decode(['']))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report( + limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['']) + ) + ).toMatchInlineSnapshot(` Array [ "string must have length >= 1", ] @@ -23,8 +26,11 @@ describe('schema', () => { }); it('fails when given an empty array', () => { - expect(PathReporter.report(limitedArraySchema(NonEmptyString, 1, 1, fieldName).decode([]))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report( + limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode([]) + ) + ).toMatchInlineSnapshot(` Array [ "The length of the field foobar is too short. Array must be of length >= 1.", ] @@ -33,7 +39,12 @@ describe('schema', () => { it('fails when given an array larger than the limit of one item', () => { expect( - PathReporter.report(limitedArraySchema(NonEmptyString, 1, 1, fieldName).decode(['a', 'b'])) + PathReporter.report( + limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode([ + 'a', + 'b', + ]) + ) ).toMatchInlineSnapshot(` Array [ "The length of the field foobar is too long. Array must be of length <= 1.", @@ -42,8 +53,11 @@ describe('schema', () => { }); it('succeeds when given an array of 1 item with a non-empty string', () => { - expect(PathReporter.report(limitedArraySchema(NonEmptyString, 1, 1, fieldName).decode(['a']))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report( + limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['a']) + ) + ).toMatchInlineSnapshot(` Array [ "No errors!", ] @@ -51,8 +65,11 @@ describe('schema', () => { }); it('succeeds when given an array of 0 item with a non-empty string when the min is 0', () => { - expect(PathReporter.report(limitedArraySchema(NonEmptyString, 0, 2, fieldName).decode([]))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report( + limitedArraySchema({ codec: NonEmptyString, fieldName, min: 0, max: 2 }).decode([]) + ) + ).toMatchInlineSnapshot(` Array [ "No errors!", ] @@ -64,7 +81,7 @@ describe('schema', () => { const fieldName = 'foo'; it('fails when given string is shorter than minimum', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 2, 1).decode('a'))) + expect(PathReporter.report(limitedStringSchema({ fieldName, min: 2, max: 1 }).decode('a'))) .toMatchInlineSnapshot(` Array [ "The length of the ${fieldName} is too short. The minimum length is 2.", @@ -73,7 +90,7 @@ describe('schema', () => { }); it('fails when given string is empty and minimum is not 0', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 1, 1).decode(''))) + expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(''))) .toMatchInlineSnapshot(` Array [ "The ${fieldName} field cannot be an empty string.", @@ -82,7 +99,7 @@ describe('schema', () => { }); it('fails when given string consists only empty characters and minimum is not 0', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 1, 1).decode(' '))) + expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(' '))) .toMatchInlineSnapshot(` Array [ "The ${fieldName} field cannot be an empty string.", @@ -91,8 +108,11 @@ describe('schema', () => { }); it('fails when given string is larger than maximum', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 1, 5).decode('Hello there!!'))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report( + limitedStringSchema({ fieldName, min: 1, max: 5 }).decode('Hello there!!') + ) + ).toMatchInlineSnapshot(` Array [ "The length of the ${fieldName} is too long. The maximum length is 5.", ] @@ -100,8 +120,9 @@ describe('schema', () => { }); it('succeeds when given string within limit', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 1, 50).decode('Hello!!'))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 50 }).decode('Hello!!')) + ).toMatchInlineSnapshot(` Array [ "No errors!", ] @@ -109,7 +130,7 @@ describe('schema', () => { }); it('succeeds when given string is empty and minimum is 0', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 0, 5).decode(''))) + expect(PathReporter.report(limitedStringSchema({ fieldName, min: 0, max: 5 }).decode(''))) .toMatchInlineSnapshot(` Array [ "No errors!", @@ -118,7 +139,7 @@ describe('schema', () => { }); it('succeeds when given string consists only empty characters and minimum is 0', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 0, 5).decode(' '))) + expect(PathReporter.report(limitedStringSchema({ fieldName, min: 0, max: 5 }).decode(' '))) .toMatchInlineSnapshot(` Array [ "No errors!", @@ -127,8 +148,9 @@ describe('schema', () => { }); it('succeeds when given string is same as maximum', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 0, 5).decode('Hello'))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report(limitedStringSchema({ fieldName, min: 0, max: 5 }).decode('Hello')) + ).toMatchInlineSnapshot(` Array [ "No errors!", ] @@ -136,8 +158,9 @@ describe('schema', () => { }); it('succeeds when given string is larger than maximum but same as maximum after trim', () => { - expect(PathReporter.report(limitedStringSchema(fieldName, 0, 5).decode('Hello '))) - .toMatchInlineSnapshot(` + expect( + PathReporter.report(limitedStringSchema({ fieldName, min: 0, max: 5 }).decode('Hello ')) + ).toMatchInlineSnapshot(` Array [ "No errors!", ] diff --git a/x-pack/plugins/cases/common/schema/index.ts b/x-pack/plugins/cases/common/schema/index.ts index 1f8e4e05c49336..9003360ae11b82 100644 --- a/x-pack/plugins/cases/common/schema/index.ts +++ b/x-pack/plugins/cases/common/schema/index.ts @@ -8,6 +8,12 @@ import * as rt from 'io-ts'; import { either } from 'fp-ts/lib/Either'; +export interface LimitedSchemaType { + fieldName: string; + min: number; + max: number; +} + export const NonEmptyString = new rt.Type( 'NonEmptyString', rt.string.is, @@ -22,7 +28,7 @@ export const NonEmptyString = new rt.Type( rt.identity ); -export const limitedStringSchema = (fieldName: string, min: number, max: number) => +export const limitedStringSchema = ({ fieldName, min, max }: LimitedSchemaType) => new rt.Type( 'LimitedString', rt.string.is, @@ -55,12 +61,12 @@ export const limitedStringSchema = (fieldName: string, min: number, max: number) rt.identity ); -export const limitedArraySchema = ( - codec: T, - min: number, - max: number, - fieldName: string -) => +export const limitedArraySchema = ({ + codec, + fieldName, + min, + max, +}: { codec: T } & LimitedSchemaType) => new rt.Type>, Array>, unknown>( 'LimitedArray', (input): input is T[] => rt.array(codec).is(input), From 5d444945f5acfa20b4f6c90daa1ce9f8e7cf16ff Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Tue, 4 Jul 2023 02:43:59 -0500 Subject: [PATCH 44/98] [Lens] Automatically unlink cloned library annotation group layers (#161130) --- .../visualizations/xy/visualization.test.tsx | 59 ++++++++++++++++++- .../visualizations/xy/visualization.tsx | 19 +++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.tsx index 8c618618c5c1e1..97b3e726a388c9 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.tsx @@ -50,7 +50,11 @@ import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks import { layerTypes, Visualization } from '../..'; import { set } from '@kbn/safer-lodash-set'; import { SavedObjectReference } from '@kbn/core-saved-objects-api-server'; -import { getAnnotationsLayers } from './visualization_helpers'; +import { + getAnnotationsLayers, + isAnnotationsLayer, + isByReferenceAnnotationsLayer, +} from './visualization_helpers'; import { cloneDeep } from 'lodash'; import { DataViewsServicePublic } from '@kbn/data-views-plugin/public'; @@ -3240,6 +3244,59 @@ describe('xy_visualization', () => { }); }); + describe('#cloneLayer', () => { + it('should turned cloned by-reference annotation groups into by-value', () => { + const state = exampleState(); + const layer: XYByValueAnnotationLayerConfig = { + layerId: 'layer-id', + layerType: 'annotations', + indexPatternId: 'some-index-pattern', + ignoreGlobalFilters: false, + annotations: [ + { + id: 'some-annotation-id', + type: 'manual', + key: { + type: 'point_in_time', + timestamp: 'timestamp', + }, + } as PointInTimeEventAnnotationConfig, + ], + }; + + state.layers = [ + { + ...layer, + annotationGroupId: 'some-group-id', + __lastSaved: { + ...layer, + title: '', + description: '', + tags: [], + }, + }, + ]; + + const newLayerId = 'new-layer-id'; + + const stateWithClonedLayer = xyVisualization.cloneLayer!( + state, + layer.layerId, + newLayerId, + new Map() + ); + + expect( + isAnnotationsLayer(stateWithClonedLayer.layers[0]) && + isByReferenceAnnotationsLayer(stateWithClonedLayer.layers[0]) + ).toBe(true); + expect( + isAnnotationsLayer(stateWithClonedLayer.layers[1]) && + isByReferenceAnnotationsLayer(stateWithClonedLayer.layers[1]) + ).toBe(false); + }); + }); + describe('#getUniqueLabels', () => { it('creates unique labels for single annotations layer with repeating labels', async () => { const annotationLayer: XYAnnotationLayerConfig = { diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index 7f236b69f44714..f74bcc9145b06e 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -106,7 +106,7 @@ import { validateLayersForDimension, } from './visualization_helpers'; import { groupAxesByType } from './axes_configuration'; -import type { XYState } from './types'; +import type { XYByValueAnnotationLayerConfig, XYState } from './types'; import { ReferenceLinePanel } from './xy_config_panel/reference_line_config_panel'; import { AnnotationsPanel } from './xy_config_panel/annotations_config_panel'; import { defaultAnnotationLabel } from './annotations/helpers'; @@ -174,10 +174,25 @@ export const getXyVisualization = ({ if (isAnnotationsLayer(toCopyLayer)) { toCopyLayer.annotations.forEach((i) => clonedIDsMap.set(i.id, generateId())); } - const newLayer = renewIDs(toCopyLayer, [...clonedIDsMap.keys()], (id: string) => + + let newLayer = renewIDs(toCopyLayer, [...clonedIDsMap.keys()], (id: string) => clonedIDsMap.get(id) ); + newLayer.layerId = newLayerId; + + if (isAnnotationsLayer(newLayer) && isByReferenceAnnotationsLayer(newLayer)) { + const byValueVersion: XYByValueAnnotationLayerConfig = { + annotations: newLayer.annotations, + ignoreGlobalFilters: newLayer.ignoreGlobalFilters, + layerId: newLayer.layerId, + layerType: newLayer.layerType, + indexPatternId: newLayer.indexPatternId, + }; + + newLayer = byValueVersion; + } + return { ...state, layers: [...state.layers, newLayer], From 4819efa8eb16529db807043d36a1214070e10c79 Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Tue, 4 Jul 2023 10:19:30 +0200 Subject: [PATCH 45/98] [Discover] Refresh fields when entering Discover (#160195) - Closes https://github.com/elastic/kibana/issues/156556 - Probably also addresses https://github.com/elastic/kibana/issues/157239 ## Summary This PR allows to refresh fields list when revisiting Discover page. ## For testing 1. Open discover 2. In a separate tab open Dev Tools and create documents which include new field names 3. Press "Refresh" in the unified search bar on Discover and notice that new fields appear under Unmapped section 4. Navigate to another Kibana app (for example Home page) 5. Navigate back to Discover and notice that new fields are now under Available section and have a proper icon. --- .../public/application/main/utils/resolve_data_view.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts index d846f7b9495134..fc6a1ae9d166ed 100644 --- a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts +++ b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts @@ -70,7 +70,7 @@ export async function loadDataView({ let fetchedDataView: DataView | null = null; // try to fetch adhoc data view first try { - fetchedDataView = fetchId ? await dataViews.get(fetchId, false) : null; + fetchedDataView = fetchId ? await dataViews.get(fetchId, false, true) : null; if (fetchedDataView && !fetchedDataView.isPersisted()) { return { list: dataViewList || [], @@ -88,7 +88,10 @@ export async function loadDataView({ let defaultDataView: DataView | null = null; if (!fetchedDataView) { try { - defaultDataView = await dataViews.getDefaultDataView({ displayErrors: false }); + defaultDataView = await dataViews.getDefaultDataView({ + displayErrors: false, + refreshFields: true, + }); } catch (e) { // } From 41fec243ae961bf3371eec8143ff1b648ac9a1c6 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 4 Jul 2023 11:44:39 +0200 Subject: [PATCH 46/98] [Cases] Guardrails: Limit bulk get cases and bulk get attachments (#161088) Connected to https://github.com/elastic/kibana/issues/146945 ## Summary | Description | Limit | Done? | Documented? | ------------- | ---- | :---: | ---- | | Total number of attachments returned by bulk get API | 100 | :white_check_mark: | No (internal) | | Total number of cases returned by bulk get API | 1000 | :white_check_mark: | No (internal) | - Replaced the code validation with schema validation. - BulkGet Cases - The minimum of cases that can be returned is now 1(was not validated before). - BulkGet Attachments - The maximum of attachments that can be returned is now 100(was **10000**). - The minimum of attachments that can be returned is now 1(was not validated before). - Updated unit and e2e tests. - The documentation was not updated because these are internal APIs. - Skipping the release notes because these are internal APIs. ### 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] [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 --- x-pack/plugins/cases/common/api/cases/case.ts | 3 +- .../cases/common/api/cases/comment/index.ts | 9 +++- .../plugins/cases/common/constants/index.ts | 2 +- .../client/attachments/bulk_get.test.ts | 41 +++++++++++++++++++ .../server/client/attachments/bulk_get.ts | 13 ------ .../server/client/cases/bulk_get.test.ts | 17 +++++--- .../cases/server/client/cases/bulk_get.ts | 10 ----- .../common/internal/bulk_get_attachments.ts | 41 +++++++++---------- .../tests/common/internal/bulk_get_cases.ts | 13 ++++-- 9 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index a4bd4b016d955e..9778195465432e 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -24,6 +24,7 @@ import { MAX_ASSIGNEES_FILTER_LENGTH, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, + MAX_BULK_GET_CASES, } from '../../constants'; export const AttachmentTotalsRt = rt.strict({ @@ -509,7 +510,7 @@ export const GetCategoriesResponseRt = rt.array(rt.string); export const GetReportersResponseRt = rt.array(UserRt); export const CasesBulkGetRequestRt = rt.strict({ - ids: rt.array(rt.string), + ids: limitedArraySchema({ codec: rt.string, min: 1, max: MAX_BULK_GET_CASES, fieldName: 'ids' }), }); export const CasesBulkGetResponseRt = rt.strict({ diff --git a/x-pack/plugins/cases/common/api/cases/comment/index.ts b/x-pack/plugins/cases/common/api/cases/comment/index.ts index f688dc24fdf85b..1662631ae2b797 100644 --- a/x-pack/plugins/cases/common/api/cases/comment/index.ts +++ b/x-pack/plugins/cases/common/api/cases/comment/index.ts @@ -6,6 +6,8 @@ */ import * as rt from 'io-ts'; +import { MAX_BULK_GET_ATTACHMENTS } from '../../../constants'; +import { limitedArraySchema } from '../../../schema'; import { jsonValueRt } from '../../runtime_types'; import { NumberFromString } from '../../saved_object'; @@ -307,7 +309,12 @@ export const FindCommentsQueryParamsRt = rt.exact( export const BulkCreateCommentRequestRt = rt.array(CommentRequestRt); export const BulkGetAttachmentsRequestRt = rt.strict({ - ids: rt.array(rt.string), + ids: limitedArraySchema({ + codec: rt.string, + min: 1, + max: MAX_BULK_GET_ATTACHMENTS, + fieldName: 'ids', + }), }); export const BulkGetAttachmentsResponseRt = rt.strict({ diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index bee8ff9f3b17e0..b7b49870424956 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -101,7 +101,7 @@ export const MAX_ALERTS_PER_CASE = 1000 as const; * Searching */ export const MAX_DOCS_PER_PAGE = 10000 as const; -export const MAX_BULK_GET_ATTACHMENTS = MAX_DOCS_PER_PAGE; +export const MAX_BULK_GET_ATTACHMENTS = 100 as const; export const MAX_CONCURRENT_SEARCHES = 10 as const; export const MAX_BULK_GET_CASES = 1000 as const; export const MAX_COMMENTS_PER_PAGE = 100 as const; diff --git a/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts b/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts new file mode 100644 index 00000000000000..078f79128391b0 --- /dev/null +++ b/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MAX_BULK_GET_ATTACHMENTS } from '../../../common/constants'; +import { createCasesClientMockArgs, createCasesClientMock } from '../mocks'; +import { bulkGet } from './bulk_get'; + +describe('bulkGet', () => { + describe('errors', () => { + const casesClient = createCasesClientMock(); + const clientArgs = createCasesClientMockArgs(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it(`throws when trying to fetch more than ${MAX_BULK_GET_ATTACHMENTS} attachments`, async () => { + await expect( + bulkGet( + { attachmentIDs: Array(MAX_BULK_GET_ATTACHMENTS + 1).fill('foobar'), caseID: '123' }, + clientArgs, + casesClient + ) + ).rejects.toThrow( + `Error: The length of the field ids is too long. Array must be of length <= ${MAX_BULK_GET_ATTACHMENTS}.` + ); + }); + + it('throws when trying to fetch zero attachments', async () => { + await expect( + bulkGet({ attachmentIDs: [], caseID: '123' }, clientArgs, casesClient) + ).rejects.toThrow( + 'Error: The length of the field ids is too short. Array must be of length >= 1.' + ); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/attachments/bulk_get.ts b/x-pack/plugins/cases/server/client/attachments/bulk_get.ts index 294b39bab69595..553f8ca258669b 100644 --- a/x-pack/plugins/cases/server/client/attachments/bulk_get.ts +++ b/x-pack/plugins/cases/server/client/attachments/bulk_get.ts @@ -5,10 +5,7 @@ * 2.0. */ -import Boom from '@hapi/boom'; - import { partition } from 'lodash'; -import { MAX_BULK_GET_ATTACHMENTS } from '../../../common/constants'; import type { BulkGetAttachmentsResponse, CommentAttributes } from '../../../common/api'; import { decodeWithExcessOrThrow, @@ -45,8 +42,6 @@ export async function bulkGet( try { const request = decodeWithExcessOrThrow(BulkGetAttachmentsRequestRt)({ ids: attachmentIDs }); - throwErrorIfIdsExceedTheLimit(request.ids); - // perform an authorization check for the case await casesClient.cases.resolve({ id: caseID }); @@ -83,14 +78,6 @@ export async function bulkGet( } } -const throwErrorIfIdsExceedTheLimit = (ids: string[]) => { - if (ids.length > MAX_BULK_GET_ATTACHMENTS) { - throw Boom.badRequest( - `Maximum request limit of ${MAX_BULK_GET_ATTACHMENTS} attachments reached` - ); - } -}; - interface PartitionedAttachments { validAttachments: AttachmentSavedObject[]; attachmentsWithErrors: AttachmentSavedObjectWithErrors; diff --git a/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts b/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts index 0ee8955c9adb5c..771f5ece6f188c 100644 --- a/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts +++ b/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts @@ -5,22 +5,29 @@ * 2.0. */ +import { MAX_BULK_GET_CASES } from '../../../common/constants'; import { createCasesClientMockArgs } from '../mocks'; import { bulkGet } from './bulk_get'; describe('bulkGet', () => { - describe('throwErrorIfCaseIdsReachTheLimit', () => { + describe('errors', () => { const clientArgs = createCasesClientMockArgs(); beforeEach(() => { jest.clearAllMocks(); }); - it('throws if the requested cases are more than 1000', async () => { - const ids = Array(1001).fill('test'); + it(`throws when trying to fetch more than ${MAX_BULK_GET_CASES} cases`, async () => { + await expect( + bulkGet({ ids: Array(MAX_BULK_GET_CASES + 1).fill('foobar') }, clientArgs) + ).rejects.toThrow( + `Error: The length of the field ids is too long. Array must be of length <= ${MAX_BULK_GET_CASES}.` + ); + }); - await expect(bulkGet({ ids }, clientArgs)).rejects.toThrow( - 'Maximum request limit of 1000 cases reached' + it('throws when trying to fetch zero cases', async () => { + await expect(bulkGet({ ids: [] }, clientArgs)).rejects.toThrow( + 'Error: The length of the field ids is too short. Array must be of length >= 1.' ); }); diff --git a/x-pack/plugins/cases/server/client/cases/bulk_get.ts b/x-pack/plugins/cases/server/client/cases/bulk_get.ts index 13df81bf06965d..4665c27cebbf60 100644 --- a/x-pack/plugins/cases/server/client/cases/bulk_get.ts +++ b/x-pack/plugins/cases/server/client/cases/bulk_get.ts @@ -5,10 +5,8 @@ * 2.0. */ -import Boom from '@hapi/boom'; import { partition } from 'lodash'; -import { MAX_BULK_GET_CASES } from '../../../common/constants'; import type { CasesBulkGetResponse, CasesBulkGetRequest, @@ -45,8 +43,6 @@ export const bulkGet = async ( try { const request = decodeWithExcessOrThrow(CasesBulkGetRequestRt)(params); - throwErrorIfCaseIdsReachTheLimit(request.ids); - const cases = await caseService.getCases({ caseIds: request.ids }); const [validCases, soBulkGetErrors] = partition( @@ -91,12 +87,6 @@ export const bulkGet = async ( } }; -const throwErrorIfCaseIdsReachTheLimit = (ids: string[]) => { - if (ids.length > MAX_BULK_GET_CASES) { - throw Boom.badRequest(`Maximum request limit of ${MAX_BULK_GET_CASES} cases reached`); - } -}; - const constructErrors = ( soBulkGetErrors: CaseSavedObjectWithErrors, unauthorizedCases: CaseSavedObjectTransformed[] diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts index 2d1a7c2ab69a6b..8907f7e28841cf 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts @@ -90,27 +90,6 @@ export default ({ getService }: FtrProviderContext): void => { expect(response.attachments[1].id).to.eql(updatedCase.comments![1].id); }); - it('returns an empty array when no ids are requested', async () => { - const { attachments, errors } = await bulkGetAttachments({ - attachmentIds: [], - caseId: updatedCase.id, - supertest, - expectedHttpCode: 200, - }); - - expect(attachments.length).to.be(0); - expect(errors.length).to.be(0); - }); - - it('returns a 400 when more than 10k ids are requested', async () => { - await bulkGetAttachments({ - attachmentIds: Array.from(Array(10001).keys()).map((item) => item.toString()), - caseId: updatedCase.id, - supertest, - expectedHttpCode: 400, - }); - }); - it('populates the errors field with attachments that could not be found', async () => { const response = await bulkGetAttachments({ attachmentIds: [updatedCase.comments![0].id, 'does-not-exist'], @@ -455,5 +434,25 @@ export default ({ getService }: FtrProviderContext): void => { }); } }); + + describe('errors', () => { + it('400s when requesting more than 100 attachments', async () => { + await bulkGetAttachments({ + attachmentIds: Array(101).fill('foobar'), + caseId: 'id', + expectedHttpCode: 400, + supertest, + }); + }); + + it('400s when requesting zero attachments', async () => { + await bulkGetAttachments({ + attachmentIds: [], + caseId: 'id', + expectedHttpCode: 400, + supertest, + }); + }); + }); }); }; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts index 3ea30d7371b3eb..449251377a077d 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts @@ -7,6 +7,7 @@ import expect from '@kbn/expect'; import { CommentType } from '@kbn/cases-plugin/common'; +import { MAX_BULK_GET_CASES } from '@kbn/cases-plugin/common/constants'; import { getPostCaseRequest, postCaseReq } from '../../../../common/lib/mock'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -111,12 +112,18 @@ export default ({ getService }: FtrProviderContext): void => { }); describe('errors', () => { - it('400s when requesting more than 1000 cases', async () => { - const ids = Array(1001).fill('test'); + it(`400s when requesting more than ${MAX_BULK_GET_CASES} cases`, async () => { + await bulkGetCases({ + supertest, + ids: Array(MAX_BULK_GET_CASES + 1).fill('foobar'), + expectedHttpCode: 400, + }); + }); + it('400s when requesting zero cases', async () => { await bulkGetCases({ supertest, - ids, + ids: [], expectedHttpCode: 400, }); }); From 023b23f2a6a16612e48300494e66836d2c49c785 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Tue, 4 Jul 2023 11:54:02 +0200 Subject: [PATCH 47/98] Fix infinite loading of APM alert table (#161134) Fixes #161095 ## Summary This PR fixes triggering and immediately canceling /bsearch requests infinitely. --- .../public/components/app/alerts_overview/index.tsx | 11 +++++++---- .../templates/apm_service_template/index.tsx | 1 + .../templates/mobile_service_template/index.tsx | 1 + .../correlations/failed_transaction_correlations.ts | 13 +++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx b/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx index d5cd8c530332e5..7e4914f29a6710 100644 --- a/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useMemo, useEffect, useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { ObservabilityAlertSearchBar } from '@kbn/observability-plugin/public'; import { AlertStatus } from '@kbn/observability-plugin/common/typings'; @@ -72,6 +72,11 @@ export function AlertsOverview() { ]; }, [serviceName, environment]); + const onKueryChange = useCallback( + (value) => push(history, { query: { kuery: value } }), + [history] + ); + return ( @@ -86,9 +91,7 @@ export function AlertsOverview() { onRangeToChange={(value) => push(history, { query: { rangeTo: value } }) } - onKueryChange={(value) => - push(history, { query: { kuery: value } }) - } + onKueryChange={onKueryChange} defaultSearchQueries={apmQueries} onStatusChange={setAlertStatusFilter} onEsQueryChange={setEsQuery} diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx index 6400365aa87a1f..a2ab809092055d 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -401,5 +401,6 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { prepend, append, isSelected: key === selectedTab, + 'data-test-subj': `${key}Tab`, })); } diff --git a/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx index 2f92aa4b18f4c7..496010a14853a3 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx @@ -222,5 +222,6 @@ function useTabs({ selectedTabKey }: { selectedTabKey: Tab['key'] }) { label, append, isSelected: key === selectedTabKey, + 'data-test-subj': `${key}Tab`, })); } diff --git a/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts b/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts index 84913086f3c892..61b19327428e7d 100644 --- a/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts +++ b/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts @@ -16,6 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'error', 'timePicker', 'security']); const testSubjects = getService('testSubjects'); const appsMenu = getService('appsMenu'); + const observability = getService('observability'); const testData = { correlationsTab: 'Failed transaction correlations', @@ -149,6 +150,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ); }); }); + + it('navigates to the alerts tab', async function () { + await find.clickByCssSelector(`[data-test-subj="alertsTab"]`); + + await PageObjects.timePicker.timePickerExists(); + await PageObjects.timePicker.setCommonlyUsedTime('Last_15 minutes'); + + // Should show no data message + await retry.try(async () => { + await observability.overview.common.getAlertsTableNoDataOrFail(); + }); + }); }); }); } From 9685de25e06061dd9b9c4d71ee5e3b2a4b251bdf Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Tue, 4 Jul 2023 12:20:49 +0200 Subject: [PATCH 48/98] Modify open_close_signals route to avoid using update_by_query when possible (#159703) issue: https://github.com/elastic/security-team/issues/6829 ## Summary * Update `open_close_signals_route` to call `_update_by_query` API only when a query is provided. When the alert ids are provided it will call `_bulk` update instead. * It also unifies the response so both `updateAlerts` calls return the same interface. ### Context We still can call updateByQuery as many times as we need if the feature works with eventual consistency (search after writing returns stale data). If we need to show the updated data after writing, we need refresh: true, which is expensive (updateByQuery doesn't support refresh: wait_for). So, it makes sense to avoid calling refresh: true when we have the ids by using _bulk update with refresh: wait_for. ### How to test it? #### Old Alerts Table/Grouped Alerts Table * Select one or more rows * Open the bulk action menu and update the alert status Screenshot 2023-06-27 at 16 51 42 * It should update Alerts by id instead of sending a query and calling `update_by_query` API * Bulk updating all alert statuses doesn't change #### Close Alerts From Exceptions * Click on the row of actions for an alert * Select the 'Add rule exception' option Screenshot 2023-06-27 at 16 55 54 * Fill all required fields on the flyout + `Close this alert` * Click on "Add rule exception" * It should update the Alerts by id instead of sending a query and calling the `update_by_query` API * Bulk updating all alert statuses doesn't change ### 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 --- .../event_details/event_details.tsx | 4 - .../event_details/overview/index.tsx | 13 +- .../overview/status_popover_button.test.tsx | 1 - .../overview/status_popover_button.tsx | 4 +- .../common/components/events_viewer/index.tsx | 1 - .../events_viewer/use_alert_bulk_actions.tsx | 4 - .../bulk_actions/alert_bulk_actions.tsx | 3 - .../bulk_actions/alert_bulk_tags.test.tsx | 4 +- .../toolbar/bulk_actions/helpers.ts | 18 +++ .../bulk_actions/update_alerts.test.ts | 58 +++++++++ .../toolbar/bulk_actions/update_alerts.ts | 60 +++++++++ .../bulk_actions/use_bulk_action_items.tsx | 16 +-- .../bulk_actions/use_set_alert_tags.tsx | 2 +- .../toolbar/bulk_actions/use_update_alerts.ts | 41 ------- .../logic/use_close_alerts.tsx | 10 +- .../components/alerts_table/actions.tsx | 24 ++-- .../alerts_table/alerts_sub_grouping.tsx | 1 - .../group_take_action_items.test.tsx | 8 -- .../group_take_action_items.tsx | 8 +- .../timeline_actions/alert_context_menu.tsx | 1 - .../timeline_actions/use_alerts_actions.tsx | 3 - .../take_action_dropdown/index.test.tsx | 1 - .../components/take_action_dropdown/index.tsx | 3 - .../detection_engine/alerts/api.test.ts | 57 +++++++-- .../containers/detection_engine/alerts/api.ts | 29 ++++- .../detection_engine/alerts/types.ts | 10 +- .../use_alert_actions.tsx | 18 +-- .../public/flyout/right/footer.tsx | 11 +- .../event_details/expandable_event.tsx | 1 - .../event_details/flyout/footer.test.tsx | 1 - .../event_details/flyout/footer.tsx | 7 -- .../side_panel/event_details/flyout/index.tsx | 1 - .../side_panel/event_details/index.tsx | 1 - .../routes/signals/open_close_signals.test.ts | 47 +++++++ .../signals/open_close_signals_route.ts | 107 ++++++++++------ .../group10/open_close_signals.ts | 115 ++++++++++++++---- .../group10/set_alert_tags.ts | 4 +- .../utils/get_signal_status_empty_response.ts | 2 +- .../utils/set_signal_status.ts | 5 +- 39 files changed, 466 insertions(+), 238 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts delete mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx index a282a5c58a77c2..4457a669b19ae2 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx @@ -86,7 +86,6 @@ interface Props { data: TimelineEventsDetailsItem[]; detailsEcsData: Ecs | null; id: string; - indexName: string; isAlert: boolean; isDraggable?: boolean; rawEventData: object | undefined; @@ -154,7 +153,6 @@ const EventDetailsComponent: React.FC = ({ data, detailsEcsData, id, - indexName, isAlert, isDraggable, rawEventData, @@ -235,7 +233,6 @@ const EventDetailsComponent: React.FC = ({ contextId={scopeId} data={data} eventId={id} - indexName={indexName} scopeId={scopeId} handleOnEventClosed={handleOnEventClosed} isReadOnly={isReadOnly} @@ -328,7 +325,6 @@ const EventDetailsComponent: React.FC = ({ scopeId, data, id, - indexName, handleOnEventClosed, isReadOnly, renderer, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx index 497c3c5083b542..b33f777dcff41c 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx @@ -42,22 +42,12 @@ interface Props { data: TimelineEventsDetailsItem[]; eventId: string; handleOnEventClosed: () => void; - indexName: string; scopeId: string; isReadOnly?: boolean; } export const Overview = React.memo( - ({ - browserFields, - contextId, - data, - eventId, - handleOnEventClosed, - indexName, - scopeId, - isReadOnly, - }) => { + ({ browserFields, contextId, data, eventId, handleOnEventClosed, scopeId, isReadOnly }) => { const statusData = useMemo(() => { const item = find({ field: SIGNAL_STATUS_FIELD_NAME, category: 'kibana' }, data); return ( @@ -128,7 +118,6 @@ export const Overview = React.memo( eventId={eventId} contextId={contextId} enrichedFieldInfo={statusData} - indexName={indexName} scopeId={scopeId} handleOnEventClosed={handleOnEventClosed} /> diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx index 5a2f27e7a98c47..28a0a117bacc15 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx @@ -45,7 +45,6 @@ const props = { fields: {}, }, }, - indexName: '.internal.alerts-security.alerts-default-000001', scopeId: 'alerts-page', handleOnEventClosed: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx index 748b2d6a4779f2..ba88adaf99a48e 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx @@ -24,13 +24,12 @@ interface StatusPopoverButtonProps { eventId: string; contextId: string; enrichedFieldInfo: EnrichedFieldInfoWithValues; - indexName: string; scopeId: string; handleOnEventClosed: () => void; } export const StatusPopoverButton = React.memo( - ({ eventId, contextId, enrichedFieldInfo, indexName, scopeId, handleOnEventClosed }) => { + ({ eventId, contextId, enrichedFieldInfo, scopeId, handleOnEventClosed }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const togglePopover = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); const closePopover = useCallback(() => setIsPopoverOpen(false), []); @@ -51,7 +50,6 @@ export const StatusPopoverButton = React.memo( closePopover: closeAfterAction, eventId, scopeId, - indexName, alertStatus: enrichedFieldInfo.values[0] as Status, refetch: refetchGlobalQuery, }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 97c72e0c5e975f..b145fa81345a3f 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -496,7 +496,6 @@ const StatefulEventsViewerComponent: React.FC) => { + return { + query: { + bool: { + filter: { + terms: { + _id: eventIds, + }, + }, + }, + }, + }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts new file mode 100644 index 00000000000000..ccf45b091174dd --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.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 { updateAlertStatus } from './update_alerts'; + +const mockUpdateAlertStatusByIds = jest.fn().mockReturnValue(new Promise(() => {})); +const mockUpdateAlertStatusByQuery = jest.fn().mockReturnValue(new Promise(() => {})); + +jest.mock('../../../../detections/containers/detection_engine/alerts/api', () => { + return { + updateAlertStatusByQuery: (params: unknown) => mockUpdateAlertStatusByQuery(params), + updateAlertStatusByIds: (params: unknown) => mockUpdateAlertStatusByIds(params), + }; +}); + +const status = 'open'; + +describe('updateAlertStatus', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should throw an error if neither query nor signalIds are provided', () => { + expect(() => { + updateAlertStatus({ status }); + }).toThrowError('Either query or signalIds must be provided'); + }); + + it('should call updateAlertStatusByIds if signalIds are provided', () => { + const signalIds = ['1', '2']; + updateAlertStatus({ + status, + signalIds, + }); + expect(mockUpdateAlertStatusByIds).toHaveBeenCalledWith({ + status, + signalIds, + }); + expect(mockUpdateAlertStatusByQuery).not.toHaveBeenCalled(); + }); + + it('should call mockUpdateAlertStatusByQuery if query is provided', () => { + const query = { query: 'query' }; + updateAlertStatus({ + status, + query, + }); + expect(mockUpdateAlertStatusByIds).not.toHaveBeenCalled(); + expect(mockUpdateAlertStatusByQuery).toHaveBeenCalledWith({ + status, + query, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts new file mode 100644 index 00000000000000..2ffa195fee497e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.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 type { UpdateByQueryResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { Status } from '../../../../../common/detection_engine/schemas/common'; +import { + updateAlertStatusByIds, + updateAlertStatusByQuery, +} from '../../../../detections/containers/detection_engine/alerts/api'; + +interface UpdatedAlertsResponse { + updated: number; + version_conflicts: UpdateByQueryResponse['version_conflicts']; +} + +interface UpdatedAlertsProps { + status: Status; + query?: object; + signalIds?: string[]; + signal?: AbortSignal; +} + +/** + * Update alert status by query or signalIds. + * Either query or signalIds must be provided + * `signalIds` is the preferred way to update alerts because it is more cost effective on Serverless. + * + * @param status to update to('open' / 'closed' / 'acknowledged') + * @param index index to be updated + * @param query optional query object to update alerts by query. + * @param signalIds optional signalIds to update alerts by signalIds. + * @param signal to cancel request + * + * @throws An error if response is not OK + */ +export const updateAlertStatus = ({ + status, + query, + signalIds, + signal, +}: UpdatedAlertsProps): Promise => { + if (signalIds && signalIds.length > 0) { + return updateAlertStatusByIds({ status, signalIds, signal }).then(({ items }) => ({ + updated: items.length, + version_conflicts: 0, + })); + } else if (query) { + return updateAlertStatusByQuery({ status, query, signal }).then( + ({ updated, version_conflicts: conflicts }) => ({ + updated: updated ?? 0, + version_conflicts: conflicts, + }) + ); + } + throw new Error('Either query or signalIds must be provided'); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx index d2647023539e84..34b6a523efa599 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx @@ -14,22 +14,17 @@ import type { SetEventsLoading, } from '../../../../../common/types'; import * as i18n from './translations'; -import { useUpdateAlertsStatus } from './use_update_alerts'; +import { updateAlertStatus } from './update_alerts'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import { useStartTransaction } from '../../../lib/apm/use_start_transaction'; import { APM_USER_INTERACTIONS } from '../../../lib/apm/constants'; import type { AlertWorkflowStatus } from '../../../types'; import type { OnUpdateAlertStatusError, OnUpdateAlertStatusSuccess } from './types'; -export const getUpdateAlertsQuery = (eventIds: Readonly) => { - return { bool: { filter: { terms: { _id: eventIds } } } }; -}; - export interface BulkActionsProps { eventIds: string[]; currentStatus?: AlertWorkflowStatus; query?: string; - indexName: string; setEventsLoading: SetEventsLoading; setEventsDeleted: SetEventsDeleted; showAlertStatusActions?: boolean; @@ -42,7 +37,6 @@ export const useBulkActionItems = ({ eventIds, currentStatus, query, - indexName, setEventsLoading, showAlertStatusActions = true, setEventsDeleted, @@ -50,7 +44,6 @@ export const useBulkActionItems = ({ onUpdateFailure, customBulkActions, }: BulkActionsProps) => { - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const { startTransaction } = useStartTransaction(); @@ -116,11 +109,10 @@ export const useBulkActionItems = ({ try { setEventsLoading({ eventIds, isLoading: true }); - const response = await updateAlertStatus({ - index: indexName, status, - query: query ? JSON.parse(query) : getUpdateAlertsQuery(eventIds), + query: query && JSON.parse(query), + signalIds: eventIds, }); // TODO: Only delete those that were successfully updated from updatedRules @@ -140,8 +132,6 @@ export const useBulkActionItems = ({ [ setEventsLoading, eventIds, - updateAlertStatus, - indexName, query, setEventsDeleted, onAlertStatusUpdateSuccess, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx index 4805c8dc996fbe..9b211f9c259ccd 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx @@ -10,11 +10,11 @@ import type { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { getUpdateAlertsQuery } from '../../../../detections/components/alerts_table/actions'; import type { AlertTags } from '../../../../../common/detection_engine/schemas/common'; import { DETECTION_ENGINE_ALERT_TAGS_URL } from '../../../../../common/constants'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import * as i18n from './translations'; +import { getUpdateAlertsQuery } from './helpers'; export type SetAlertTagsFunc = ( tags: AlertTags, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts deleted file mode 100644 index 13ecf12b4479ca..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.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 type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { CoreStart } from '@kbn/core/public'; - -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { DETECTION_ENGINE_SIGNALS_STATUS_URL } from '../../../../../common/constants'; -import type { AlertWorkflowStatus } from '../../../types'; - -/** - * Update alert status by query - * - * @param status to update to('open' / 'closed' / 'acknowledged') - * @param index index to be updated - * @param query optional query object to update alerts by query. - - * - * @throws An error if response is not OK - */ -export const useUpdateAlertsStatus = (): { - updateAlertStatus: (params: { - status: AlertWorkflowStatus; - index: string; - query: object; - }) => Promise; -} => { - const { http } = useKibana().services; - return { - updateAlertStatus: async ({ status, index, query }) => { - return http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { - method: 'POST', - body: JSON.stringify({ status, query }), - }); - }, - }; -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx index a6dce444527d0d..4c2493fbb81e4d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx @@ -8,9 +8,6 @@ import { useEffect, useRef, useState } from 'react'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; - -import { updateAlertStatus } from '../../../detections/containers/detection_engine/alerts/api'; -import { getUpdateAlertsQuery } from '../../../detections/components/alerts_table/actions'; import { buildAlertStatusesFilter, buildAlertsFilter, @@ -21,6 +18,7 @@ import { prepareExceptionItemsForBulkClose } from '../utils/helpers'; import * as i18nCommon from '../../../common/translations'; import * as i18n from './translations'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; /** * Closes alerts. @@ -65,7 +63,7 @@ export const useCloseAlertsFromExceptions = (): ReturnUseCloseAlertsFromExceptio let bulkResponse: estypes.UpdateByQueryResponse | undefined; if (alertIdToClose != null) { alertIdResponse = await updateAlertStatus({ - query: getUpdateAlertsQuery([alertIdToClose]), + signalIds: [alertIdToClose], status: 'closed', signal: abortCtrl.signal, }); @@ -88,9 +86,7 @@ export const useCloseAlertsFromExceptions = (): ReturnUseCloseAlertsFromExceptio ); bulkResponse = await updateAlertStatus({ - query: { - query: filter, - }, + query: filter, status: 'closed', signal: abortCtrl.signal, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 8e8973310056e8..28d46d96953b8c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -44,7 +44,6 @@ import { import type { TimelineResult } from '../../../../common/types/timeline/api'; import { TimelineId } from '../../../../common/types/timeline'; import { TimelineStatus, TimelineType } from '../../../../common/types/timeline/api'; -import { updateAlertStatus } from '../../containers/detection_engine/alerts/api'; import type { SendAlertToTimelineActionProps, ThresholdAggregationData, @@ -83,20 +82,7 @@ import { DEFAULT_FROM_MOMENT, DEFAULT_TO_MOMENT, } from '../../../common/utils/default_date_settings'; - -export const getUpdateAlertsQuery = (eventIds: Readonly) => { - return { - query: { - bool: { - filter: { - terms: { - _id: eventIds, - }, - }, - }, - }, - }; -}; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; export const updateAlertStatusAction = async ({ query, @@ -110,8 +96,12 @@ export const updateAlertStatusAction = async ({ try { setEventsLoading({ eventIds: alertIds, isLoading: true }); - const queryObject = query ? { query: JSON.parse(query) } : getUpdateAlertsQuery(alertIds); - const response = await updateAlertStatus({ query: queryObject, status: selectedStatus }); + const response = await updateAlertStatus({ + query: query && JSON.parse(query), + status: selectedStatus, + signalIds: alertIds, + }); + // TODO: Only delete those that were successfully updated from updatedRules setEventsDeleted({ eventIds: alertIds, isDeleted: true }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx index f2fa9e8bb6d1b0..2465de8f14c262 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx @@ -235,7 +235,6 @@ export const GroupedSubLevelComponent: React.FC = ({ ); const takeActionItems = useGroupTakeActionsItems({ - indexName: indexPattern.title, currentStatus: currentAlertStatusFilterValue, showAlertStatusActions: hasIndexWrite && hasIndexMaintenance, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx index d663b2abc2c611..6470c9a4abc66c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx @@ -35,7 +35,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -53,7 +52,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: [], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -71,7 +69,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['open', 'closed'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -89,7 +86,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['open'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -110,7 +106,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['closed'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -131,7 +126,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['acknowledged'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -151,7 +145,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: false, }), { @@ -167,7 +160,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx index 5d151d2e4cc886..1384c592162dbe 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx @@ -15,7 +15,7 @@ import { useStartTransaction } from '../../../../common/lib/apm/use_start_transa import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import type { AlertWorkflowStatus } from '../../../../common/types'; import { APM_USER_INTERACTIONS } from '../../../../common/lib/apm/constants'; -import { useUpdateAlertsStatus } from '../../../../common/components/toolbar/bulk_actions/use_update_alerts'; +import { updateAlertStatus } from '../../../../common/components/toolbar/bulk_actions/update_alerts'; import { BULK_ACTION_ACKNOWLEDGED_SELECTED, BULK_ACTION_CLOSE_SELECTED, @@ -33,16 +33,13 @@ import type { StartServices } from '../../../../types'; export interface TakeActionsProps { currentStatus?: Status[]; - indexName: string; showAlertStatusActions?: boolean; } export const useGroupTakeActionsItems = ({ currentStatus, - indexName, showAlertStatusActions = true, }: TakeActionsProps) => { - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const { startTransaction } = useStartTransaction(); const getGlobalQuerySelector = inputsSelectors.globalQuery(); @@ -163,7 +160,6 @@ export const useGroupTakeActionsItems = ({ try { const response = await updateAlertStatus({ - index: indexName, status, query: query ? JSON.parse(query) : {}, }); @@ -176,8 +172,6 @@ export const useGroupTakeActionsItems = ({ [ startTransaction, reportAlertsGroupingTakeActionClick, - updateAlertStatus, - indexName, onAlertStatusUpdateSuccess, onAlertStatusUpdateFailure, ] diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 57b04914461219..a9e39583323222 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -177,7 +177,6 @@ const AlertContextMenuComponent: React.FC void; eventId: string; scopeId: string; - indexName: string; refetch?: () => void; } @@ -28,7 +27,6 @@ export const useAlertsActions = ({ closePopover, eventId, scopeId, - indexName, refetch, }: Props) => { const dispatch = useDispatch(); @@ -63,7 +61,6 @@ export const useAlertsActions = ({ const actionItems = useBulkActionItems({ eventIds: [eventId], currentStatus: alertStatus as AlertWorkflowStatus, - indexName, setEventsLoading: localSetEventsLoading, setEventsDeleted, onUpdateSuccess: onStatusUpdate, diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx index 1a9c71b68bc4f9..5874abe8397c50 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx @@ -99,7 +99,6 @@ describe('take action dropdown', () => { detailsData: generateAlertDetailsDataMock() as TimelineEventsDetailsItem[], ecsData: getDetectionAlertMock(), handleOnEventClosed: jest.fn(), - indexName: 'index', isHostIsolationPanelOpen: false, loadingEventDetails: false, onAddEventFilterClick: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx index 666db984054548..107af049ae6aff 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx @@ -48,7 +48,6 @@ export interface TakeActionDropdownProps { detailsData: TimelineEventsDetailsItem[] | null; ecsData?: Ecs; handleOnEventClosed: () => void; - indexName: string; isHostIsolationPanelOpen: boolean; loadingEventDetails: boolean; onAddEventFilterClick: () => void; @@ -65,7 +64,6 @@ export const TakeActionDropdown = React.memo( detailsData, ecsData, handleOnEventClosed, - indexName, isHostIsolationPanelOpen, loadingEventDetails, onAddEventFilterClick, @@ -180,7 +178,6 @@ export const TakeActionDropdown = React.memo( alertStatus: actionsData.alertStatus, closePopover: closePopoverAndFlyout, eventId: actionsData.eventId, - indexName, refetch, scopeId, }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts index eea9500e868a83..601bbf94986172 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts @@ -16,11 +16,12 @@ import { } from './mock'; import { fetchQueryAlerts, - updateAlertStatus, getSignalIndex, getUserPrivilege, createSignalIndex, createHostIsolation, + updateAlertStatusByQuery, + updateAlertStatusByIds, } from './api'; import { coreMock } from '@kbn/core/public/mocks'; @@ -57,40 +58,40 @@ describe('Detections Alerts API', () => { }); }); - describe('updateAlertStatus', () => { + describe('updateAlertStatusByQuery', () => { beforeEach(() => { fetchMock.mockClear(); fetchMock.mockResolvedValue({}); }); test('check parameter url, body when closing an alert', async () => { - await updateAlertStatus({ + await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'closed', }); expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { - body: '{"conflicts":"proceed","status":"closed","bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}', + body: '{"conflicts":"proceed","status":"closed","query":{"bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}}', method: 'POST', signal: abortCtrl.signal, }); }); test('check parameter url, body when opening an alert', async () => { - await updateAlertStatus({ + await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'open', }); expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { - body: '{"conflicts":"proceed","status":"open","bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}', + body: '{"conflicts":"proceed","status":"open","query":{"bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}}', method: 'POST', signal: abortCtrl.signal, }); }); test('happy path', async () => { - const alertsResp = await updateAlertStatus({ + const alertsResp = await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'open', @@ -99,6 +100,48 @@ describe('Detections Alerts API', () => { }); }); + describe('updateAlertStatusById', () => { + beforeEach(() => { + fetchMock.mockClear(); + fetchMock.mockResolvedValue({}); + }); + + test('check parameter url, body when closing an alert', async () => { + await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'closed', + }); + expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { + body: '{"status":"closed","signal_ids":["123"]}', + method: 'POST', + signal: abortCtrl.signal, + }); + }); + + test('check parameter url, body when opening an alert', async () => { + await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'open', + }); + expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { + body: '{"status":"open","signal_ids":["123"]}', + method: 'POST', + signal: abortCtrl.signal, + }); + }); + + test('happy path', async () => { + const alertsResp = await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'open', + }); + expect(alertsResp).toEqual({}); + }); + }); + describe('getSignalIndex', () => { beforeEach(() => { fetchMock.mockClear(); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts index d8d1bae460a6d1..91430d4818317d 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts @@ -24,9 +24,10 @@ import type { QueryAlerts, AlertSearchResponse, AlertsIndex, - UpdateAlertStatusProps, + UpdateAlertStatusByQueryProps, CasesFromAlertsResponse, CheckSignalIndex, + UpdateAlertStatusByIdsProps, } from './types'; import { isolateHost, unIsolateHost } from '../../../../common/lib/endpoint_isolation'; import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables'; @@ -84,14 +85,34 @@ export const fetchQueryRuleRegistryAlerts = async ({ * * @throws An error if response is not OK */ -export const updateAlertStatus = async ({ +export const updateAlertStatusByQuery = async ({ query, status, signal, -}: UpdateAlertStatusProps): Promise => +}: UpdateAlertStatusByQueryProps): Promise => KibanaServices.get().http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { method: 'POST', - body: JSON.stringify({ conflicts: 'proceed', status, ...query }), + body: JSON.stringify({ conflicts: 'proceed', status, query }), + signal, + }); + +/** + * Update alert status by signalIds + * + * @param signalIds List of signal ids to update + * @param status to update to('open' / 'closed' / 'acknowledged') + * @param signal AbortSignal for cancelling request + * + * @throws An error if response is not OK + */ +export const updateAlertStatusByIds = async ({ + signalIds, + status, + signal, +}: UpdateAlertStatusByIdsProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { + method: 'POST', + body: JSON.stringify({ status, signal_ids: signalIds }), signal, }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts index 9d39a3f39770f4..717f2bee7a7686 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts @@ -38,10 +38,16 @@ export interface AlertSearchResponse }; } -export interface UpdateAlertStatusProps { +export interface UpdateAlertStatusByQueryProps { query: object; status: Status; - signal?: AbortSignal; // TODO: implement cancelling + signal?: AbortSignal; +} + +export interface UpdateAlertStatusByIdsProps { + signalIds: string[]; + status: Status; + signal?: AbortSignal; } export interface AlertsIndex { diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx index 0f214d2f9b959f..5ac7628f5376fb 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx @@ -12,14 +12,12 @@ import { buildEsQuery } from '@kbn/es-query'; import type { TableId } from '@kbn/securitysolution-data-table'; import type { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { APM_USER_INTERACTIONS } from '../../../common/lib/apm/constants'; -import { useUpdateAlertsStatus } from '../../../common/components/toolbar/bulk_actions/use_update_alerts'; -import { useSourcererDataView } from '../../../common/containers/sourcerer'; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useStartTransaction } from '../../../common/lib/apm/use_start_transaction'; import type { AlertWorkflowStatus } from '../../../common/types'; import { FILTER_CLOSED, FILTER_OPEN, FILTER_ACKNOWLEDGED } from '../../../../common/types'; import * as i18n from '../translations'; -import { getUpdateAlertsQuery } from '../../components/alerts_table/actions'; import { buildTimeRangeFilter } from '../../components/alerts_table/helpers'; interface UseBulkAlertActionItemsArgs { @@ -45,7 +43,6 @@ export const useBulkAlertActionItems = ({ }: UseBulkAlertActionItemsArgs) => { const { startTransaction } = useStartTransaction(); - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const onAlertStatusUpdateSuccess = useCallback( @@ -92,8 +89,6 @@ export const useBulkAlertActionItems = ({ [addError] ); - const { selectedPatterns } = useSourcererDataView(scopeId); - const getOnAction = useCallback( (status: AlertWorkflowStatus) => { const onActionClick: BulkActionsConfig['onClick'] = async ( @@ -103,14 +98,13 @@ export const useBulkAlertActionItems = ({ clearSelection, refresh ) => { - const ids = items.map((item) => item._id); - let query: Record = getUpdateAlertsQuery(ids).query; + let ids: string[] | undefined = items.map((item) => item._id); + let query: Record | undefined; if (isSelectAllChecked) { const timeFilter = buildTimeRangeFilter(from, to); query = buildEsQuery(undefined, [], [...timeFilter, ...filters], undefined); - } - if (query) { + ids = undefined; startTransaction({ name: APM_USER_INTERACTIONS.BULK_QUERY_STATUS_UPDATE }); } else if (items.length > 1) { startTransaction({ name: APM_USER_INTERACTIONS.BULK_STATUS_UPDATE }); @@ -121,9 +115,9 @@ export const useBulkAlertActionItems = ({ try { setAlertLoading(true); const response = await updateAlertStatus({ - index: selectedPatterns.join(','), status, query, + signalIds: ids, }); setAlertLoading(false); @@ -150,8 +144,6 @@ export const useBulkAlertActionItems = ({ [ onAlertStatusUpdateFailure, onAlertStatusUpdateSuccess, - updateAlertStatus, - selectedPatterns, startTransaction, filters, from, diff --git a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx index d3f035ce64065b..d0980141ebfcc3 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx @@ -17,14 +17,8 @@ import { useHostIsolationTools } from '../../timelines/components/side_panel/eve */ export const PanelFooter: FC = memo(() => { const { closeFlyout } = useExpandableFlyoutContext(); - const { - eventId, - indexName, - dataFormattedForFieldBrowser, - dataAsNestedObject, - refetchFlyoutData, - scopeId, - } = useRightPanelContext(); + const { dataFormattedForFieldBrowser, dataAsNestedObject, refetchFlyoutData, scopeId } = + useRightPanelContext(); const { isHostIsolationPanelOpen, showHostIsolationPanel } = useHostIsolationTools(); @@ -36,7 +30,6 @@ export const PanelFooter: FC = memo(() => { ( detailsEcsData={detailsEcsData} id={event.eventId} isAlert={isAlert} - indexName={event.indexName} isDraggable={isDraggable} rawEventData={rawEventData} scopeId={scopeId} diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx index 6f069cb8dc83ed..ab24a16ca1a935 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx @@ -115,7 +115,6 @@ const defaultProps = { isHostIsolationPanelOpen: false, handleOnEventClosed: jest.fn(), onAddIsolationStatusClick: jest.fn(), - expandedEvent: { eventId: ecsData._id, indexName: '' }, detailsData: mockAlertDetailsDataWithIsObject, refetchFlyoutData: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx index b91f01885e9d5d..9234a05bf1f074 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx @@ -26,11 +26,6 @@ import { OsqueryFlyout } from '../../../../../detections/components/osquery/osqu interface FlyoutFooterProps { detailsData: TimelineEventsDetailsItem[] | null; detailsEcsData: Ecs | null; - expandedEvent: { - eventId: string; - indexName: string; - refetch?: () => void; - }; handleOnEventClosed: () => void; isHostIsolationPanelOpen: boolean; isReadOnly?: boolean; @@ -52,7 +47,6 @@ export const FlyoutFooterComponent = React.memo( ({ detailsData, detailsEcsData, - expandedEvent, handleOnEventClosed, isHostIsolationPanelOpen, isReadOnly, @@ -162,7 +156,6 @@ export const FlyoutFooterComponent = React.memo( onAddIsolationStatusClick={onAddIsolationStatusClick} refetchFlyoutData={refetchFlyoutData} refetch={refetchAll} - indexName={expandedEvent.indexName} scopeId={scopeId} onOsqueryClick={setOsqueryFlyoutOpenWithAgentId} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx index 2a9f30d0ec29b4..d52fa2331e0167 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx @@ -136,7 +136,6 @@ export const useToGetInternalFlyout = () => { = ({ { status_code: 500, }); }); + + test('calls "esClient.updateByQuery" with queryId when query is defined', async () => { + await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); + expect(context.core.elasticsearch.client.asCurrentUser.updateByQuery).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.objectContaining({ + query: expect.objectContaining({ + bool: { filter: typicalSetStatusSignalByQueryPayload().query }, + }), + }), + }) + ); + }); + + test('calls "esClient.bulk" with signalIds when ids are defined', async () => { + await server.inject( + getSetSignalStatusByIdsRequest(), + requestContextMock.convertContext(context) + ); + expect(context.core.elasticsearch.client.asCurrentUser.bulk).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.arrayContaining([ + { + update: { + _id: 'somefakeid1', + _index: '.alerts-security.alerts-default', + }, + }, + { + script: expect.anything(), + }, + { + update: { + _id: 'somefakeid2', + _index: '.alerts-security.alerts-default', + }, + }, + { + script: expect.anything(), + }, + ]), + }) + ); + }); }); describe('request validation', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index 9681d22d911986..199e0c8f412f4d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -8,7 +8,7 @@ import { get } from 'lodash'; import { transformError } from '@kbn/securitysolution-es-utils'; import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; -import type { Logger } from '@kbn/core/server'; +import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { setSignalStatusValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/set_signal_status_type_dependents'; import type { SetSignalsStatusSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/set_signal_status_schema'; import { setSignalsStatusSchema } from '../../../../../common/detection_engine/schemas/request/set_signal_status_schema'; @@ -87,40 +87,20 @@ export const setSignalsStatusRoute = ( } } - let queryObject; - if (signalIds) { - queryObject = { ids: { values: signalIds } }; - } - if (query) { - queryObject = { - bool: { - filter: query, - }, - }; - } try { - const body = await esClient.updateByQuery({ - index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, - conflicts: conflicts ?? 'abort', - // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#_refreshing_shards_2 - // Note: Before we tried to use "refresh: wait_for" but I do not think that was available and instead it defaulted to "refresh: true" - // but the tests do not pass with "refresh: false". If at some point a "refresh: wait_for" is implemented, we should use that instead. - refresh: true, - body: { - script: { - source: `if (ctx._source['${ALERT_WORKFLOW_STATUS}'] != null) { - ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}' - } - if (ctx._source.signal != null && ctx._source.signal.status != null) { - ctx._source.signal.status = '${status}' - }`, - lang: 'painless', - }, - query: queryObject, - }, - ignore_unavailable: true, - }); - return response.ok({ body }); + if (signalIds) { + const body = await updateSignalsStatusByIds(status, signalIds, spaceId, esClient); + return response.ok({ body }); + } else { + const body = await updateSignalsStatusByQuery( + status, + query, + { conflicts: conflicts ?? 'abort' }, + spaceId, + esClient + ); + return response.ok({ body }); + } } catch (err) { // error while getting or updating signal with id: id in signal index .siem-signals const error = transformError(err); @@ -132,3 +112,62 @@ export const setSignalsStatusRoute = ( } ); }; + +const updateSignalsStatusByIds = async ( + status: SetSignalsStatusSchemaDecoded['status'], + signalsId: string[], + spaceId: string, + esClient: ElasticsearchClient +) => + esClient.bulk({ + index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, + refresh: 'wait_for', + body: signalsId.flatMap((signalId) => [ + { + update: { _id: signalId, _index: `${DEFAULT_ALERTS_INDEX}-${spaceId}` }, + }, + { + script: getUpdateSignalStatusScript(status), + }, + ]), + }); + +/** + * Please avoid using `updateSignalsStatusByQuery` when possible, use `updateSignalsStatusByIds` instead. + * + * This method calls `updateByQuery` with `refresh: true` which is expensive on serverless. + */ +const updateSignalsStatusByQuery = async ( + status: SetSignalsStatusSchemaDecoded['status'], + query: object | undefined, + options: { conflicts: 'abort' | 'proceed' }, + spaceId: string, + esClient: ElasticsearchClient +) => + esClient.updateByQuery({ + index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, + conflicts: options.conflicts, + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#_refreshing_shards_2 + // Note: Before we tried to use "refresh: wait_for" but I do not think that was available and instead it defaulted to "refresh: true" + // but the tests do not pass with "refresh: false". If at some point a "refresh: wait_for" is implemented, we should use that instead. + refresh: true, + body: { + script: getUpdateSignalStatusScript(status), + query: { + bool: { + filter: query, + }, + }, + }, + ignore_unavailable: true, + }); + +const getUpdateSignalStatusScript = (status: SetSignalsStatusSchemaDecoded['status']) => ({ + source: `if (ctx._source['${ALERT_WORKFLOW_STATUS}'] != null) { + ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}' + } + if (ctx._source.signal != null && ctx._source.signal.status != null) { + ctx._source.signal.status = '${status}' + }`, + lang: 'painless', +}); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts index c9fb6334ab8c55..72262b12453f89 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts @@ -20,7 +20,7 @@ import { createSignalsIndex, deleteAllAlerts, setSignalStatus, - getAlertUpdateEmptyResponse, + getAlertUpdateByQueryEmptyResponse, getQuerySignalIds, deleteAllRules, createRule, @@ -41,33 +41,106 @@ export default ({ getService }: FtrProviderContext) => { describe('open_close_signals', () => { describe('validation checks', () => { - it('should not give errors when querying and the signals index does not exist yet', async () => { - const { body } = await supertest - .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) - .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) - .expect(200); + describe('update by ids', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); - // remove any server generated items that are indeterministic - delete body.took; + // remove any server generated items that are nondeterministic + body.items.forEach((_: any, index: number) => { + delete body.items[index].update.error.index_uuid; + }); + delete body.took; + + expect(body).to.eql({ + errors: true, + items: [ + { + update: { + _id: '123', + _index: '.internal.alerts-security.alerts-default-000001', + error: { + index: '.internal.alerts-security.alerts-default-000001', + reason: '[123]: document missing', + shard: '0', + type: 'document_missing_exception', + }, + status: 404, + }, + }, + ], + }); + }); - expect(body).to.eql(getAlertUpdateEmptyResponse()); + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest, log); + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); + + // remove any server generated items that are nondeterministic + body.items.forEach((_: any, index: number) => { + delete body.items[index].update.error.index_uuid; + }); + delete body.took; + + expect(body).to.eql({ + errors: true, + items: [ + { + update: { + _id: '123', + _index: '.internal.alerts-security.alerts-default-000001', + error: { + index: '.internal.alerts-security.alerts-default-000001', + reason: '[123]: document missing', + shard: '0', + type: 'document_missing_exception', + }, + status: 404, + }, + }, + ], + }); + + await deleteAllAlerts(supertest, log, es); + }); }); - it('should not give errors when querying and the signals index does exist and is empty', async () => { - await createSignalsIndex(supertest, log); - const { body } = await supertest - .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) - .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) - .expect(200); + describe('update by query', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ query: { match_all: {} }, status: 'open' })) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); + }); + + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest, log); + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ query: { match_all: {} }, status: 'open' })) + .expect(200); - // remove any server generated items that are indeterministic - delete body.took; + // remove any server generated items that are indeterministic + delete body.took; - expect(body).to.eql(getAlertUpdateEmptyResponse()); + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); - await deleteAllAlerts(supertest, log, es); + await deleteAllAlerts(supertest, log, es); + }); }); describe('tests with auditbeat data', () => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts index c3334cbe1c5046..970d8b5426acd5 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts @@ -17,7 +17,6 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, deleteAllAlerts, - getAlertUpdateEmptyResponse, getQuerySignalIds, deleteAllRules, createRule, @@ -25,6 +24,7 @@ import { getSignalsByIds, waitForRuleSuccess, getRuleForSignalTesting, + getAlertUpdateByQueryEmptyResponse, } from '../../utils'; import { buildAlertTagsQuery, setAlertTags } from '../../utils/set_alert_tags'; @@ -47,7 +47,7 @@ export default ({ getService }: FtrProviderContext) => { // remove any server generated items that are indeterministic delete body.took; - expect(body).to.eql(getAlertUpdateEmptyResponse()); + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); }); it('should give errors when duplicate tags exist in both tags_to_add and tags_to_remove', async () => { diff --git a/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts b/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts index 3a7d612fea8548..953d1ac4e77f87 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const getAlertUpdateEmptyResponse = () => ({ +export const getAlertUpdateByQueryEmptyResponse = () => ({ timed_out: false, total: 0, updated: 0, diff --git a/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts b/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts index 2cd4cb557f6373..37a10bd23f9a9a 100644 --- a/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts +++ b/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts @@ -12,11 +12,14 @@ import type { export const setSignalStatus = ({ signalIds, + query, status, }: { - signalIds: SignalIds; + signalIds?: SignalIds; + query?: object; status: Status; }) => ({ signal_ids: signalIds, + query, status, }); From 122977ef09a523ed7545b6639480979a5eaa83c8 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Tue, 4 Jul 2023 13:53:39 +0300 Subject: [PATCH 49/98] [Cloud Security] Fix search in benchmark page (#161093) --- .../public/pages/rules/use_csp_rules.ts | 2 +- .../routes/csp_rule_template/get_csp_rule_template.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index a5aee47c7c1cc7..e0870d1e64b018 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -27,7 +27,7 @@ export const useFindCspRuleTemplates = ( [CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, { search, page, perPage, packagePolicyId }], () => { return http.get(FIND_CSP_RULE_TEMPLATE_ROUTE_PATH, { - query: { packagePolicyId, page, perPage }, + query: { packagePolicyId, page, perPage, search }, version: FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION, }); } diff --git a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts index 63e2bdb6ee1020..fb6e0e7c53ab0a 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts @@ -60,9 +60,9 @@ const findCspRuleTemplateHandler = async ( filter: getBenchmarkTypeFilter(benchmarkId), }); - const cspRulesTemplates = cspRulesTemplatesSo.saved_objects.map((cspRuleTemplate) => { - return { ...cspRuleTemplate.attributes }; - }); + const cspRulesTemplates = cspRulesTemplatesSo.saved_objects.map( + (cspRuleTemplate) => cspRuleTemplate.attributes + ); return { items: cspRulesTemplates, From bfe6cf82e0bc47818f55203a60b381217e88b515 Mon Sep 17 00:00:00 2001 From: Giorgos Bamparopoulos Date: Tue, 4 Jul 2023 12:04:40 +0100 Subject: [PATCH 50/98] [DOCS] Update the 8.8.2 release notes (#161163) --- docs/CHANGELOG.asciidoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 4685d40e5ddbf4..5d915c8feb6a66 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -54,7 +54,6 @@ Review the following information about the {kib} 8.8.2 release. === Bug Fixes APM:: -* Circuit breaker and performance improvements for service map {kibana-pull}159883[#159883] * Fixes the latency graph displaying all service transactions, rather than the selected one, on the transaction detail page {kibana-pull}159085[#159085] Dashboard:: From ad5930927cca5c1587eba5e944463198f044029c Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 4 Jul 2023 07:25:35 -0400 Subject: [PATCH 51/98] skip failing test suite (#161157) --- test/functional/apps/discover/group3/_request_counts.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/discover/group3/_request_counts.ts b/test/functional/apps/discover/group3/_request_counts.ts index c4f5676f357e53..24698bcb45c11e 100644 --- a/test/functional/apps/discover/group3/_request_counts.ts +++ b/test/functional/apps/discover/group3/_request_counts.ts @@ -27,7 +27,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const queryBar = getService('queryBar'); const elasticChart = getService('elasticChart'); - describe('discover request counts', function describeIndexTests() { + // Failing: See https://github.com/elastic/kibana/issues/161157 + describe.skip('discover request counts', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); From 54e613b1d9341497d40a2c671c527de18beec165 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Tue, 4 Jul 2023 05:13:54 -0700 Subject: [PATCH 52/98] [Security Solution][Fix] Alert Page Filter Controls should not ignore Invalid Selections (#160374) This PR changes how Alert Page Filter Controls Work. ## Before 1. Filter Controls use to ignore invalid Selections. For example, if User has selected `Open` as the filter, but there is actually no alert with Status `Open`, filters would ignore that selection and would proceed to show other alerts ( which are NOT `Open`) . - It seemed it was confusing users. [This bug](https://github.com/elastic/kibana/issues/159606) and [messages in community slack](https://elasticstack.slack.com/archives/CNRTGB9A4/p1686937708085629?thread_ts=1686841414.978319&cid=CNRTGB9A4) are the examples. @paulewing also emphasized this. - Below video shows what I mean. https://github.com/elastic/kibana/assets/7485038/01771587-e4e8-4331-9535-4ffa09877c02 ## After 1. With this Change Control Filters no longer ignore invalid selection. So if user has chosen to show only `Open` Alerts. Then that filter will be taken into account even though no alert with `Open` exists and a empty table will be show. - Here is a video to demonstrate it. https://github.com/elastic/kibana/assets/7485038/62b17762-16c0-471f-8480-e9f46e2ca5ef --- .../pipelines/pull_request/pipeline.ts | 1 + .../security_solution/common/constants.ts | 7 +- .../alerts/detection_page_filters.cy.ts | 98 ++++---- .../cypress/screens/common/filter_group.ts | 8 +- .../security_solution/cypress/tasks/alerts.ts | 33 +-- .../cypress/tasks/common/filter_group.ts | 12 +- .../components/filter_group/constants.ts | 19 ++ .../components/filter_group/context_menu.tsx | 10 +- .../filter_group/filter_group.test.tsx | 76 ++++-- .../common/components/filter_group/index.tsx | 210 ++++++++-------- .../common/components/filter_group/types.ts | 11 +- .../components/filter_group/utils.test.ts | 225 +++++++++++++++++- .../common/components/filter_group/utils.ts | 114 ++++++++- 13 files changed, 617 insertions(+), 207 deletions(-) diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts index 70a06d1d97e8d0..98bd47597bd3eb 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts @@ -60,6 +60,7 @@ const uploadPipeline = (pipelineContent: string | object) => { if ( (await doAnyChangesMatch([ + /^src\/plugins\/controls/, /^packages\/kbn-securitysolution-.*/, /^x-pack\/plugins\/lists/, /^x-pack\/plugins\/security_solution/, diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index a311cae265f33b..7150d08da713d9 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -6,6 +6,7 @@ */ import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import type { AddOptionsListControlProps } from '@kbn/controls-plugin/public'; import * as i18n from './translations'; /** @@ -507,19 +508,23 @@ export const MAX_NUMBER_OF_NEW_TERMS_FIELDS = 3; export const BULK_ADD_TO_TIMELINE_LIMIT = 2000; -export const DEFAULT_DETECTION_PAGE_FILTERS = [ +export const DEFAULT_DETECTION_PAGE_FILTERS: Array< + Omit & { persist?: boolean } +> = [ { title: 'Status', fieldName: 'kibana.alert.workflow_status', selectedOptions: ['open'], hideActionBar: true, persist: true, + hideExists: true, }, { title: 'Severity', fieldName: 'kibana.alert.severity', selectedOptions: [], hideActionBar: true, + hideExists: true, }, { title: 'User', diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts index 6e77002c945dd4..acff1f8acb4261 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts @@ -6,13 +6,13 @@ */ import { encode } from '@kbn/rison'; +import type { FilterItemObj } from '../../../../public/common/components/filter_group/types'; import { getNewRule } from '../../../objects/rule'; import { CONTROL_FRAMES, CONTROL_FRAME_TITLE, CONTROL_POPOVER, FILTER_GROUP_CHANGED_BANNER, - OPTION_IGNORED, OPTION_LIST_LABELS, OPTION_LIST_VALUES, OPTION_SELECTABLE, @@ -29,7 +29,6 @@ import { formatPageFilterSearchParam } from '../../../../common/utils/format_pag import { closePageFilterPopover, markAcknowledgedFirstAlert, - openFirstAlert, openPageFilterPopover, resetFilters, selectCountTable, @@ -38,7 +37,7 @@ import { waitForAlerts, waitForPageFilters, } from '../../../tasks/alerts'; -import { ALERTS_COUNT, ALERTS_REFRESH_BTN } from '../../../screens/alerts'; +import { ALERTS_COUNT, ALERTS_REFRESH_BTN, EMPTY_ALERT_TABLE } from '../../../screens/alerts'; import { kqlSearch, navigateFromHeaderTo } from '../../../tasks/security_header'; import { ALERTS, CASES } from '../../../screens/security_header'; import { @@ -84,7 +83,9 @@ const customFilters = [ title: 'Rule Name', }, ]; -const assertFilterControlsWithFilterObject = (filterObject = DEFAULT_DETECTION_PAGE_FILTERS) => { +const assertFilterControlsWithFilterObject = ( + filterObject: FilterItemObj[] = DEFAULT_DETECTION_PAGE_FILTERS +) => { cy.get(CONTROL_FRAMES).should((sub) => { expect(sub.length).eq(filterObject.length); }); @@ -97,18 +98,16 @@ const assertFilterControlsWithFilterObject = (filterObject = DEFAULT_DETECTION_P filterObject.forEach((filter, idx) => { cy.get(OPTION_LIST_VALUES(idx)).should((sub) => { - expect(sub.text().replace(',', '')).satisfy((txt: string) => { - return txt.startsWith( - filter.selectedOptions && filter.selectedOptions.length > 0 - ? filter.selectedOptions.join('') - : '' - ); - }); + const selectedOptionsText = + filter.selectedOptions && filter.selectedOptions.length > 0 + ? filter.selectedOptions.join('') + : ''; + expect(sub.text().replace(',', '').replace(' ', '')).to.have.string(selectedOptionsText); }); }); }; -describe('Detections : Page Filters', () => { +describe(`Detections : Page Filters`, () => { before(() => { cleanKibana(); createRule(getNewRule({ rule_id: 'custom_rule_filters' })); @@ -130,6 +129,9 @@ describe('Detections : Page Filters', () => { login(); visit(ALERTS_URL); waitForAlerts(); + }); + + afterEach(() => { resetFilters(); }); @@ -182,10 +184,11 @@ describe('Detections : Page Filters', () => { it('Page filters are loaded with custom values provided in the URL', () => { const NEW_FILTERS = DEFAULT_DETECTION_PAGE_FILTERS.filter((item) => item.persist).map( (filter) => { - if (filter.title === 'Status') { - filter.selectedOptions = ['open', 'acknowledged']; - } - return filter; + return { + ...filter, + selectedOptions: + filter.title === 'Status' ? ['open', 'acknowledged'] : filter.selectedOptions, + }; } ); @@ -231,40 +234,39 @@ describe('Detections : Page Filters', () => { cy.get(FILTER_GROUP_CHANGED_BANNER).should('be.visible'); }); - it(`Alert list is updated when the alerts are updated`, () => { - // mark status of one alert to be acknowledged - selectCountTable(); - cy.get(ALERTS_COUNT) - .invoke('text') - .then((noOfAlerts) => { - const originalAlertCount = noOfAlerts.split(' ')[0]; - markAcknowledgedFirstAlert(); - waitForAlerts(); - cy.get(OPTION_LIST_VALUES(0)).click(); - cy.get(OPTION_SELECTABLE(0, 'acknowledged')).should('be.visible').trigger('click'); - cy.get(ALERTS_COUNT) - .invoke('text') - .should((newAlertCount) => { - expect(newAlertCount.split(' ')[0]).eq(String(parseInt(originalAlertCount, 10) - 1)); - }); - }); + context('with data modificiation', () => { + after(() => { + cleanKibana(); + createRule(getNewRule({ rule_id: 'custom_rule_filters' })); + }); - // cleanup - // revert the changes so that data does not change for further tests. - // It would make sure that tests can run in any order. - cy.get(OPTION_SELECTABLE(0, 'open')).trigger('click'); - togglePageFilterPopover(0); - openFirstAlert(); - waitForAlerts(); + it(`Alert list is updated when the alerts are updated`, () => { + // mark status of one alert to be acknowledged + selectCountTable(); + cy.get(ALERTS_COUNT) + .invoke('text') + .then((noOfAlerts) => { + const originalAlertCount = noOfAlerts.split(' ')[0]; + markAcknowledgedFirstAlert(); + waitForAlerts(); + cy.get(OPTION_LIST_VALUES(0)).click(); + cy.get(OPTION_SELECTABLE(0, 'acknowledged')).should('be.visible').trigger('click'); + cy.get(ALERTS_COUNT) + .invoke('text') + .should((newAlertCount) => { + expect(newAlertCount.split(' ')[0]).eq(String(parseInt(originalAlertCount, 10) - 1)); + }); + }); + }); }); it(`URL is updated when filters are updated`, () => { cy.on('url:changed', (urlString) => { const NEW_FILTERS = DEFAULT_DETECTION_PAGE_FILTERS.map((filter) => { - if (filter.title === 'Severity') { - filter.selectedOptions = ['high']; - } - return filter; + return { + ...filter, + selectedOptions: filter.title === 'Severity' ? ['high'] : filter.selectedOptions, + }; }); const expectedVal = encode(formatPageFilterSearchParam(NEW_FILTERS)); expect(urlString).to.contain.text(expectedVal); @@ -331,7 +333,7 @@ describe('Detections : Page Filters', () => { afterEach(() => { resetFilters(); }); - it('should recover from invalide kql Query result', () => { + it('should recover from invalid kql Query result', () => { // do an invalid search // kqlSearch('\\'); @@ -350,7 +352,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); it('should take filters into account', () => { @@ -362,7 +364,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); it('should take timeRange into account', () => { const startDateWithZeroAlerts = 'Jan 1, 2002 @ 00:00:00.000'; @@ -375,7 +377,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); }); it('Number fields are not visible in field edit panel', () => { diff --git a/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts b/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts index ab56bee03a34b7..a4c069c2e24676 100644 --- a/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts +++ b/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts @@ -21,6 +21,8 @@ export const OPTION_LIST_LABELS = '.controlFrame__labelToolTip'; export const OPTION_LIST_VALUES = (idx: number) => `[data-test-subj="optionsList-control-${idx}"]`; +export const OPTION_LIST_CLEAR_BTN = '.presentationUtil__floatingActions [aria-label="Clear"]'; + export const OPTION_LIST_NUMBER_OFF = '.euiFilterButton__notification'; export const OPTION_LISTS_LOADING = '.optionsList--filterBtnWrapper .euiLoadingSpinner'; @@ -48,7 +50,11 @@ export const DETECTION_PAGE_FILTERS_LOADING = '.securityPageWrapper .controlFram export const DETECTION_PAGE_FILTER_GROUP_LOADING = '[data-test-subj="filter-group__loading"]'; -export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU = '[data-test-subj="filter-group__context"]'; +export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN = + '[data-test-subj="filter-group__context"]'; + +export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU = + '[data-test-subj="filter-group__context-menu"]'; export const DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON = '[data-test-subj="filter-group__context--reset"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts index 67d61925fa1648..0e6a1524147633 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts @@ -6,6 +6,7 @@ */ import { encode } from '@kbn/rison'; +import { recurse } from 'cypress-recurse'; import { formatPageFilterSearchParam } from '../../common/utils/format_page_filter_search_param'; import { TOP_N_CONTAINER } from '../screens/network/flows'; import { @@ -63,14 +64,14 @@ import { } from '../screens/alerts_details'; import { FIELD_INPUT } from '../screens/exceptions'; import { + CONTROL_FRAME_TITLE, DETECTION_PAGE_FILTERS_LOADING, - DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, DETECTION_PAGE_FILTER_GROUP_LOADING, DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON, DETECTION_PAGE_FILTER_GROUP_WRAPPER, - OPTION_LISTS_EXISTS, OPTION_LISTS_LOADING, OPTION_LIST_VALUES, + OPTION_LIST_CLEAR_BTN, OPTION_SELECTABLE, } from '../screens/common/filter_group'; import { LOADING_SPINNER } from '../screens/common/page'; @@ -78,6 +79,7 @@ import { ALERTS_URL } from '../urls/navigation'; import { FIELDS_BROWSER_BTN } from '../screens/rule_details'; import type { FilterItemObj } from '../../public/common/components/filter_group/types'; import { visit } from './login'; +import { openFilterGroupContextMenu } from './common/filter_group'; export const addExceptionFromFirstAlert = () => { expandFirstAlertActions(); @@ -175,23 +177,21 @@ export const closePageFilterPopover = (filterIndex: number) => { cy.get(OPTION_LIST_VALUES(filterIndex)).should('not.have.class', 'euiFilterButton-isSelected'); }; -export const clearAllSelections = () => { - cy.get(OPTION_LISTS_EXISTS).click({ force: true }); - - cy.get(OPTION_LISTS_EXISTS).then(($el) => { - if ($el.attr('aria-checked', 'false')) { - // check it - $el.click(); - } - // uncheck it - $el.click(); - }); +export const clearAllSelections = (filterIndex: number) => { + recurse( + () => { + cy.get(CONTROL_FRAME_TITLE).eq(filterIndex).realHover(); + return cy.get(OPTION_LIST_CLEAR_BTN).eq(filterIndex); + }, + ($el) => $el.is(':visible') + ); + cy.get(OPTION_LIST_CLEAR_BTN).eq(filterIndex).should('be.visible').trigger('click'); }; export const selectPageFilterValue = (filterIndex: number, ...values: string[]) => { refreshAlertPageFilter(); + clearAllSelections(filterIndex); openPageFilterPopover(filterIndex); - clearAllSelections(); values.forEach((value) => { cy.get(OPTION_SELECTABLE(filterIndex, value)).click({ force: true }); }); @@ -407,9 +407,10 @@ export const waitForPageFilters = () => { }; export const resetFilters = () => { - cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).click({ force: true }); - cy.get(DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON).click({ force: true }); + openFilterGroupContextMenu(); + cy.get(DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON).trigger('click'); waitForPageFilters(); + cy.log('Resetting filters complete'); }; export const parseAlertsCountToInt = (count: string | number) => diff --git a/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts b/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts index b19cf2586ff78c..d3b1c5857bb456 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts @@ -5,8 +5,9 @@ * 2.0. */ +import { recurse } from 'cypress-recurse'; import { - DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, + DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN, DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON, FILTER_GROUP_ADD_CONTROL, FILTER_GROUP_CONTEXT_EDIT_CONTROLS, @@ -23,11 +24,18 @@ import { OPTION_LISTS_LOADING, FILTER_GROUP_CONTEXT_DISCARD_CHANGES, FILTER_GROUP_CONTROL_ACTION_EDIT, + DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, } from '../../screens/common/filter_group'; import { waitForPageFilters } from '../alerts'; export const openFilterGroupContextMenu = () => { - cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).click(); + recurse( + () => { + cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN).click(); + return cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).should(Cypress._.noop); + }, + ($el) => $el.length === 1 + ); }; export const waitForFilterGroups = () => { diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts index 075cbec275c9e0..873355fa60a764 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { AddOptionsListControlProps } from '@kbn/controls-plugin/public'; + export const TEST_IDS = { FILTER_CONTROLS: 'filter-group__items', FILTER_LOADING: 'filter-group__loading', @@ -23,3 +25,20 @@ export const TEST_IDS = { DISCARD: `filter-group__context--discard`, }, }; + +export const COMMON_OPTIONS_LIST_CONTROL_INPUTS: Partial = { + hideExclude: true, + hideSort: true, + hidePanelTitles: true, + placeholder: '', + ignoreParentSettings: { + ignoreValidations: true, + }, +}; + +export const TIMEOUTS = { + /* because of recent changes in controls-plugin debounce time may not be needed + * still keeping the config for some time for any recent changes + * */ + FILTER_UPDATES_DEBOUNCE_TIME: 0, +}; diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx index b7dc2f6f32457f..2e77a40a70a808 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx @@ -7,7 +7,7 @@ import { EuiButtonIcon, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS } from './constants'; import { useFilterGroupInternalContext } from './hooks/use_filters'; import { CONTEXT_MENU_RESET, @@ -60,10 +60,7 @@ export const FilterGroupContextMenu = () => { const control = initialControls[counter]; await controlGroup?.addOptionsListControl({ controlId: String(counter), - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, // option List controls will handle an invalid dataview // & display an appropriate message dataViewId: dataViewId ?? '', @@ -139,6 +136,9 @@ export const FilterGroupContextMenu = () => { closePopover={toggleContextMenu} panelPaddingSize="none" anchorPosition="downLeft" + panelProps={{ + 'data-test-subj': TEST_IDS.CONTEXT_MENU.MENU, + }} > diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx index 5600d231df19af..7d3c961473fa9c 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx @@ -26,7 +26,7 @@ import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; import { initialInputData, sampleOutputData } from './mocks/data'; import { createStore } from '../../store'; import { useGetInitialUrlParamValue } from '../../utils/global_query_string/helpers'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS } from './constants'; import { controlGroupFilterInputMock$, controlGroupFilterOutputMock$, @@ -304,7 +304,7 @@ describe(' Filter Group Component ', () => { ); }); - it('should save controls successfully', async () => { + it('should not rebuild controls while saving controls when controls are in desired order', async () => { render(); updateControlGroupInputMock(initialInputData as ControlGroupInput); await openContextMenu(); @@ -314,7 +314,9 @@ describe(' Filter Group Component ', () => { const newInputData = { ...initialInputData, panels: { + // status as persistent controls is first in the position with order as 0 '0': initialInputData.panels['0'], + '1': initialInputData.panels['1'], }, } as ControlGroupInput; @@ -329,10 +331,51 @@ describe(' Filter Group Component ', () => { // edit model gone expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); - // check if upsert was called correctely - expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(1); + // check if upsert was called correctly + expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(0); + }); + }); + + it('should rebuild and save controls successfully when controls are not in desired order', async () => { + render(); + updateControlGroupInputMock(initialInputData as ControlGroupInput); + await openContextMenu(); + fireEvent.click(screen.getByTestId(TEST_IDS.CONTEXT_MENU.EDIT)); + + // modify controls + const newInputData = { + ...initialInputData, + panels: { + '0': { + ...initialInputData.panels['0'], + // status is second in position. + // this will force the rebuilding of controls + order: 1, + }, + '1': { + ...initialInputData.panels['1'], + order: 0, + }, + }, + } as ControlGroupInput; + + updateControlGroupInputMock(newInputData); + + // clear any previous calls to the API + controlGroupMock.addOptionsListControl.mockClear(); + + fireEvent.click(screen.getByTestId(TEST_IDS.SAVE_CONTROL)); + + await waitFor(() => { + // edit model gone + expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); + + // check if upsert was called correctly + expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); + // field id is not required to be passed when creating a control + const { id, ...expectedInputData } = initialInputData.panels['0'].explicitInput; expect(controlGroupMock.addOptionsListControl.mock.calls[0][0]).toMatchObject({ - ...initialInputData.panels['0'].explicitInput, + ...expectedInputData, }); }); }); @@ -363,17 +406,18 @@ describe(' Filter Group Component ', () => { await waitFor(() => { // edit model gone expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); - // check if upsert was called correctely + // check if upsert was called correctly expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); expect(controlGroupMock.addOptionsListControl.mock.calls[0][0]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, ...DEFAULT_DETECTION_PAGE_FILTERS[0], }); + + // field id is not required to be passed when creating a control + const { id, ...expectedInputData } = initialInputData.panels['3'].explicitInput; + expect(controlGroupMock.addOptionsListControl.mock.calls[1][0]).toMatchObject({ - ...initialInputData.panels['3'].explicitInput, + ...expectedInputData, }); }); }); @@ -595,18 +639,12 @@ describe(' Filter Group Component ', () => { updateControlGroupInputMock(initialInputData as ControlGroupInput); expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); expect(controlGroupMock.addOptionsListControl.mock.calls[0][1]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, ...DEFAULT_DETECTION_PAGE_FILTERS[0], }); expect(controlGroupMock.addOptionsListControl.mock.calls[1][1]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, fieldName: 'abc', }); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx index 52629cc58c2b94..dd1f9109a4e1e5 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx @@ -6,11 +6,7 @@ */ import type { Filter } from '@kbn/es-query'; -import type { - ControlInputTransform, - ControlPanelState, - OptionsListEmbeddableInput, -} from '@kbn/controls-plugin/common'; +import type { ControlInputTransform } from '@kbn/controls-plugin/common'; import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; import type { ControlGroupInput, @@ -18,6 +14,7 @@ import type { ControlGroupOutput, ControlGroupContainer, ControlGroupRendererProps, + DataControlInput, } from '@kbn/controls-plugin/public'; import { ControlGroupRenderer } from '@kbn/controls-plugin/public'; import type { PropsWithChildren } from 'react'; @@ -26,7 +23,7 @@ import { ViewMode } from '@kbn/embeddable-plugin/public'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import type { Subscription } from 'rxjs'; import styled from 'styled-components'; -import { cloneDeep, debounce, isEqual } from 'lodash'; +import { debounce, isEqual, isEqualWith } from 'lodash'; import type { ControlGroupCreationOptions, FieldFilterPredicate, @@ -43,11 +40,16 @@ import { useControlGroupSyncToLocalStorage } from './hooks/use_control_group_syn import { useViewEditMode } from './hooks/use_view_edit_mode'; import { FilterGroupContextMenu } from './context_menu'; import { AddControl, SaveControls } from './buttons'; -import { getFilterItemObjListFromControlInput } from './utils'; +import { + getFilterControlsComparator, + getFilterItemObjListFromControlInput, + mergeControls, + reorderControlsWithDefaultControls, +} from './utils'; import { FiltersChangedBanner } from './filters_changed_banner'; import { FilterGroupContext } from './filter_group_context'; import { NUM_OF_CONTROLS } from './config'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS, TIMEOUTS } from './constants'; import { URL_PARAM_ARRAY_EXCEPTION_MSG } from './translations'; import { convertToBuildEsQuery } from '../../lib/kuery'; @@ -79,6 +81,15 @@ const FilterGroupComponent = (props: PropsWithChildren) => { const filterChangedSubscription = useRef(); const inputChangedSubscription = useRef(); + const initialControlsObj = useMemo( + () => + initialControls.reduce>((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {}), + [initialControls] + ); + const [controlGroup, setControlGroup] = useState(); const localStoragePageFilterKey = useMemo( @@ -128,7 +139,9 @@ const FilterGroupComponent = (props: PropsWithChildren) => { const storedControlGroupInput = getStoredControlInput(); if (storedControlGroupInput) { const panelsFormatted = getFilterItemObjListFromControlInput(storedControlGroupInput); - if (!isEqual(panelsFormatted, param)) { + if ( + !isEqualWith(panelsFormatted, param, getFilterControlsComparator('fieldName', 'title')) + ) { setShowFiltersChangedBanner(true); switchToEditMode(); } @@ -203,8 +216,12 @@ const FilterGroupComponent = (props: PropsWithChildren) => { ); const handleOutputFilterUpdates = useCallback( - ({ filters: newFilters }: ControlGroupOutput) => { + ({ filters: newFilters, embeddableLoaded }: ControlGroupOutput) => { + const haveAllEmbeddablesLoaded = Object.values(embeddableLoaded).every((v) => + Boolean(v ?? true) + ); if (isEqual(currentFiltersRef.current, newFilters)) return; + if (!haveAllEmbeddablesLoaded) return; if (onFilterChange) onFilterChange(newFilters ?? []); currentFiltersRef.current = newFilters ?? []; }, @@ -212,7 +229,7 @@ const FilterGroupComponent = (props: PropsWithChildren) => { ); const debouncedFilterUpdates = useMemo( - () => debounce(handleOutputFilterUpdates, 500), + () => debounce(handleOutputFilterUpdates, TIMEOUTS.FILTER_UPDATES_DEBOUNCE_TIME), [handleOutputFilterUpdates] ); @@ -253,53 +270,35 @@ const FilterGroupComponent = (props: PropsWithChildren) => { * * */ - const localInitialControls = cloneDeep(initialControls).filter( - (control) => control.persist === true - ); - let resultControls = [] as FilterItemObj[]; - - let overridingControls = initialUrlParam; - if (!initialUrlParam || initialUrlParam.length === 0) { - // if nothing is found in URL Param.. read from local storage - const storedControlGroupInput = getStoredControlInput(); - if (storedControlGroupInput) { - const urlParamsFromLocalStorage: FilterItemObj[] = - getFilterItemObjListFromControlInput(storedControlGroupInput); - - overridingControls = urlParamsFromLocalStorage; - } + const controlsFromURL = initialUrlParam ?? []; + let controlsFromLocalStorage: FilterItemObj[] = []; + const storedControlGroupInput = getStoredControlInput(); + if (storedControlGroupInput) { + controlsFromLocalStorage = getFilterItemObjListFromControlInput(storedControlGroupInput); } + let overridingControls = mergeControls({ + controlsWithPriority: [controlsFromURL, controlsFromLocalStorage], + defaultControlsObj: initialControlsObj, + }); if (!overridingControls || overridingControls.length === 0) return initialControls; - // if initialUrlParam Exists... replace localInitialControls with what was provided in the Url - if (overridingControls && !urlDataApplied.current) { - if (localInitialControls.length > 0) { - localInitialControls.forEach((persistControl) => { - const doesPersistControlAlreadyExist = overridingControls?.some( - (control) => control.fieldName === persistControl.fieldName - ); - - if (!doesPersistControlAlreadyExist) { - resultControls.push(persistControl); - } - }); - } - - resultControls = [ - ...resultControls, - ...overridingControls.map((item) => ({ - fieldName: item.fieldName, - title: item.title, - selectedOptions: item.selectedOptions ?? [], - existsSelected: item.existsSelected ?? false, - exclude: item.exclude, - })), - ]; - } + overridingControls = overridingControls.map((item) => { + return { + // give default value to params which are coming from the URL + fieldName: item.fieldName, + title: item.title, + selectedOptions: item.selectedOptions ?? [], + existsSelected: item.existsSelected ?? false, + exclude: item.exclude, + }; + }); - return resultControls; - }, [initialUrlParam, initialControls, getStoredControlInput]); + return reorderControlsWithDefaultControls({ + controls: overridingControls, + defaultControls: initialControls, + }); + }, [initialUrlParam, initialControls, getStoredControlInput, initialControlsObj]); const fieldFilterPredicate: FieldFilterPredicate = useCallback((f) => f.type !== 'number', []); @@ -325,10 +324,7 @@ const FilterGroupComponent = (props: PropsWithChildren) => { finalControls.forEach((control, idx) => { addOptionsListControl(initialInput, { controlId: String(idx), - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, // option List controls will handle an invalid dataview // & display an appropriate message dataViewId: dataViewId ?? '', @@ -376,48 +372,29 @@ const FilterGroupComponent = (props: PropsWithChildren) => { }, [controlGroup, switchToViewMode, getStoredControlInput, hasPendingChanges]); const upsertPersistableControls = useCallback(async () => { - const persistableControls = initialControls.filter((control) => control.persist === true); - if (persistableControls.length > 0) { - const currentPanels = Object.values(controlGroup?.getInput().panels ?? []) as Array< - ControlPanelState - >; - const orderedPanels = currentPanels.sort((a, b) => a.order - b.order); - let filterControlsDeleted = false; - for (const control of persistableControls) { - const controlExists = currentPanels.some( - (currControl) => control.fieldName === currControl.explicitInput.fieldName - ); - if (!controlExists) { - // delete current controls - if (!filterControlsDeleted) { - controlGroup?.updateInput({ panels: {} }); - filterControlsDeleted = true; - } - - // add persitable controls - await controlGroup?.addOptionsListControl({ - title: control.title, - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', - // option List controls will handle an invalid dataview - // & display an appropriate message - dataViewId: dataViewId ?? '', - selectedOptions: control.selectedOptions, - ...control, - }); - } - } + if (!controlGroup) return; + const currentPanels = getFilterItemObjListFromControlInput(controlGroup.getInput()); + + const reorderedControls = reorderControlsWithDefaultControls({ + controls: currentPanels, + defaultControls: initialControls, + }); + + if (!isEqualWith(reorderedControls, currentPanels, getFilterControlsComparator('fieldName'))) { + // reorder only if fields are in different order + // or not same. + controlGroup?.updateInput({ panels: {} }); - for (const panel of orderedPanels) { - if (panel.explicitInput.fieldName) - await controlGroup?.addOptionsListControl({ - selectedOptions: [], - fieldName: panel.explicitInput.fieldName, - dataViewId: dataViewId ?? '', - ...panel.explicitInput, - }); + for (const control of reorderedControls) { + await controlGroup?.addOptionsListControl({ + title: control.title, + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, + // option List controls will handle an invalid dataview + // & display an appropriate message + dataViewId: dataViewId ?? '', + selectedOptions: control.selectedOptions, + ...control, + }); } } }, [controlGroup, dataViewId, initialControls]); @@ -428,23 +405,36 @@ const FilterGroupComponent = (props: PropsWithChildren) => { setShowFiltersChangedBanner(false); }, [switchToViewMode, upsertPersistableControls]); - const newControlInputTranform: ControlInputTransform = (newInput, controlType) => { - // for any new controls, we want to avoid - // default placeholder - if (controlType === OPTIONS_LIST_CONTROL) { - return { - ...newInput, - placeholder: '', - }; - } - return newInput; - }; + const newControlInputTranform: ControlInputTransform = useCallback( + (newInput, controlType) => { + // for any new controls, we want to avoid + // default placeholder + let result = newInput; + if (controlType === OPTIONS_LIST_CONTROL) { + result = { + ...newInput, + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, + }; + + if ((newInput as DataControlInput).fieldName in initialControlsObj) { + result = { + ...result, + ...initialControlsObj[(newInput as DataControlInput).fieldName], + // title should not be overridden by the initial controls, hence the hardcoding + title: newInput.title ?? result.title, + }; + } + } + return result; + }, + [initialControlsObj] + ); const addControlsHandler = useCallback(() => { controlGroup?.openAddDataControlFlyout({ controlInputTransform: newControlInputTranform, }); - }, [controlGroup]); + }, [controlGroup, newControlInputTranform]); return ( void; } -export type FilterItemObj = Omit & - Pick; +export type FilterItemObj = Omit & { + /* + * Determines the present and order of a control + * + * */ + persist?: boolean; +}; export type FilterGroupHandler = ControlGroupContainer; export type FilterGroupProps = { dataViewId: string | null; onFilterChange?: (newFilters: Filter[]) => void; - initialControls: Array; + initialControls: FilterItemObj[]; spaceId: string; onInit?: (controlGroupHandler: FilterGroupHandler | undefined) => void; } & Pick; diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts index edcffd7502df9b..f2f860710ac848 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts @@ -6,9 +6,64 @@ */ import type { ControlGroupInput } from '@kbn/controls-plugin/common'; -import { getFilterItemObjListFromControlInput } from './utils'; +import { + getFilterItemObjListFromControlInput, + mergeControls, + reorderControlsWithDefaultControls, + getFilterControlsComparator, +} from './utils'; import { initialInputData } from './mocks/data'; +import type { FilterItemObj } from './types'; +import { isEqualWith } from 'lodash'; +const defaultControls: FilterItemObj[] = [ + { + fieldName: 'first', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + }, + + { + fieldName: 'second', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + persist: true, + }, +]; + +const firstControlsSet: FilterItemObj[] = [ + { + fieldName: 'first', + selectedOptions: ['firstVal'], + }, +]; + +const secondControlsSet: FilterItemObj[] = [ + { + fieldName: 'first', + selectedOptions: ['secondVal1', 'secondVal2'], + existsSelected: true, + }, + { + fieldName: 'second', + hideActionBar: false, + exclude: true, + }, +]; + +const thirdControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + selectedOptions: [], + }, +]; + +const emptyControlSet: FilterItemObj[] = []; + +const defaultControlsObj = defaultControls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; +}, {} as Record); describe('utils', () => { describe('getFilterItemObjListFromControlOutput', () => { it('should return ordered filterItem where passed in order', () => { @@ -61,4 +116,172 @@ describe('utils', () => { }); }); }); + + describe('mergeControls', () => { + it('should return first controls set when it is not empty', () => { + const result = mergeControls({ + controlsWithPriority: [firstControlsSet, secondControlsSet], + defaultControlsObj, + }); + + const expectedResult = [ + { + fieldName: 'first', + selectedOptions: ['firstVal'], + hideActionBar: true, + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + + it('should return second controls set when first one is empty', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, secondControlsSet], + defaultControlsObj, + }); + + const expectedResult = [ + { + fieldName: 'first', + selectedOptions: ['secondVal1', 'secondVal2'], + hideActionBar: true, + existsSelected: true, + }, + { + fieldName: 'second', + selectedOptions: ['val1', 'val2'], + hideActionBar: false, + exclude: true, + persist: true, + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + + it('should return controls as it is when default control for a field does not exist', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, emptyControlSet, thirdControlsSet], + defaultControlsObj, + }); + const expectedResult = thirdControlsSet; + expect(result).toMatchObject(expectedResult); + }); + + it('should return default controls if no priority controls are given', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, emptyControlSet, emptyControlSet], + defaultControlsObj, + }); + + expect(result).toBeUndefined(); + }); + }); + + describe('reorderControls', () => { + it('should add persist controls in order if they are not available in the given controls', () => { + const newControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + }, + ]; + + const result = reorderControlsWithDefaultControls({ + controls: newControlsSet, + defaultControls, + }); + + const expectedResult = [ + { + fieldName: 'second', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + persist: true, + }, + { + fieldName: 'new', + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + it('should change controls order if they are available in the given controls', () => { + const newControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + }, + { + fieldName: 'second', + selectedOptions: ['val2'], + hideActionBar: false, + }, + { + fieldName: 'first', + selectedOptions: [], + }, + ]; + + const expectedResult = [ + { + fieldName: 'second', + selectedOptions: ['val2'], + hideActionBar: false, + persist: true, + }, + { + fieldName: 'new', + }, + { + fieldName: 'first', + selectedOptions: [], + hideActionBar: true, + }, + ]; + + const result = reorderControlsWithDefaultControls({ + controls: newControlsSet, + defaultControls, + }); + + expect(result).toMatchObject(expectedResult); + }); + }); + + describe('getFilterControlsComparator', () => { + it('should return true when controls are equal and and list of field is empty', () => { + const comparator = getFilterControlsComparator(); + const result = isEqualWith(defaultControls, defaultControls, comparator); + + expect(result).toBe(true); + }); + it('should return false when arrays of different length', () => { + const comparator = getFilterControlsComparator(); + const result = isEqualWith(defaultControls, thirdControlsSet, comparator); + + expect(result).toBe(false); + }); + it('should return true when given set of fields match ', () => { + const comparator = getFilterControlsComparator('fieldName'); + const result = isEqualWith(defaultControls, secondControlsSet, comparator); + + expect(result).toBe(true); + }); + it("should return false when given set of fields don't match ", () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith(defaultControls, secondControlsSet, comparator); + expect(result).toBe(false); + }); + + it('should return true when comparing empty set of filter controls', () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith([], [], comparator); + expect(result).toBe(true); + }); + it('should return false when comparing one empty and one non-empty set of filter controls', () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith(defaultControls, [], comparator); + expect(result).toBe(false); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts index 6523ff61b20606..c005621831d5b2 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts @@ -11,6 +11,9 @@ import type { OptionsListEmbeddableInput, } from '@kbn/controls-plugin/common'; +import { isEmpty, isEqual, pick } from 'lodash'; +import type { FilterItemObj } from './types'; + export const getPanelsInOrderFromControlsInput = (controlInput: ControlGroupInput) => { const panels = controlInput.panels; @@ -21,7 +24,7 @@ export const getFilterItemObjListFromControlInput = (controlInput: ControlGroupI const panels = getPanelsInOrderFromControlsInput(controlInput); return panels.map((panel) => { const { - explicitInput: { fieldName, selectedOptions, title, existsSelected, exclude }, + explicitInput: { fieldName, selectedOptions, title, existsSelected, exclude, hideActionBar }, } = panel as ControlPanelState; return { @@ -30,6 +33,115 @@ export const getFilterItemObjListFromControlInput = (controlInput: ControlGroupI title, existsSelected: existsSelected ?? false, exclude: exclude ?? false, + hideActionBar: hideActionBar ?? false, }; }); }; + +interface MergableControlsArgs { + /* + * Set of controls that need be merged with priority + * Set of controls with lower index take priority over the next one. + * + * Final set of controls is merged with the defaulControls + * + */ + controlsWithPriority: FilterItemObj[][]; + defaultControlsObj: Record; +} + +/* + * mergeControls merges controls based on priority with the default controls + * + * @return undefined if all provided controls are empty + * */ +export const mergeControls = ({ + controlsWithPriority, + defaultControlsObj, +}: MergableControlsArgs) => { + const highestPriorityControlSet = controlsWithPriority.find((control) => !isEmpty(control)); + + return highestPriorityControlSet?.map((singleControl) => { + if (singleControl.fieldName in defaultControlsObj) { + return { + ...defaultControlsObj[singleControl.fieldName], + ...singleControl, + }; + } + return singleControl; + }); +}; + +interface ReorderControlsArgs { + /* + * Ordered Controls + * + * */ + controls: FilterItemObj[]; + /* + * default controls in order + * */ + defaultControls: FilterItemObj[]; +} + +/** + * reorderControlsWithPersistentControls reorders the controls such that controls which + * are persistent in default controls should be upserted in given order + * + * */ +export const reorderControlsWithDefaultControls = (args: ReorderControlsArgs) => { + const { controls, defaultControls } = args; + const controlsObject = controls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {} as Record); + + const defaultControlsObj = defaultControls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {} as Record); + + const resultDefaultControls: FilterItemObj[] = defaultControls + .filter((defaultControl) => defaultControl.persist) + .map((defaultControl) => { + return { + ...defaultControl, + ...(controlsObject[defaultControl.fieldName] ?? {}), + }; + }); + + const resultNonPersitantControls = controls + .filter( + // filter out persisting controls since we have already taken + // in account above + (control) => !defaultControlsObj[control.fieldName]?.persist + ) + .map((control) => ({ + // insert some default properties from default controls + // irrespective of whether they are persistent or not. + ...(defaultControlsObj[control.fieldName] ?? {}), + ...control, + })); + + return [...resultDefaultControls, ...resultNonPersitantControls]; +}; + +/* + * getFilterControlsComparator provides a comparator that can be used with `isEqualWith` to compare + * 2 instances of FilterItemObj + * + * */ +export const getFilterControlsComparator = + (...fieldsToCompare: Array) => + (filterItemObject1: FilterItemObj[], filterItemObject2: FilterItemObj[]) => { + if (filterItemObject1.length !== filterItemObject2.length) return false; + const filterItemObjectWithSelectedKeys1 = filterItemObject1.map((v) => { + return pick(v, fieldsToCompare); + }); + + const filterItemObjectWithSelectedKeys2 = filterItemObject2.map((v) => { + return pick(v, fieldsToCompare); + }); + + return isEqual(filterItemObjectWithSelectedKeys1, filterItemObjectWithSelectedKeys2); + }; From 472d843fbc81ba386b273c71dd3c4bfc4784518b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Tue, 4 Jul 2023 14:45:57 +0200 Subject: [PATCH 53/98] [Enterprise Search] Remove access control as well if exists (#161122) ## Summary - Add access control remove - Deletes access control index too after content index is deleted. ### 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 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../indices/delete_access_control_index.ts | 22 +++++++++++++++++++ .../routes/enterprise_search/indices.ts | 2 ++ .../plugins/enterprise_search/tsconfig.json | 1 + 3 files changed, 25 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts new file mode 100644 index 00000000000000..2df773b1af30e0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.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 { isIndexNotFoundException } from '@kbn/core-saved-objects-migration-server-internal'; +import { IScopedClusterClient } from '@kbn/core/server'; + +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../..'; + +export const deleteAccessControlIndex = async (client: IScopedClusterClient, index: string) => { + try { + await client.asCurrentUser.indices.delete({ + index: index.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX), + }); + } catch (e) { + // Gracefully exit if index not found. This is a valid case. + if (!isIndexNotFoundException(e)) throw e; + } +}; 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 81233d842d6298..5b5a0c7e99b9be 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 @@ -26,6 +26,7 @@ import { fetchConnectorByIndexName, fetchConnectors } from '../../lib/connectors import { fetchCrawlerByIndexName, fetchCrawlers } from '../../lib/crawler/fetch_crawlers'; import { createIndex } from '../../lib/indices/create_index'; +import { deleteAccessControlIndex } from '../../lib/indices/delete_access_control_index'; import { indexOrAliasExists } from '../../lib/indices/exists_index'; import { fetchIndex } from '../../lib/indices/fetch_index'; import { fetchIndices, fetchSearchIndices } from '../../lib/indices/fetch_indices'; @@ -201,6 +202,7 @@ export function registerIndexRoutes({ } await deleteIndexPipelines(client, indexName); + await deleteAccessControlIndex(client, indexName); await client.asCurrentUser.indices.delete({ index: indexName }); diff --git a/x-pack/plugins/enterprise_search/tsconfig.json b/x-pack/plugins/enterprise_search/tsconfig.json index 0ea008f3691f5e..f8407385478f5b 100644 --- a/x-pack/plugins/enterprise_search/tsconfig.json +++ b/x-pack/plugins/enterprise_search/tsconfig.json @@ -61,5 +61,6 @@ "@kbn/shared-ux-link-redirect-app", "@kbn/global-search-plugin", "@kbn/share-plugin", + "@kbn/core-saved-objects-migration-server-internal", ] } From 2a71469894af46716e5b40cfff981a0fb3448901 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 4 Jul 2023 15:43:47 +0200 Subject: [PATCH 54/98] [Deployment Management] Add landing page redirect feature and implement in security solution (#161060) --- src/plugins/management/README.md | 12 ++- .../management_app/management_app.tsx | 8 +- .../management_app/management_router.tsx | 96 ++++++++++++------- src/plugins/management/public/mocks/index.ts | 1 + src/plugins/management/public/plugin.ts | 4 + src/plugins/management/public/types.ts | 1 + src/plugins/management/tsconfig.json | 4 +- .../plugins/serverless_security/kibana.jsonc | 1 + .../public/common/services.mock.tsx | 2 + .../serverless_security/public/plugin.ts | 4 +- .../serverless_security/public/types.ts | 3 + .../plugins/serverless_security/tsconfig.json | 1 + .../test_serverless/functional/config.base.ts | 3 + .../functional/test_suites/security/index.ts | 1 + .../test_suites/security/management.ts | 25 +++++ 15 files changed, 126 insertions(+), 40 deletions(-) create mode 100644 x-pack/test_serverless/functional/test_suites/security/management.ts diff --git a/src/plugins/management/README.md b/src/plugins/management/README.md index 354fe766d473a0..828715235b1b96 100644 --- a/src/plugins/management/README.md +++ b/src/plugins/management/README.md @@ -38,4 +38,14 @@ If card needs to be hidden from the navigation you can specify that by using the }); ``` -More specifics about the `setupCardsNavigation` can be found in `packages/kbn-management/cards_navigation/readme.mdx`. \ No newline at end of file +More specifics about the `setupCardsNavigation` can be found in `packages/kbn-management/cards_navigation/readme.mdx`. + +## Landing page redirect + +If the consumer wants to have a separate landing page for the management section, they can use the `setLandingPageRedirect` +method to specify the path to the landing page: + + +``` + management.setLandingPageRedirect('/app/security/management'); +``` \ No newline at end of file diff --git a/src/plugins/management/public/components/management_app/management_app.tsx b/src/plugins/management/public/components/management_app/management_app.tsx index 133d19250085a4..538da6045255ac 100644 --- a/src/plugins/management/public/components/management_app/management_app.tsx +++ b/src/plugins/management/public/components/management_app/management_app.tsx @@ -43,6 +43,7 @@ export interface ManagementAppDependencies { setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void; isSidebarEnabled$: BehaviorSubject; cardsNavigationConfig$: BehaviorSubject; + landingPageRedirect$: BehaviorSubject; } export const ManagementApp = ({ @@ -51,11 +52,13 @@ export const ManagementApp = ({ theme$, appBasePath, }: ManagementAppProps) => { - const { setBreadcrumbs, isSidebarEnabled$, cardsNavigationConfig$ } = dependencies; + const { setBreadcrumbs, isSidebarEnabled$, cardsNavigationConfig$, landingPageRedirect$ } = + dependencies; const [selectedId, setSelectedId] = useState(''); const [sections, setSections] = useState(); const isSidebarEnabled = useObservable(isSidebarEnabled$); const cardsNavigationConfig = useObservable(cardsNavigationConfig$); + const landingPageRedirect = useObservable(landingPageRedirect$); const onAppMounted = useCallback((id: string) => { setSelectedId(id); @@ -131,6 +134,9 @@ export const ManagementApp = ({ setBreadcrumbs={setBreadcrumbsScoped} onAppMounted={onAppMounted} sections={sections} + landingPageRedirect={landingPageRedirect} + navigateToUrl={dependencies.coreStart.application.navigateToUrl} + basePath={dependencies.coreStart.http.basePath} /> diff --git a/src/plugins/management/public/components/management_app/management_router.tsx b/src/plugins/management/public/components/management_app/management_router.tsx index ad9a6e41989cea..9335af3bf5b78e 100644 --- a/src/plugins/management/public/components/management_app/management_router.tsx +++ b/src/plugins/management/public/components/management_app/management_router.tsx @@ -6,10 +6,12 @@ * Side Public License, v 1. */ -import React, { memo } from 'react'; +import React, { memo, useEffect } from 'react'; import { Redirect } from 'react-router-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from '@kbn/core/public'; +import type { ApplicationStart } from '@kbn/core-application-browser'; +import type { HttpStart } from '@kbn/core-http-browser'; import { ManagementAppWrapper } from '../management_app_wrapper'; import { ManagementLandingPage } from '../landing'; import { ManagementSection } from '../../utils'; @@ -20,43 +22,65 @@ interface ManagementRouterProps { setBreadcrumbs: (crumbs?: ChromeBreadcrumb[], appHistory?: ScopedHistory) => void; onAppMounted: (id: string) => void; sections: ManagementSection[]; + landingPageRedirect: string | undefined; + navigateToUrl: ApplicationStart['navigateToUrl']; + basePath: HttpStart['basePath']; } export const ManagementRouter = memo( - ({ history, setBreadcrumbs, onAppMounted, sections, theme$ }: ManagementRouterProps) => ( - - - {sections.map((section) => - section - .getAppsEnabled() - .map((app) => ( - ( - - )} - /> - )) - )} - {sections.map((section) => - section - .getAppsEnabled() - .filter((app) => app.redirectFrom) - .map((app) => ) - )} - ( - + ({ + history, + setBreadcrumbs, + onAppMounted, + sections, + theme$, + landingPageRedirect, + navigateToUrl, + basePath, + }: ManagementRouterProps) => { + // Redirect the user to the configured landing page if there is one + useEffect(() => { + if (landingPageRedirect) { + navigateToUrl(basePath.prepend(landingPageRedirect)); + } + }, [landingPageRedirect, navigateToUrl, basePath]); + + return ( + + + {sections.map((section) => + section + .getAppsEnabled() + .map((app) => ( + ( + + )} + /> + )) + )} + {sections.map((section) => + section + .getAppsEnabled() + .filter((app) => app.redirectFrom) + .map((app) => ) )} - /> - - - ) + + ( + + )} + /> + + + ); + } ); diff --git a/src/plugins/management/public/mocks/index.ts b/src/plugins/management/public/mocks/index.ts index 93ccefbe5130f3..bc6bdcdc468141 100644 --- a/src/plugins/management/public/mocks/index.ts +++ b/src/plugins/management/public/mocks/index.ts @@ -44,6 +44,7 @@ const createSetupContract = (): ManagementSetup => ({ const createStartContract = (): ManagementStart => ({ setIsSidebarEnabled: jest.fn(), setupCardsNavigation: jest.fn(), + setLandingPageRedirect: jest.fn(), }); export const managementPluginMock = { diff --git a/src/plugins/management/public/plugin.ts b/src/plugins/management/public/plugin.ts index 712799de2f65c4..445a9b3a3db0af 100644 --- a/src/plugins/management/public/plugin.ts +++ b/src/plugins/management/public/plugin.ts @@ -72,6 +72,7 @@ export class ManagementPlugin private hasAnyEnabledApps = true; private isSidebarEnabled$ = new BehaviorSubject(true); + private landingPageRedirect$ = new BehaviorSubject(undefined); private cardsNavigationConfig$ = new BehaviorSubject({ enabled: false, hideLinksTo: [], @@ -124,6 +125,7 @@ export class ManagementPlugin setBreadcrumbs: coreStart.chrome.setBreadcrumbs, isSidebarEnabled$: managementPlugin.isSidebarEnabled$, cardsNavigationConfig$: managementPlugin.cardsNavigationConfig$, + landingPageRedirect$: managementPlugin.landingPageRedirect$, }); }, }); @@ -154,6 +156,8 @@ export class ManagementPlugin this.isSidebarEnabled$.next(isSidebarEnabled), setupCardsNavigation: ({ enabled, hideLinksTo }) => this.cardsNavigationConfig$.next({ enabled, hideLinksTo }), + setLandingPageRedirect: (landingPageRedirect: string) => + this.landingPageRedirect$.next(landingPageRedirect), }; } } diff --git a/src/plugins/management/public/types.ts b/src/plugins/management/public/types.ts index e2b5353d8995c7..52e66698629fd6 100644 --- a/src/plugins/management/public/types.ts +++ b/src/plugins/management/public/types.ts @@ -30,6 +30,7 @@ export interface DefinedSections { export interface ManagementStart { setIsSidebarEnabled: (enabled: boolean) => void; + setLandingPageRedirect: (landingPageRedirect: string) => void; setupCardsNavigation: ({ enabled, hideLinksTo }: NavigationCardsSubject) => void; } diff --git a/src/plugins/management/tsconfig.json b/src/plugins/management/tsconfig.json index 019867f3873877..aeb231f2ea9edc 100644 --- a/src/plugins/management/tsconfig.json +++ b/src/plugins/management/tsconfig.json @@ -22,7 +22,9 @@ "@kbn/shared-ux-router", "@kbn/management-cards-navigation", "@kbn/shared-ux-link-redirect-app", - "@kbn/test-jest-helpers" + "@kbn/test-jest-helpers", + "@kbn/core-application-browser", + "@kbn/core-http-browser" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/serverless_security/kibana.jsonc b/x-pack/plugins/serverless_security/kibana.jsonc index daa7490a386510..306918ed70697f 100644 --- a/x-pack/plugins/serverless_security/kibana.jsonc +++ b/x-pack/plugins/serverless_security/kibana.jsonc @@ -14,6 +14,7 @@ ], "requiredPlugins": [ "kibanaReact", + "management", "ml", "security", "securitySolution", diff --git a/x-pack/plugins/serverless_security/public/common/services.mock.tsx b/x-pack/plugins/serverless_security/public/common/services.mock.tsx index 70f024842a340d..a3aba806af18c0 100644 --- a/x-pack/plugins/serverless_security/public/common/services.mock.tsx +++ b/x-pack/plugins/serverless_security/public/common/services.mock.tsx @@ -12,6 +12,7 @@ import { serverlessMock } from '@kbn/serverless/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; import { BehaviorSubject } from 'rxjs'; +import { managementPluginMock } from '@kbn/management-plugin/public/mocks'; import type { ProjectNavigationLink } from './navigation/links'; import type { Services } from './services'; @@ -23,6 +24,7 @@ export const servicesMocks: Services = { security: securityMock.createStart(), securitySolution: securitySolutionMock.createStart(), getProjectNavLinks$: jest.fn(() => new BehaviorSubject(mockProjectNavLinks())), + management: managementPluginMock.createStartContract(), }; export const KibanaServicesProvider = React.memo(({ children }) => ( diff --git a/x-pack/plugins/serverless_security/public/plugin.ts b/x-pack/plugins/serverless_security/public/plugin.ts index 356aea4f2c345e..acc7854a363b04 100644 --- a/x-pack/plugins/serverless_security/public/plugin.ts +++ b/x-pack/plugins/serverless_security/public/plugin.ts @@ -48,7 +48,7 @@ export class ServerlessSecurityPlugin core: CoreStart, startDeps: ServerlessSecurityPluginStartDependencies ): ServerlessSecurityPluginStart { - const { securitySolution, serverless } = startDeps; + const { securitySolution, serverless, management } = startDeps; const { productTypes } = this.config; const services = createServices(core, startDeps); @@ -62,6 +62,8 @@ export class ServerlessSecurityPlugin subscribeNavigationTree(services); subscribeBreadcrumbs(services); + management.setLandingPageRedirect('/app/security/manage'); + return {}; } diff --git a/x-pack/plugins/serverless_security/public/types.ts b/x-pack/plugins/serverless_security/public/types.ts index 3954183cc97490..73052810127ad8 100644 --- a/x-pack/plugins/serverless_security/public/types.ts +++ b/x-pack/plugins/serverless_security/public/types.ts @@ -11,6 +11,7 @@ import type { PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public'; +import { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; import type { SecurityProductTypes } from '../common/config'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -23,12 +24,14 @@ export interface ServerlessSecurityPluginSetupDependencies { security: SecurityPluginSetup; securitySolution: SecuritySolutionPluginSetup; serverless: ServerlessPluginSetup; + management: ManagementSetup; } export interface ServerlessSecurityPluginStartDependencies { security: SecurityPluginStart; securitySolution: SecuritySolutionPluginStart; serverless: ServerlessPluginStart; + management: ManagementStart; } export interface ServerlessSecurityPublicConfig { diff --git a/x-pack/plugins/serverless_security/tsconfig.json b/x-pack/plugins/serverless_security/tsconfig.json index 69d976d3241057..2d2d3b8d34e6a2 100644 --- a/x-pack/plugins/serverless_security/tsconfig.json +++ b/x-pack/plugins/serverless_security/tsconfig.json @@ -17,6 +17,7 @@ "kbn_references": [ "@kbn/core", "@kbn/config-schema", + "@kbn/management-plugin", "@kbn/security-plugin", "@kbn/security-solution-plugin", "@kbn/serverless", diff --git a/x-pack/test_serverless/functional/config.base.ts b/x-pack/test_serverless/functional/config.base.ts index 81a3f197a0ec08..23739a9615e696 100644 --- a/x-pack/test_serverless/functional/config.base.ts +++ b/x-pack/test_serverless/functional/config.base.ts @@ -52,6 +52,9 @@ export function createTestConfig(options: CreateTestConfigOptions) { observability: { pathname: '/app/observability', }, + management: { + pathname: '/app/management', + }, }, // choose where screenshots should be saved screenshots: { diff --git a/x-pack/test_serverless/functional/test_suites/security/index.ts b/x-pack/test_serverless/functional/test_suites/security/index.ts index 470f1e98082e89..4d31c06188bcf9 100644 --- a/x-pack/test_serverless/functional/test_suites/security/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/index.ts @@ -10,5 +10,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless security UI', function () { loadTestFile(require.resolve('./landing_page')); + loadTestFile(require.resolve('./management')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/security/management.ts b/x-pack/test_serverless/functional/test_suites/security/management.ts new file mode 100644 index 00000000000000..f610e7b25ca73c --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/management.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 { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getPageObject }: FtrProviderContext) { + const PageObject = getPageObject('common'); + + describe('Management', function () { + it('redirects from common management url to security specific page', async () => { + const SUB_URL = ''; + await PageObject.navigateToUrl('management', SUB_URL, { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + shouldUseHashForSubUrl: false, + }); + + await PageObject.waitUntilUrlIncludes('/security/manage'); + }); + }); +} From b340cb301bd47c6ba3fd13873c901ac01a5bf717 Mon Sep 17 00:00:00 2001 From: Stef Nestor <26751266+stefnestor@users.noreply.github.com> Date: Tue, 4 Jul 2023 09:26:43 -0500 Subject: [PATCH 55/98] [DOC+] License not available is KB-ES connection error (#161176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 👋🏼 howdy, team! When Kibana can't connect to Elasticsearch (past finding master / network issue, just unhealthy cluster ballpark), its code logic cascades into first tripping warn/error log `license is not available`. This is a red-herring in that the license can not be determined and user should investigate the network connection / Elasticsearch health rather than investigating for lapsed licenses. Adding this into the "Kibana not ready" docs since it raises at this point in the flow to hopefully allow users to search-find it in our official docs rather than e.g. top-goggle-results: [Elastic Discuss](https://discuss.elastic.co/t/license-not-available/265931), [external Github](https://github.com/spujadas/elk-docker/issues/349). --- docs/setup/access.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/access.asciidoc b/docs/setup/access.asciidoc index 2b76843b5964d4..631fa22d711ddf 100644 --- a/docs/setup/access.asciidoc +++ b/docs/setup/access.asciidoc @@ -61,5 +61,5 @@ curl -XGET elasticsearch_ip_or_hostname:9200/_cat/indices/.kibana,.kibana_task_m + For example: -* When {kib} is unable to connect to a healthy {es} cluster, the `master_not_discovered_exception` or `Unable to revive connection` errors appear. +* When {kib} is unable to connect to a healthy {es} cluster, errors like `master_not_discovered_exception` or `unable to revive connection` or `license is not available` errors appear. * When one or more {kib}-backing indices are unhealthy, the `index_not_green_timeout` error appears. From 50e015e4ff9b52cf7e537366373d357c95f5d628 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 4 Jul 2023 10:50:18 -0400 Subject: [PATCH 56/98] chore(slo): use doclinks (#160673) --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + .../public/rules/register_observability_rule_types.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index b47b0ab86ac3b5..304c249c7e2d42 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -521,6 +521,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { syntheticsCommandReference: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-configuration.html#synthetics-configuration-playwright-options`, syntheticsProjectMonitors: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetic-run-tests.html#synthetic-monitor-choose-project`, syntheticsMigrateFromIntegration: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-migrate-from-integration.html`, + sloBurnRateRule: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/slo-burn-rate-alert.html`, }, alerting: { guide: `${KIBANA_DOCS}create-and-manage-rules.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index 5f6b92ebd2a44e..0fe2e7b30047f0 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -401,6 +401,7 @@ export interface DocLinks { syntheticsCommandReference: string; syntheticsProjectMonitors: string; syntheticsMigrateFromIntegration: string; + sloBurnRateRule: string; }>; readonly alerting: Readonly<{ guide: string; 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 e6e5412cc046e8..8e284120509200 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 @@ -70,7 +70,7 @@ export const registerObservabilityRuleTypes = ( }, iconClass: 'bell', documentationUrl(docLinks) { - return 'https://www.elastic.co/guide/en/observability/current/slo-burn-rate-alert.html'; + return `${docLinks.links.observability.sloBurnRateRule}`; }, ruleParamsExpression: lazy(() => import('../components/burn_rate_rule_editor')), validate: validateBurnRateRule, @@ -78,6 +78,7 @@ export const registerObservabilityRuleTypes = ( defaultActionMessage: sloBurnRateDefaultActionMessage, defaultRecoveryMessage: sloBurnRateDefaultRecoveryMessage, }); + if (config.unsafe.thresholdRule.enabled) { observabilityRuleTypeRegistry.register({ id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, From 72719a5013b0c60f7f4a68106c1c8db4eba272d1 Mon Sep 17 00:00:00 2001 From: Gerard Soldevila Date: Tue, 4 Jul 2023 17:01:31 +0200 Subject: [PATCH 57/98] [ZDT] Pickup updated types only (#161123) Part of https://github.com/elastic/kibana/issues/161067 Same idea as https://github.com/elastic/kibana/pull/159962, but applied to ZDT. When "picking up" the updated mappings, we add a "query" in order to select and update only the SO types that have been updated, compared to the previous version. --- .../src/actions/check_target_mappings.test.ts | 11 +--- .../src/actions/check_target_mappings.ts | 10 +-- .../core/build_pickup_mappings_query.test.ts | 31 +++++++++ .../src/core/build_pickup_mappings_query.ts | 30 +++++++++ .../src/model/model.test.ts | 6 +- .../src/model/model.ts | 20 +++--- .../src/next.ts | 2 - .../src/zdt/next.test.ts | 64 +++++++++++++++++++ .../src/zdt/next.ts | 2 + 9 files changed, 143 insertions(+), 33 deletions(-) create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts index 17c55102a3cc74..4e04cc2a705395 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts @@ -20,8 +20,6 @@ jest.mock('../core/build_active_mappings'); const getUpdatedHashesMock = getUpdatedHashes as jest.MockedFn; -const indexTypes = ['type1', 'type2']; - const properties: SavedObjectsMappingProperties = { type1: { type: 'long' }, type2: { type: 'long' }, @@ -48,7 +46,6 @@ describe('checkTargetMappings', () => { describe('when actual mappings are incomplete', () => { it("returns 'actual_mappings_incomplete' if actual mappings are not defined", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, }); @@ -58,7 +55,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings do not define _meta", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -72,7 +68,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings do not define migrationMappingPropertyHashes", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -87,7 +82,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings define a different value for 'dynamic' property", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -105,7 +99,6 @@ describe('checkTargetMappings', () => { describe('and mappings do not match', () => { it('returns the lists of changed root fields and types', async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: expectedMappings, }); @@ -115,8 +108,7 @@ describe('checkTargetMappings', () => { const result = await task(); const expected: ComparedMappingsChanged = { type: 'compared_mappings_changed' as const, - updatedRootFields: ['someRootField'], - updatedTypes: ['type1', 'type2'], + updatedHashes: ['type1', 'type2', 'someRootField'], }; expect(result).toEqual(Either.left(expected)); }); @@ -125,7 +117,6 @@ describe('checkTargetMappings', () => { describe('and mappings match', () => { it('returns a compared_mappings_match response', async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: expectedMappings, }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts index 26e0f074f43cb2..576459beadd74b 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts @@ -13,7 +13,6 @@ import { getUpdatedHashes } from '../core/build_active_mappings'; /** @internal */ export interface CheckTargetMappingsParams { - indexTypes: string[]; actualMappings?: IndexMapping; expectedMappings: IndexMapping; } @@ -29,13 +28,11 @@ export interface ActualMappingsIncomplete { export interface ComparedMappingsChanged { type: 'compared_mappings_changed'; - updatedRootFields: string[]; - updatedTypes: string[]; + updatedHashes: string[]; } export const checkTargetMappings = ({ - indexTypes, actualMappings, expectedMappings, }: CheckTargetMappingsParams): TaskEither.TaskEither< @@ -56,12 +53,9 @@ export const checkTargetMappings = }); if (updatedHashes.length) { - const updatedTypes = updatedHashes.filter((field) => indexTypes.includes(field)); - const updatedRootFields = updatedHashes.filter((field) => !indexTypes.includes(field)); return Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields, - updatedTypes, + updatedHashes, }); } else { return Either.right({ type: 'compared_mappings_match' as const }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts new file mode 100644 index 00000000000000..3895bd9314df3a --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { buildPickupMappingsQuery } from './build_pickup_mappings_query'; + +describe('buildPickupMappingsQuery', () => { + describe('when no root fields have been updated', () => { + it('builds a boolean query to select the updated types', () => { + const query = buildPickupMappingsQuery(['type1', 'type2']); + + expect(query).toEqual({ + bool: { + should: [{ term: { type: 'type1' } }, { term: { type: 'type2' } }], + }, + }); + }); + }); + + describe('when some root fields have been updated', () => { + it('returns undefined', () => { + const query = buildPickupMappingsQuery(['type1', 'type2', 'namespaces']); + + expect(query).toBeUndefined(); + }); + }); +}); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts new file mode 100644 index 00000000000000..ce110f72f66c1b --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import { getBaseMappings } from './build_active_mappings'; + +export const buildPickupMappingsQuery = ( + updatedFields: string[] +): QueryDslQueryContainer | undefined => { + const rootFields = Object.keys(getBaseMappings().properties); + + if (updatedFields.some((field) => rootFields.includes(field))) { + // we are updating some root fields, update ALL documents (no filter query) + return undefined; + } + + // at this point, all updated fields correspond to SO types + const updatedTypes = updatedFields; + + return { + bool: { + should: updatedTypes.map((type) => ({ term: { type } })), + }, + }; +}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts index 39a03e1e28d478..7039ce1cd1afaa 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts @@ -2615,8 +2615,7 @@ describe('migrations v2 model', () => { it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_PROPERTIES if core fields have been updated', () => { const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields: ['namespaces'], - updatedTypes: ['dashboard', 'lens'], + updatedHashes: ['dashboard', 'lens', 'namespaces'], }); const newState = model( checkTargetMappingsState, @@ -2631,8 +2630,7 @@ describe('migrations v2 model', () => { it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_PROPERTIES if only SO types have changed', () => { const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields: [], - updatedTypes: ['dashboard', 'lens'], + updatedHashes: ['dashboard', 'lens'], }); const newState = model( checkTargetMappingsState, diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts index 2505581c6bc3d2..2264ca388c9756 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts @@ -54,6 +54,8 @@ import { CLUSTER_SHARD_LIMIT_EXCEEDED_REASON, FATAL_REASON_REQUEST_ENTITY_TOO_LARGE, } from '../common/constants'; +import { getBaseMappings } from '../core'; +import { buildPickupMappingsQuery } from '../core/build_pickup_mappings_query'; export const model = (currentState: State, resW: ResponseType): State => { // The action response `resW` is weakly typed, the type includes all action @@ -1439,18 +1441,22 @@ export const model = (currentState: State, resW: ResponseType): updatedTypesQuery: Option.none, }; } else if (isTypeof(left, 'compared_mappings_changed')) { - if (left.updatedRootFields.length) { + const rootFields = Object.keys(getBaseMappings().properties); + const updatedRootFields = left.updatedHashes.filter((field) => rootFields.includes(field)); + const updatedTypesQuery = Option.fromNullable(buildPickupMappingsQuery(left.updatedHashes)); + + if (updatedRootFields.length) { // compatible migration: some core fields have been updated return { ...stateP, controlState: 'UPDATE_TARGET_MAPPINGS_PROPERTIES', // we must "pick-up" all documents on the index (by not providing a query) - updatedTypesQuery: Option.none, + updatedTypesQuery, logs: [ ...stateP.logs, { level: 'info', - message: `Kibana is performing a compatible upgrade and the mappings of some root fields have been changed. For Elasticsearch to pickup these mappings, all saved objects need to be updated. Updated root fields: ${left.updatedRootFields}.`, + message: `Kibana is performing a compatible upgrade and the mappings of some root fields have been changed. For Elasticsearch to pickup these mappings, all saved objects need to be updated. Updated root fields: ${updatedRootFields}.`, }, ], }; @@ -1460,16 +1466,12 @@ export const model = (currentState: State, resW: ResponseType): ...stateP, controlState: 'UPDATE_TARGET_MAPPINGS_PROPERTIES', // we can "pick-up" only the SO types that have changed - updatedTypesQuery: Option.some({ - bool: { - should: left.updatedTypes.map((type) => ({ term: { type } })), - }, - }), + updatedTypesQuery, logs: [ ...stateP.logs, { level: 'info', - message: `Kibana is performing a compatible upgrade and NO root fields have been udpated. Kibana will update the following SO types so that ES can pickup the updated mappings: ${left.updatedTypes}.`, + message: `Kibana is performing a compatible upgrade and NO root fields have been udpated. Kibana will update the following SO types so that ES can pickup the updated mappings: ${left.updatedHashes}.`, }, ], }; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts index df7e0c23fbc205..b8d4afc55631df 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts @@ -58,7 +58,6 @@ import { createDelayFn } from './common/utils'; import type { TransformRawDocs } from './types'; import * as Actions from './actions'; import { REMOVED_TYPES } from './core'; -import { getIndexTypes } from './model/helpers'; type ActionMap = ReturnType; @@ -202,7 +201,6 @@ export const nextActionMap = ( Actions.checkTargetMappings({ actualMappings: Option.toUndefined(state.sourceIndexMappings), expectedMappings: state.targetIndexMappings, - indexTypes: getIndexTypes(state), }), UPDATE_TARGET_MAPPINGS_PROPERTIES: (state: UpdateTargetMappingsPropertiesState) => Actions.updateAndPickupMappings({ diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts index 00684ec46f85cf..6c2f90155ac763 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts @@ -22,6 +22,7 @@ import type { SetDocMigrationStartedState, UpdateMappingModelVersionState, UpdateDocumentModelVersionsState, + UpdateIndexMappingsState, } from './state'; describe('actions', () => { @@ -147,4 +148,67 @@ describe('actions', () => { }); }); }); + + describe('UPDATE_INDEX_MAPPINGS', () => { + describe('when only SO types have been updated', () => { + it('calls updateAndPickupMappings with the correct parameters', () => { + const state: UpdateIndexMappingsState = { + ...createPostDocInitState(), + controlState: 'UPDATE_INDEX_MAPPINGS', + additiveMappingChanges: { + someToken: {}, + }, + }; + const action = actionMap.UPDATE_INDEX_MAPPINGS; + + action(state); + + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledTimes(1); + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledWith({ + client: context.elasticsearchClient, + index: state.currentIndex, + mappings: { + properties: { + someToken: {}, + }, + }, + batchSize: context.batchSize, + query: { + bool: { + should: [{ term: { type: 'someToken' } }], + }, + }, + }); + }); + }); + + describe('when core properties have been updated', () => { + it('calls updateAndPickupMappings with the correct parameters', () => { + const state: UpdateIndexMappingsState = { + ...createPostDocInitState(), + controlState: 'UPDATE_INDEX_MAPPINGS', + additiveMappingChanges: { + managed: {}, // this is a root field + someToken: {}, + }, + }; + const action = actionMap.UPDATE_INDEX_MAPPINGS; + + action(state); + + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledTimes(1); + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledWith({ + client: context.elasticsearchClient, + index: state.currentIndex, + mappings: { + properties: { + managed: {}, + someToken: {}, + }, + }, + batchSize: context.batchSize, + }); + }); + }); + }); }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts index 17749104d18fe4..fe1093b0f4978f 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts @@ -39,6 +39,7 @@ import { setMetaDocMigrationComplete, setMetaDocMigrationStarted, } from './utils'; +import { buildPickupMappingsQuery } from '../core/build_pickup_mappings_query'; export type ActionMap = ReturnType; @@ -72,6 +73,7 @@ export const nextActionMap = (context: MigratorContext) => { index: state.currentIndex, mappings: { properties: state.additiveMappingChanges }, batchSize: context.batchSize, + query: buildPickupMappingsQuery(Object.keys(state.additiveMappingChanges)), }), UPDATE_INDEX_MAPPINGS_WAIT_FOR_TASK: (state: UpdateIndexMappingsWaitForTaskState) => Actions.waitForPickupUpdatedMappingsTask({ From e53ac35745da6f971594ad32c6e5c9a418cf8807 Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Tue, 4 Jul 2023 10:06:04 -0500 Subject: [PATCH 58/98] [main] Sync bundled packages with Package Storage (#161188) Automated by https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/5214/ Co-authored-by: apmmachine --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index e35f69b4dbc174..c4fbbc97501479 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -24,7 +24,7 @@ [ { "name": "apm", - "version": "8.10.0-preview-1687509840", + "version": "8.10.0-preview-1688475406", "forceAlignStackVersion": true, "allowSyncToPrerelease": true }, From 9de4cc5f46092b1fbf2b3d31e00e2d18b2b324f4 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 4 Jul 2023 17:09:56 +0100 Subject: [PATCH 59/98] skip flaky suite (#151981) --- .../case_view/components/case_view_activity.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx index bd604514b4cfac..1ef1d870daf77c 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx @@ -566,7 +566,8 @@ describe('Case View Page activity tab', () => { }); }); - describe('User actions', () => { + // FLAKY: https://github.com/elastic/kibana/issues/151981 + describe.skip('User actions', () => { it('renders the description correctly', async () => { appMockRender = createAppMockRenderer(); appMockRender.render(); From 8a95bf7fabe34c601725313c922f95ee0fa641e5 Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko Date: Tue, 4 Jul 2023 18:26:57 +0200 Subject: [PATCH 60/98] [ftr] Improve FTR error handling for NoSuchSessionError (#161025) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Sometimes browser/driver process dies during test run on CI and FTR fails with errors cascade, good example is [here](https://buildkite.com/elastic/kibana-pull-request/builds/138535#0188fd74-9adf-4011-8168-1bdc6e3d0f17) Current behaviour on `main`: FTR lifecycle hooks, defined in [remote](https://github.com/elastic/kibana/blob/57aea91fae4f2d0a047ff9e2339eb61352f1d73d/test/functional/services/remote/remote.ts) service, has no access to the information about test suite run and particular test failure. These hooks are related to WebDriver (browser) state management and suppose to reset it to default state. Currently we silently fail screenshot taking which means tests execution is continued even if `--bail` flag is passed. It ends with cascade of failures with the same error `NoSuchSessionError: invalid session id`
FTR output on failure ``` └- ✖ fail: discover/group1 discover test query should show correct time range string by timepicker │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ └-> "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" └- ✖ fail: discover/group1 discover test query "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ └-> "after all" hook in "discover test" │ debg Cleaning all saved objects { space: undefined } │ succ deleted 2 objects └-> "after all" hook: afterTestSuite.trigger in "discover test" └- ✖ fail: discover/group1 discover test "after all" hook: afterTestSuite.trigger in "discover test" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ └-> "after all" hook: unloadMakelogs in "discover/group1" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "mappings.json" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.22" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.20" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.21" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "data.json.gz" └-> "after all" hook: afterTestSuite.trigger in "discover/group1" └- ✖ fail: discover/group1 "after all" hook: afterTestSuite.trigger in "discover/group1" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at runMicrotasks () │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │ │0 passing (15.7s) │4 failing │ │1) discover/group1 │ discover test │ query │ should show correct time range string by timepicker: │ │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ │2) discover/group1 │ discover test │ query │ "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │3) discover/group1 │ discover test │ "after all" hook: afterTestSuite.trigger in "discover test": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │4) discover/group1 │ "after all" hook: afterTestSuite.trigger in "discover/group1": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at runMicrotasks () │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) ```
This PR change: I didn't find a good reason why we need to fail silently on screenshot taking. I added a check WebDriver session status with `hasOpenWindow` and take failure artefacts only if is still valid. Next change is to fail FTR after hooks related to WebDriver silently: there is no help having cascade of the repeated stacktrace so I wrap WebDriver call in hooks with `tryWebDriverCall` that catches the error and only prints it for visibility.
FTR new output on failure ``` │ERROR WebDriver session is no longer valid. │ Probably Chrome process crashed when it tried to use more memory than what was available. │ERROR Browser is closed, no artifacts were captured for the failure └- ✖ fail: discover/group1 discover test query should show correct time range string by timepicker │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ └-> "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" │ERROR WebDriver session is no longer valid └-> "after all" hook in "discover test" │ debg Cleaning all saved objects { space: undefined } │ warn browser[SEVERE] ERROR FETCHING BROWSR LOGS: This driver instance does not have a valid session ID (did you call WebDriver.quit()?) and may no longer be used. │ succ deleted 2 objects └-> "after all" hook: afterTestSuite.trigger in "discover test" │ERROR WebDriver session is no longer valid └-> "after all" hook: unloadMakelogs in "discover/group1" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "mappings.json" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.22" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.20" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.21" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "data.json.gz" └-> "after all" hook: afterTestSuite.trigger in "discover/group1" │ERROR WebDriver session is no longer valid 0 passing (16.2s) 1 failing 1) discover/group1 discover test query should show correct time range string by timepicker: Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' at Assertion.assert (expect.js:100:11) at Assertion.apply (expect.js:227:8) at Assertion.be (expect.js:69:22) at Context. (_discover.ts:53:31) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.apply (wrap_function.js:73:16) ```
Flaky-test-runner verification: started 100x to hopefully catch invalid session on CI https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2539 Note: locally I was simulating it by calling `this.driver.close()` to close browser before screenshot taking --- test/functional/services/common/browser.ts | 30 +++++++++++++++++-- .../services/common/failure_debugging.ts | 7 ++++- .../functional/services/common/screenshots.ts | 20 +++---------- test/functional/services/remote/remote.ts | 30 +++++++++++++++---- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index 9de8ba0d569f0c..393f093d541898 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -12,6 +12,7 @@ import { Key, Origin, WebDriver } from 'selenium-webdriver'; import { modifyUrl } from '@kbn/std'; import sharp from 'sharp'; +import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import { WebElementWrapper } from '../lib/web_element_wrapper'; import { FtrProviderContext, FtrService } from '../../ftr_provider_context'; import { Browsers } from '../remote/browsers'; @@ -632,8 +633,33 @@ class BrowserService extends FtrService { return Boolean(result?.state === 'granted'); } - public getClipboardValue(): Promise { - return this.driver.executeAsyncScript('navigator.clipboard.readText().then(arguments[0])'); + public async getClipboardValue(): Promise { + return await this.driver.executeAsyncScript( + 'navigator.clipboard.readText().then(arguments[0])' + ); + } + + /** + * Checks if browser session is active and any browser window exists + * @returns {Promise} + */ + public async hasOpenWindow(): Promise { + if (this.driver == null) { + return false; + } else { + try { + const windowHandles = await this.driver.getAllWindowHandles(); + return windowHandles.length > 0; + } catch (err) { + if (err instanceof NoSuchSessionError) { + // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID + this.log.error( + `WebDriver session is no longer valid.\nProbably Chrome process crashed when it tried to use more memory than what was available.` + ); + } + return false; + } + } } } diff --git a/test/functional/services/common/failure_debugging.ts b/test/functional/services/common/failure_debugging.ts index 5555ae78bccf82..f269a83359da02 100644 --- a/test/functional/services/common/failure_debugging.ts +++ b/test/functional/services/common/failure_debugging.ts @@ -50,7 +50,12 @@ export async function FailureDebuggingProvider({ getService }: FtrProviderContex async function onFailure(_: any, test: Test) { const name = FtrScreenshotFilename.create(test.fullTitle(), { ext: false }); - await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]); + const hasOpenWindow = await browser.hasOpenWindow(); + if (hasOpenWindow) { + await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]); + } else { + log.error('Browser is closed, no artifacts were captured for the failure'); + } } lifecycle.testFailure.add(onFailure); diff --git a/test/functional/services/common/screenshots.ts b/test/functional/services/common/screenshots.ts index 191fc5202c4177..50421e480dd9cc 100644 --- a/test/functional/services/common/screenshots.ts +++ b/test/functional/services/common/screenshots.ts @@ -9,7 +9,6 @@ import { resolve, dirname } from 'path'; import { writeFile, readFileSync, mkdir } from 'fs'; import { promisify } from 'util'; -import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import del from 'del'; @@ -85,20 +84,9 @@ export class ScreenshotsService extends FtrService { } private async capture(path: string, el?: WebElementWrapper) { - try { - this.log.info(`Taking screenshot "${path}"`); - const screenshot = await (el ? el.takeScreenshot() : this.browser.takeScreenshot()); - await mkdirAsync(dirname(path), { recursive: true }); - await writeFileAsync(path, screenshot, 'base64'); - } catch (err) { - this.log.error('SCREENSHOT FAILED'); - this.log.error(err); - if (err instanceof NoSuchSessionError) { - // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID - this.log.error( - `WebDriver session is no longer valid.\nProbably Chrome process crashed when it tried to use more memory than what was available.` - ); - } - } + this.log.info(`Taking ${el ? 'element' : 'window'} screenshot "${path}"`); + const screenshot = await (el ? el.takeScreenshot() : this.browser.takeScreenshot()); + await mkdirAsync(dirname(path), { recursive: true }); + await writeFileAsync(path, screenshot, 'base64'); } } diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index 284029514606fe..b3038130b01879 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import { FtrProviderContext } from '../../ftr_provider_context'; import { initWebDriver, BrowserConfig } from './webdriver'; import { Browsers } from './browsers'; @@ -27,6 +28,21 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { } }; + const tryWebDriverCall = async (command: () => Promise) => { + // Since WebDriver session may be deleted, we fail silently. Use only in after hooks. + try { + await command(); + } catch (error) { + if (error instanceof NoSuchSessionError) { + // Avoid duplicating NoSuchSessionError error output on each hook + // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID + log.error('WebDriver session is no longer valid'); + } else { + throw error; + } + } + }; + const browserConfig: BrowserConfig = { logPollingMs: config.get('browser.logPollingMs'), acceptInsecureCerts: config.get('browser.acceptInsecureCerts'), @@ -72,14 +88,18 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { }); lifecycle.afterTestSuite.add(async () => { - const { width, height } = windowSizeStack.shift()!; - await driver.manage().window().setRect({ width, height }); - await clearBrowserStorage('sessionStorage'); - await clearBrowserStorage('localStorage'); + await tryWebDriverCall(async () => { + const { width, height } = windowSizeStack.shift()!; + await driver.manage().window().setRect({ width, height }); + await clearBrowserStorage('sessionStorage'); + await clearBrowserStorage('localStorage'); + }); }); lifecycle.cleanup.add(async () => { - await driver.quit(); + await tryWebDriverCall(async () => { + await driver.quit(); + }); }); return { driver, browserType, consoleLog$ }; From bfab1b0659269cf67d6a864d6a80ee29632b4b4c Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Tue, 4 Jul 2023 18:46:47 +0200 Subject: [PATCH 61/98] [Discover] Fix shared links flaky test (#161172) - Closes https://github.com/elastic/kibana/issues/158465 100x https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2550 --- .../apps/discover/group1/_shared_links.ts | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/test/functional/apps/discover/group1/_shared_links.ts b/test/functional/apps/discover/group1/_shared_links.ts index 11e92297aad991..30626d9d42576d 100644 --- a/test/functional/apps/discover/group1/_shared_links.ts +++ b/test/functional/apps/discover/group1/_shared_links.ts @@ -8,6 +8,7 @@ import { DISCOVER_APP_LOCATOR } from '@kbn/discover-plugin/common'; import expect from '@kbn/expect'; +import { decompressFromBase64 } from 'lz-string'; import { FtrProviderContext } from '../ftr_provider_context'; @@ -21,8 +22,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const toasts = getService('toasts'); const deployment = getService('deployment'); - // Failing: See https://github.com/elastic/kibana/issues/158465 - describe.skip('shared links', function describeIndexTests() { + describe('shared links', function describeIndexTests() { let baseUrl: string; async function setup({ storeStateInSessionStorage }: { storeStateInSessionStorage: boolean }) { @@ -75,14 +75,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('permalink', function () { it('should allow for copying the snapshot URL', async function () { - const lz = - 'N4IgjgrgpgTgniAXKSsGJCANCANgQwDsBzCfYqJEAa2nhAF8cBnAexgBckBtbkAAQ4BLALZRmHfCIAO2EABNxAYxABdVTiWtcEEYWY8N' + - 'IIYUUAPKrlbEJ%2BZgAsAtACo5JjrABu%2BXFXwQOVjkAMyFcDxgDRG4jeXxJADUhKAB3AEl5S2tbBxc5YTEAJSIKJFBgmFYRKgAmAAY' + - 'ARgBWRzqATkcGtoAVOoA2RABmBsQAFlGAOjrpgC18oIx65taOmsHuhoAOIZHxqdnGHBgoCvF7NMII719kEGvoJD7p6Zxpf2ZKRA4YaAY' + - 'GIA%3D'; const actualUrl = await PageObjects.share.getSharedUrl(); expect(actualUrl).to.contain(`?l=${DISCOVER_APP_LOCATOR}`); - expect(actualUrl).to.contain(`&lz=${lz}`); + const urlSearchParams = new URLSearchParams(actualUrl); + expect(JSON.parse(decompressFromBase64(urlSearchParams.get('lz')!)!)).to.eql({ + query: { + language: 'kuery', + query: '', + }, + sort: [['@timestamp', 'desc']], + columns: [], + index: 'logstash-*', + interval: 'auto', + filters: [], + dataViewId: 'logstash-*', + timeRange: { + from: '2015-09-19T06:31:44.000Z', + to: '2015-09-23T18:31:44.000Z', + }, + refreshInterval: { + value: 60000, + pause: true, + }, + }); }); it('should allow for copying the snapshot URL as a short URL', async function () { From b128f268d9450f007fbc15dc7c1bc066c7e36b65 Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Tue, 4 Jul 2023 19:25:12 +0200 Subject: [PATCH 62/98] Have SLO routes return a 403 instead of a 400 when user has an insufficient license (#161193) --- .../observability/docs/openapi/slo/README.md | 26 +- .../docs/openapi/slo/bundled.json | 2259 +++++++++++++++++ .../docs/openapi/slo/bundled.yaml | 107 +- .../slo/components/schemas/403_response.yaml | 16 + .../paths/s@{spaceid}@api@composite_slos.yaml | 24 +- ...}@api@composite_slos@{compositesloid}.yaml | 36 +- .../slo/paths/s@{spaceid}@api@slos.yaml | 28 +- ...spaceid}@api@slos@_historical_summary.yaml | 12 +- .../paths/s@{spaceid}@api@slos@{sloid}.yaml | 38 +- ...@{spaceid}@api@slos@{sloid}@{disable}.yaml | 14 +- ...s@{spaceid}@api@slos@{sloid}@{enable}.yaml | 14 +- .../slo_details/components/header_control.tsx | 2 +- .../pages/slos/components/slo_list_item.tsx | 2 +- .../observability/server/routes/slo/route.ts | 22 +- 14 files changed, 2524 insertions(+), 76 deletions(-) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/bundled.json create mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml diff --git a/x-pack/plugins/observability/docs/openapi/slo/README.md b/x-pack/plugins/observability/docs/openapi/slo/README.md index e128dd32a38b9d..440e560bf62f16 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/README.md +++ b/x-pack/plugins/observability/docs/openapi/slo/README.md @@ -7,28 +7,28 @@ A guide about the OpenApi specification can be found at [https://swagger.io/docs ## The `openapi/slo` folder -* `entrypoint.yaml` is the overview file which pulls together all the paths and components. -* [Paths](paths/README.md): this defines each endpoint. A path can have one operation per http method. -* [Components](components/README.md): Reusable components +- `entrypoint.yaml` is the overview file which pulls together all the paths and components. +- [Paths](paths/README.md): this defines each endpoint. A path can have one operation per http method. +- [Components](components/README.md): Reusable components ## Tools It is possible to validate the docs before bundling them with the following command in the `x-pack/plugins/observability/docs/openapi/slo` folder: - ```bash - npx swagger-cli validate entrypoint.yaml - ``` +```bash + npx swagger-cli validate entrypoint.yaml +``` Then you can generate the `bundled` files by running the following commands: - ```bash - npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml - npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json - ``` +```bash + npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml + npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json +``` After generating the json bundle ensure that it is also valid by running the following command: - ```bash - npx @redocly/cli lint bundled.json - ``` +```bash + npx @redocly/cli lint bundled.json +``` diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.json b/x-pack/plugins/observability/docs/openapi/slo/bundled.json new file mode 100644 index 00000000000000..09295ed2966789 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.json @@ -0,0 +1,2259 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "SLOs", + "description": "OpenAPI schema for SLOs endpoints", + "version": "1.0", + "contact": { + "name": "Actionable Observability Team" + }, + "license": { + "name": "Elastic License 2.0", + "url": "https://www.elastic.co/licensing/elastic-license" + } + }, + "servers": [ + { + "url": "http://localhost:5601", + "description": "local" + } + ], + "security": [ + { + "basicAuth": [] + }, + { + "apiKeyAuth": [] + } + ], + "tags": [ + { + "name": "slo", + "description": "SLO APIs enable you to define, manage and track service-level objectives" + }, + { + "name": "composite slo", + "description": "Composite SLO APIs enable you to define, manage and track a group of SLOs." + } + ], + "paths": { + "/s/{spaceId}/api/observability/composite_slos": { + "post": { + "summary": "Creates a Composite SLO", + "operationId": "createCompositeSlo", + "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_composite_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "409": { + "description": "Conflict - The Composite SLO id already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/409_response" + } + } + } + } + } + }, + "get": { + "summary": "Retrieves a paginated list of composite SLOs with summary", + "operationId": "findCompositeSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "name": "page", + "in": "query", + "description": "The page number to return", + "schema": { + "type": "integer", + "default": 1 + }, + "example": 1 + }, + { + "name": "perPage", + "in": "query", + "description": "The number of SLOs to return per page", + "schema": { + "type": "integer", + "default": 25 + }, + "example": 20 + }, + { + "name": "sortBy", + "in": "query", + "description": "Sort by field", + "schema": { + "type": "string", + "enum": [ + "creationTime" + ], + "default": "creationTime" + }, + "example": "creationTime" + }, + { + "name": "sortDirection", + "in": "query", + "description": "Sort order", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "asc" + }, + "example": "asc" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/find_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/composite_slos/{compositeSloId}": { + "get": { + "summary": "Retrieves a composite SLO", + "operationId": "getCompositeSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "put": { + "summary": "Updates a composite SLO", + "operationId": "updateCompositeSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/update_composite_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/base_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "delete": { + "summary": "Deletes a composite SLO", + "operationId": "deleteCompositeSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos": { + "post": { + "summary": "Creates an SLO.", + "operationId": "createSlo", + "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "409": { + "description": "Conflict - The SLO id already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/409_response" + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "get": { + "summary": "Retrieves a paginated list of SLOs", + "operationId": "findSlos", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "name": "name", + "in": "query", + "description": "Filter by name", + "schema": { + "type": "string" + }, + "example": "awesome-service" + }, + { + "name": "indicatorTypes", + "in": "query", + "description": "Filter by indicator type", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": [ + "sli.kql.custom" + ] + }, + { + "name": "page", + "in": "query", + "description": "The page number to return", + "schema": { + "type": "integer", + "default": 1 + }, + "example": 1 + }, + { + "name": "perPage", + "in": "query", + "description": "The number of SLOs to return per page", + "schema": { + "type": "integer", + "default": 25 + }, + "example": 20 + }, + { + "name": "sortBy", + "in": "query", + "description": "Sort by field", + "schema": { + "type": "string", + "enum": [ + "creationTime", + "indicatorType" + ], + "default": "creationTime" + }, + "example": "creationTime" + }, + { + "name": "sortDirection", + "in": "query", + "description": "Sort order", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "asc" + }, + "example": "asc" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/find_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}": { + "get": { + "summary": "Retrieves a SLO", + "operationId": "getSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "put": { + "summary": "Updates an SLO", + "operationId": "updateSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/update_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "delete": { + "summary": "Deletes an SLO", + "operationId": "deleteSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}/enable": { + "post": { + "summary": "Enables an SLO", + "operationId": "enableSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}/disable": { + "post": { + "summary": "Disables an SLO", + "operationId": "disableSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/internal/observability/slos/_historical_summary": { + "post": { + "summary": "Retrieves the historical summary for a list of SLOs", + "operationId": "historicalSummary", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/historical_summary_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/historical_summary_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" + }, + "apiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "ApiKey" + } + }, + "parameters": { + "kbn_xsrf": { + "schema": { + "type": "string" + }, + "in": "header", + "name": "kbn-xsrf", + "description": "Cross-site request forgery protection", + "required": true + }, + "space_id": { + "in": "path", + "name": "spaceId", + "description": "An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used.", + "required": true, + "schema": { + "type": "string", + "example": "default" + } + }, + "composite_slo_id": { + "in": "path", + "name": "compositeSloId", + "description": "An identifier for the composite slo.", + "required": true, + "schema": { + "type": "string", + "example": "9c235211-6834-11ea-a78c-6feb38a34414" + } + }, + "slo_id": { + "in": "path", + "name": "sloId", + "description": "An identifier for the slo.", + "required": true, + "schema": { + "type": "string", + "example": "9c235211-6834-11ea-a78c-6feb38a34414" + } + } + }, + "schemas": { + "time_window_rolling": { + "title": "Rolling", + "required": [ + "duration", + "isRolling" + ], + "description": "Defines properties for rolling time window", + "type": "object", + "properties": { + "duration": { + "description": "the duration formatted as {duration}{unit}", + "type": "string", + "example": "28d" + }, + "isRolling": { + "description": "Indicates a rolling time window", + "type": "boolean", + "example": true + } + } + }, + "budgeting_method": { + "title": "Budgeting method", + "type": "string", + "description": "The budgeting method to use when computing the rollup data.", + "enum": [ + "occurrences", + "timeslices" + ], + "example": "occurrences" + }, + "composite_method": { + "title": "Composite method", + "type": "string", + "description": "The composite method to use for the composite SLO.", + "enum": [ + "weightedAverage" + ], + "example": "weightedAverage" + }, + "objective": { + "title": "Objective", + "required": [ + "target" + ], + "description": "Defines properties for the SLO objective", + "type": "object", + "properties": { + "target": { + "description": "the target objective between 0 and 1 excluded", + "type": "number", + "example": 0.99 + }, + "timeslicesTarget": { + "description": "the target objective for each slice when using a timeslices budgeting method", + "type": "number", + "example": 0.995 + }, + "timeslicesWindow": { + "description": "the duration of each slice when using a timeslices budgeting method, as {duraton}{unit}", + "type": "string", + "example": "5m" + } + } + }, + "weighted_composite_sources": { + "title": "Weighted sources", + "description": "An array of source SLO to use for the weighted average composite.", + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "revision", + "weight" + ], + "properties": { + "id": { + "description": "The id of the SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "revision": { + "description": "The revision number of the SLO.", + "type": "number", + "example": 2 + }, + "weight": { + "description": "The weight to apply to this SLO.", + "type": "number", + "example": 3 + } + } + } + }, + "error_budget": { + "title": "Error budget", + "type": "object", + "properties": { + "initial": { + "type": "number", + "description": "The initial error budget, as 1 - objective", + "example": 0.02 + }, + "consumed": { + "type": "number", + "description": "The error budget consummed, as a percentage of the initial value.", + "example": 0.8 + }, + "remaining": { + "type": "number", + "description": "The error budget remaining, as a percentage of the initial value.", + "example": 0.2 + }, + "isEstimated": { + "type": "boolean", + "description": "Only for SLO defined with occurrences budgeting method and calendar aligned time window.", + "example": true + } + } + }, + "summary": { + "title": "Summary", + "type": "object", + "description": "The SLO computed data", + "properties": { + "status": { + "type": "string", + "enum": [ + "NO_DATA", + "HEALTHY", + "DEGRADING", + "VIOLATED" + ], + "example": "HEALTHY" + }, + "sliValue": { + "type": "number", + "example": 0.9836 + }, + "errorBudget": { + "$ref": "#/components/schemas/error_budget" + } + } + }, + "composite_slo_response": { + "title": "Composite SLO with summary response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the composite SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the composite SLO.", + "type": "string", + "example": "My Service SLO" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + }, + "summary": { + "$ref": "#/components/schemas/summary" + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "find_composite_slo_response": { + "title": "Find composite SLO response", + "description": "A paginated response of composite SLOs matching the query.", + "type": "object", + "properties": { + "page": { + "type": "number", + "example": 1 + }, + "perPage": { + "type": "number", + "example": 25 + }, + "total": { + "type": "number", + "example": 34 + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/composite_slo_response" + } + } + } + }, + "400_response": { + "title": "Bad request", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 400 + }, + "error": { + "type": "string", + "example": "Bad Request" + }, + "message": { + "type": "string", + "example": "Invalid value 'foo' supplied to: [...]" + } + } + }, + "401_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 401 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "403_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 403 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "404_response": { + "title": "Not found", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 404 + }, + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found" + } + } + }, + "create_composite_slo_request": { + "title": "Create composite SLO request", + "description": "The create Composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", + "type": "object", + "required": [ + "name", + "timeWindow", + "budgetingMethod", + "compositeMethod", + "objective", + "sources" + ], + "properties": { + "id": { + "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-composite-slo-id" + }, + "name": { + "description": "A name for the composite SLO.", + "type": "string" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + } + } + }, + "create_composite_slo_response": { + "title": "Create composite SLO response", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + }, + "409_response": { + "title": "Conflict", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 409 + }, + "error": { + "type": "string", + "example": "Conflict" + }, + "message": { + "type": "string", + "example": "SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists" + } + } + }, + "update_composite_slo_request": { + "title": "Update composite SLO request", + "description": "The update composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", + "type": "object", + "properties": { + "id": { + "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-composite-slo-id" + }, + "name": { + "description": "A name for the composite SLO.", + "type": "string" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + } + } + }, + "base_composite_slo_response": { + "title": "Composite SLO response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the composite SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the composite SLO.", + "type": "string", + "example": "My Service SLO" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "indicator_properties_custom_kql": { + "title": "Custom KQL", + "required": [ + "type", + "params" + ], + "description": "Defines properties for a custom KQL indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "index", + "timestampField" + ], + "properties": { + "index": { + "description": "The index or index pattern to use", + "type": "string", + "example": "my-service-*" + }, + "filter": { + "description": "the KQL query to filter the documents with.", + "type": "string", + "example": "field.environment : \"production\" and service.name : \"my-service\"" + }, + "good": { + "description": "the KQL query used to define the good events.", + "type": "string", + "example": "request.latency <= 150 and request.status_code : \"2xx\"" + }, + "total": { + "description": "the KQL query used to define all events.", + "type": "string", + "example": "" + }, + "timestampField": { + "description": "The timestamp field used in the source indice.\n", + "type": "string", + "example": "timestamp" + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.kql.custom" + } + } + }, + "indicator_properties_apm_availability": { + "title": "APM availability", + "required": [ + "type", + "params" + ], + "description": "Defines properties for the APM availability indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "service", + "environment", + "transactionType", + "transactionName", + "index" + ], + "properties": { + "service": { + "description": "The APM service name", + "type": "string", + "example": "o11y-app" + }, + "environment": { + "description": "The APM service environment or \"*\"", + "type": "string", + "example": "production" + }, + "transactionType": { + "description": "The APM transaction type or \"*\"", + "type": "string", + "example": "request" + }, + "transactionName": { + "description": "The APM transaction name or \"*\"", + "type": "string", + "example": "GET /my/api" + }, + "filter": { + "description": "KQL query used for filtering the data", + "type": "string", + "example": "service.foo : \"bar\"" + }, + "index": { + "description": "The index used by APM metrics", + "type": "string", + "example": "metrics-apm*,apm*" + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.apm.transactionDuration" + } + } + }, + "indicator_properties_apm_latency": { + "title": "APM latency", + "required": [ + "type", + "params" + ], + "description": "Defines properties for the APM latency indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "service", + "environment", + "transactionType", + "transactionName", + "index", + "threshold" + ], + "properties": { + "service": { + "description": "The APM service name", + "type": "string", + "example": "o11y-app" + }, + "environment": { + "description": "The APM service environment or \"*\"", + "type": "string", + "example": "production" + }, + "transactionType": { + "description": "The APM transaction type or \"*\"", + "type": "string", + "example": "request" + }, + "transactionName": { + "description": "The APM transaction name or \"*\"", + "type": "string", + "example": "GET /my/api" + }, + "filter": { + "description": "KQL query used for filtering the data", + "type": "string", + "example": "service.foo : \"bar\"" + }, + "index": { + "description": "The index used by APM metrics", + "type": "string", + "example": "metrics-apm*,apm*" + }, + "threshold": { + "description": "The latency threshold in milliseconds", + "type": "number", + "example": 250 + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.apm.transactionDuration" + } + } + }, + "indicator_properties_custom_metric": { + "title": "Custom metric", + "required": [ + "type", + "params" + ], + "description": "Defines properties for a custom metric indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "index", + "timestampField", + "good", + "total" + ], + "properties": { + "index": { + "description": "The index or index pattern to use", + "type": "string", + "example": "my-service-*" + }, + "filter": { + "description": "the KQL query to filter the documents with.", + "type": "string", + "example": "field.environment : \"production\" and service.name : \"my-service\"" + }, + "timestampField": { + "description": "The timestamp field used in the source indice.\n", + "type": "string", + "example": "timestamp" + }, + "good": { + "description": "An object defining the \"good\" metrics and equation\n", + "type": "object", + "required": [ + "metrics", + "equation" + ], + "properties": { + "metrics": { + "description": "List of metrics with their name, aggregation type, and field.", + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "aggregation", + "field" + ], + "properties": { + "name": { + "description": "The name of the metric. Only valid options are A-Z", + "type": "string", + "example": "A", + "pattern": "^[A-Z]$" + }, + "aggregation": { + "description": "The aggregation type of the metric. Only valid option is \"sum\"", + "type": "string", + "example": "sum", + "enum": [ + "sum" + ] + }, + "field": { + "description": "The field of the metric.", + "type": "string", + "example": "processor.processed" + } + } + } + }, + "equation": { + "description": "The equation to calculate the \"good\" metric.", + "type": "string", + "example": "A" + } + } + }, + "total": { + "description": "An object defining the \"total\" metrics and equation\n", + "type": "object", + "required": [ + "metrics", + "equation" + ], + "properties": { + "metrics": { + "description": "List of metrics with their name, aggregation type, and field.", + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "aggregation", + "field" + ], + "properties": { + "name": { + "description": "The name of the metric. Only valid options are A-Z", + "type": "string", + "example": "A", + "pattern": "^[A-Z]$" + }, + "aggregation": { + "description": "The aggregation type of the metric. Only valid option is \"sum\"", + "type": "string", + "example": "sum", + "enum": [ + "sum" + ] + }, + "field": { + "description": "The field of the metric.", + "type": "string", + "example": "processor.processed" + } + } + } + }, + "equation": { + "description": "The equation to calculate the \"total\" metric.", + "type": "string", + "example": "A" + } + } + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.metric.custom" + } + } + }, + "time_window_calendar_aligned": { + "title": "Calendar aligned", + "required": [ + "duration", + "isCalendar" + ], + "description": "Defines properties for calendar aligned time window", + "type": "object", + "properties": { + "duration": { + "description": "the duration formatted as {duration}{unit}, accept '1w' (weekly calendar) or '1M' (monthly calendar) only", + "type": "string", + "example": "1M" + }, + "isCalendar": { + "description": "Indicates a calendar aligned time window", + "type": "boolean", + "example": true + } + } + }, + "settings": { + "title": "Settings", + "description": "Defines properties for SLO settings.", + "type": "object", + "properties": { + "syncDelay": { + "description": "The synch delay to apply to the transform. Default 1m", + "type": "string", + "example": "5m" + }, + "frequency": { + "description": "Configure how often the transform runs, default 1m", + "type": "string", + "example": "5m" + } + } + }, + "slo_response": { + "title": "SLO response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the SLO.", + "type": "string", + "example": "My Service SLO" + }, + "description": { + "description": "The description of the SLO.", + "type": "string", + "example": "My SLO description" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + }, + "revision": { + "description": "The SLO revision", + "type": "number", + "example": 2 + }, + "summary": { + "$ref": "#/components/schemas/summary" + }, + "enabled": { + "description": "Indicate if the SLO is enabled", + "type": "boolean", + "example": true + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "find_slo_response": { + "title": "Find SLO response", + "description": "A paginated response of SLOs matching the query.\n", + "type": "object", + "properties": { + "page": { + "type": "number", + "example": 1 + }, + "perPage": { + "type": "number", + "example": 25 + }, + "total": { + "type": "number", + "example": 34 + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "create_slo_request": { + "title": "Create SLO request", + "description": "The create SLO API request body varies depending on the type of indicator, time window and budgeting method.\n", + "type": "object", + "required": [ + "name", + "description", + "indicator", + "timeWindow", + "budgetingMethod", + "objective" + ], + "properties": { + "id": { + "description": "A optional and unique identifier for the SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-slo-id" + }, + "name": { + "description": "A name for the SLO.", + "type": "string" + }, + "description": { + "description": "A description for the SLO.", + "type": "string" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + } + } + }, + "create_slo_response": { + "title": "Create SLO response", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + }, + "update_slo_request": { + "title": "Update SLO request", + "description": "The update SLO API request body varies depending on the type of indicator, time window and budgeting method. Partial update is handled.\n", + "type": "object", + "properties": { + "name": { + "description": "A name for the SLO.", + "type": "string" + }, + "description": { + "description": "A description for the SLO.", + "type": "string" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + } + } + }, + "historical_summary_request": { + "title": "Historical summary request", + "type": "object", + "required": [ + "sloIds" + ], + "properties": { + "sloIds": { + "description": "The list of SLO identifiers to get the historical summary for", + "type": "array", + "items": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + } + }, + "historical_summary_response": { + "title": "Historical summary response", + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "date": { + "type": "string", + "example": "2022-01-01T00:00:00.000Z" + }, + "status": { + "type": "string", + "enum": [ + "NO_DATA", + "HEALTHY", + "DEGRADING", + "VIOLATED" + ], + "example": "HEALTHY" + }, + "sliValue": { + "type": "number", + "example": 0.9836 + }, + "errorBudget": { + "$ref": "#/components/schemas/error_budget" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index 59d600a9e13753..f4ef3a5991387a 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -8,14 +8,17 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license +servers: + - url: http://localhost:5601 + description: local +security: + - basicAuth: [] + - apiKeyAuth: [] tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. -servers: - - url: http://localhost:5601 - description: local paths: /s/{spaceId}/api/observability/composite_slos: post: @@ -53,6 +56,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '409': description: Conflict - The Composite SLO id already exists content: @@ -121,6 +130,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -158,6 +173,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -200,6 +221,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -232,6 +259,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -274,6 +307,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '409': description: Conflict - The SLO id already exists content: @@ -360,6 +399,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -397,6 +442,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -439,6 +490,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -471,6 +528,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -504,6 +567,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -537,6 +606,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -579,6 +654,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' components: securitySchemes: basicAuth: @@ -817,6 +898,23 @@ components: message: type: string example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + 403_response: + title: Unauthorized + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 403 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" 404_response: title: Not found type: object @@ -1405,6 +1503,3 @@ components: example: 0.9836 errorBudget: $ref: '#/components/schemas/error_budget' -security: - - basicAuth: [] - - apiKeyAuth: [] diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml new file mode 100644 index 00000000000000..24fcbad202a83d --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml @@ -0,0 +1,16 @@ +title: Unauthorized +type: object +required: + - statusCode + - error + - message +properties: + statusCode: + type: number + example: 403 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml index e8e3cf75decc38..d77431452136ad 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml @@ -24,16 +24,22 @@ post: $ref: '../components/schemas/create_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '409': description: Conflict - The Composite SLO id already exists content: @@ -91,19 +97,25 @@ get: $ref: '../components/schemas/find_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml index 54b3613c7a5c46..bca3976b80fcd2 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml @@ -19,19 +19,25 @@ get: $ref: '../components/schemas/composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -63,19 +69,25 @@ put: $ref: '../components/schemas/base_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -97,19 +109,25 @@ delete: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml index 47fec9eee6494d..68c0c602448dce 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml @@ -24,16 +24,22 @@ post: $ref: '../components/schemas/create_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '409': description: Conflict - The SLO id already exists content: @@ -65,9 +71,9 @@ get: description: Filter by indicator type schema: type: array - items: + items: type: string - example: ["sli.kql.custom"] + example: ['sli.kql.custom'] - name: page in: query description: The page number to return @@ -107,19 +113,25 @@ get: $ref: '../components/schemas/find_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml index 48ffe492a5a2b7..6ce99505894cfb 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml @@ -18,19 +18,25 @@ post: responses: '200': description: Successful request - content: + content: application/json: schema: $ref: '../components/schemas/historical_summary_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml index cf31ccb2de8bfe..66a5ddd7825a83 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml @@ -19,19 +19,25 @@ get: $ref: '../components/schemas/slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -63,19 +69,25 @@ put: $ref: '../components/schemas/slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -97,19 +109,25 @@ delete: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml index ace5b805cf92f7..4932e9cf78c369 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml @@ -15,19 +15,25 @@ post: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml index d751535fe365a5..4ddda2bc94b603 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml @@ -15,19 +15,25 @@ post: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx index 2d71fca18eede4..6e733985275238 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx @@ -76,7 +76,7 @@ export function HeaderControl({ isLoading, slo }: Props) { params: { sloId: slo.id }, }, { - replace: true, + replace: false, } ); } diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx index 3d9e70f68dc6ec..374b64b5674040 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx @@ -106,7 +106,7 @@ export function SloListItem({ params: { sloId: slo.id }, }, { - replace: true, + replace: false, } ); }; diff --git a/x-pack/plugins/observability/server/routes/slo/route.ts b/x-pack/plugins/observability/server/routes/slo/route.ts index 52c6aa3cff0d49..f41d37d4fc5731 100644 --- a/x-pack/plugins/observability/server/routes/slo/route.ts +++ b/x-pack/plugins/observability/server/routes/slo/route.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { badRequest, forbidden, failedDependency } from '@hapi/boom'; +import { forbidden, failedDependency } from '@hapi/boom'; import { createSLOParamsSchema, deleteSLOParamsSchema, @@ -68,7 +68,7 @@ const createSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -95,7 +95,7 @@ const updateSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -127,7 +127,7 @@ const deleteSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -153,7 +153,7 @@ const getSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -178,7 +178,7 @@ const enableSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -204,7 +204,7 @@ const disableSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -230,7 +230,7 @@ const findSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -255,7 +255,7 @@ const fetchHistoricalSummary = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -317,7 +317,7 @@ const getSloBurnRates = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -340,7 +340,7 @@ const getPreviewData = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; From cd04cd305a29431200f9f8e08211ee0065fcfaca Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Tue, 4 Jul 2023 10:51:09 -0700 Subject: [PATCH 63/98] [Cloud Security][FTR]Refactor API FTR to use .to.eql instead of .to.be (#160694) ## Summary This PR is for refactoring current API FTR to use .to.eql instead of .to.be for more understandable error message when an error occurs. Currently when test fail due to unmatched value, the error message can be quite confusing as we don't know which one is the expected and actual value from current error message. With this change from this PR it's easier to see which is the expected value and which is the actual value Screenshot 2023-06-27 at 7 49 07 PM --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../get_csp_rule_template.ts | 35 +++++-- .../apis/cloud_security_posture/helper.ts | 14 +++ .../status/status_index_timeout.ts | 15 ++- .../status/status_indexed.ts | 15 ++- .../status/status_indexing.ts | 15 ++- .../status_not_deployed_not_installed.ts | 75 ++++++++++++--- .../status/status_unprivileged.ts | 94 ++++++++++++++----- .../status/status_waiting_for_results.ts | 15 ++- 8 files changed, 217 insertions(+), 61 deletions(-) diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts b/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts index 1d91efdc7fe895..99fa403c226352 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts @@ -55,8 +55,9 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(500); - expect(body.message).to.be( - 'Please provide either benchmarkId or packagePolicyId, but not both' + expect(body.message).to.eql( + 'Please provide either benchmarkId or packagePolicyId, but not both', + `expected message to be 'Please provide either benchmarkId or packagePolicyId, but not both' but got ${body.message} instead` ); }); @@ -80,8 +81,9 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(500); - expect(body.message).to.be( - 'Please provide either benchmarkId or packagePolicyId, but not both' + expect(body.message).to.eql( + 'Please provide either benchmarkId or packagePolicyId, but not both', + `expected message to be 'Please provide either benchmarkId or packagePolicyId, but not both' but got ${body.message} instead` ); }); @@ -95,8 +97,14 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(404); - expect(body.statusCode).to.be(404); - expect(body.error).to.be('Not Found'); + expect(body.statusCode).to.eql( + 404, + `expected status code to be 404 but got ${body.statusCode} instead` + ); + expect(body.error).to.eql( + 'Not Found', + `expected error message to be 'Not Found' but got ${body.error} instead` + ); }); it(`Should return 200 status code and filter rules by benchmarkId`, async () => { @@ -124,7 +132,10 @@ export default function ({ getService }: FtrProviderContext) { (rule: CspRuleTemplate) => rule.metadata.benchmark.id === 'cis_k8s' ); - expect(allRulesHaveCorrectBenchmarkId).to.be(true); + expect(allRulesHaveCorrectBenchmarkId).to.eql( + true, + `expected true but got ${allRulesHaveCorrectBenchmarkId} instead` + ); }); it(`Should return 200 status code, and only requested fields in the response`, async () => { @@ -157,7 +168,7 @@ export default function ({ getService }: FtrProviderContext) { ); }); - expect(fieldsMatched).to.be(true); + expect(fieldsMatched).to.eql(true, `expected true but got ${fieldsMatched} instead`); }); it(`Should return 200 status code, items sorted by metadata.section field`, async () => { @@ -188,7 +199,8 @@ export default function ({ getService }: FtrProviderContext) { const isSorted = sections.every( (section, index) => index === 0 || section >= sections[index - 1] ); - expect(isSorted).to.be(true); + + expect(isSorted).to.eql(true, `expected true but got ${isSorted} instead`); }); it(`Should return 200 status code and paginate rules with a limit of PerPage`, async () => { @@ -213,7 +225,10 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(200); - expect(body.items.length).to.be(perPage); + expect(body.items.length).to.eql( + perPage, + `expected length to be ${perPage} but got ${body.items.length} instead` + ); }); }); } diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts b/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts index b659153b1bf690..79aede12385db9 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts @@ -7,6 +7,8 @@ import type { SuperTest, Test } from 'supertest'; import { Client } from '@elastic/elasticsearch'; +import expect from '@kbn/expect'; +import type { IndexDetails } from '@kbn/cloud-security-posture-plugin/common/types'; import { SecurityService } from '../../../../../test/common/services/security/security'; export const deleteIndex = (es: Client, indexToBeDeleted: string[]) => { @@ -141,3 +143,15 @@ export const deleteRole = async (security: SecurityService, roleName: string) => export const deleteUser = async (security: SecurityService, userName: string) => { await security.user.delete(userName); }; + +export const assertIndexStatus = ( + indicesDetails: IndexDetails[], + indexName: string, + expectedStatus: string +) => { + const actualValue = indicesDetails.find((idx) => idx.index === indexName)?.status; + expect(actualValue).to.eql( + expectedStatus, + `expected ${indexName} status to be ${expectedStatus} but got ${actualValue} instead` + ); +}; diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts index fe52d8d3a07736..2203a6374db701 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts @@ -110,7 +110,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('index-timeout'); + expect(res.kspm.status).to.eql( + 'index-timeout', + `expected kspm status to be index-timeout but got ${res.kspm.status} instead` + ); }); it(`Should return index-timeout when installed cspm, has findings only on logs-cloud_security_posture.findings-default* and it has been more than 10 minutes since the installation`, async () => { @@ -137,7 +140,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('index-timeout'); + expect(res.cspm.status).to.eql( + 'index-timeout', + `expected cspm status to be index-timeout but got ${res.cspm.status} instead` + ); }); it(`Should return index-timeout when installed cnvm, has findings only on logs-cloud_security_posture.vulnerabilities-default* and it has been more than 4 hours minutes since the installation`, async () => { @@ -164,7 +170,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('index-timeout'); + expect(res.vuln_mgmt.status).to.eql( + 'index-timeout', + `expected vuln_mgmt status to be index-timeout but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts index aa9d6d3289e95d..594babe643b058 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts @@ -76,7 +76,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('indexed'); + expect(res.kspm.status).to.eql( + 'indexed', + `expected kspm status to be indexed but got ${res.kspm.status} instead` + ); }); it(`Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents`, async () => { @@ -95,7 +98,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('indexed'); + expect(res.cspm.status).to.eql( + 'indexed', + `expected cspm status to be indexed but got ${res.cspm.status} instead` + ); }); it(`Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents`, async () => { @@ -114,7 +120,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('indexed'); + expect(res.vuln_mgmt.status).to.eql( + 'indexed', + `expected vuln_mgmt status to be indexed but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts index ef16eb94d8a333..ef38ab85efb041 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts @@ -75,7 +75,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('indexing'); + expect(res.kspm.status).to.eql( + 'indexing', + `expected kspm status to be indexing but got ${res.kspm.status} instead` + ); }); it(`Return cspm status indexing when logs-cloud_security_posture.findings_latest-default doesn't contain new cspm documents, but has newly connected agents `, async () => { @@ -94,7 +97,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('indexing'); + expect(res.cspm.status).to.eql( + 'indexing', + `expected cspm status to be indexing but got ${res.cspm.status} instead` + ); }); it(`Return vuln status indexing when logs-cloud_security_posture.vulnerabilities_latest-default doesn't contain vuln new documents, but has newly connected agents`, async () => { @@ -113,7 +119,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('indexing'); + expect(res.vuln_mgmt.status).to.eql( + 'indexing', + `expected vuln_mgmt status to be indexing but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts index d7d77c93ecad4a..dcfbedae157415 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts @@ -55,11 +55,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('not-deployed'); - expect(res.cspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-installed'); - expect(res.kspm.healthyAgents).to.be(0); - expect(res.kspm.installedPackagePolicies).to.be(1); + expect(res.kspm.status).to.eql( + 'not-deployed', + `expected kspm status to be not-deployed but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'not-installed', + `expected cspm status to be not-installed but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected vuln_mgmt status to be not-installed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.kspm.healthyAgents).to.eql( + 0, + `expected number of kspm healthy agents to be 0 but got ${res.kspm.healthyAgents} instead` + ); + expect(res.kspm.installedPackagePolicies).to.eql( + 1, + `expected number of kspm installed package policies to be 1 but got ${res.kspm.installedPackagePolicies} instead` + ); }); it(`Should return not-deployed when installed cspm, no findings on either indices and no healthy agents`, async () => { @@ -78,11 +93,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('not-deployed'); - expect(res.kspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-installed'); - expect(res.cspm.healthyAgents).to.be(0); - expect(res.cspm.installedPackagePolicies).to.be(1); + expect(res.cspm.status).to.eql( + 'not-deployed', + `expected cspm status to be not-deployed but got ${res.cspm.status} instead` + ); + expect(res.kspm.status).to.eql( + 'not-installed', + `expected kspm status to be not-installed but got ${res.kspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected vuln_mgmt status to be not-installed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.cspm.healthyAgents).to.eql( + 0, + `expected number of cspm healthy agents to be 0 but got ${res.cspm.healthyAgents} instead` + ); + expect(res.cspm.installedPackagePolicies).to.eql( + 1, + `expected number of cspm installed package policies to be 1 but got ${res.cspm.installedPackagePolicies} instead` + ); }); it(`Should return not-deployed when installed cnvm, no findings on either indices and no healthy agents`, async () => { @@ -101,11 +131,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('not-installed'); - expect(res.kspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-deployed'); - expect(res.vuln_mgmt.healthyAgents).to.be(0); - expect(res.vuln_mgmt.installedPackagePolicies).to.be(1); + expect(res.cspm.status).to.eql( + 'not-installed', + `expected cspm status to be not-installed but got ${res.cspm.status} instead` + ); + expect(res.kspm.status).to.eql( + 'not-installed', + `expected kspm status to be not-installed but got ${res.kspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-deployed', + `expected vuln_mgmt status to be not-deployed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.vuln_mgmt.healthyAgents).to.eql( + 0, + `expected number of vuln_mgmt healthy agents to be 0 but got ${res.vuln_mgmt.healthyAgents} instead` + ); + expect(res.vuln_mgmt.installedPackagePolicies).to.eql( + 1, + `expected number of vuln_mgmt installed package policies to be 1 but got ${res.vuln_mgmt.installedPackagePolicies} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts index 2432165566de81..7d1445932fa6c8 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts @@ -11,6 +11,7 @@ import { BENCHMARK_SCORE_INDEX_DEFAULT_NS, LATEST_FINDINGS_INDEX_DEFAULT_NS, LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + FINDINGS_INDEX_PATTERN, } from '@kbn/cloud-security-posture-plugin/common/constants'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { @@ -20,6 +21,7 @@ import { deleteRole, deleteUser, deleteIndex, + assertIndexStatus, } from '../helper'; const UNPRIVILEGED_ROLE = 'unprivileged_test_role'; @@ -85,9 +87,18 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); }); }); @@ -134,14 +145,27 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('empty'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('unprivileged'); - expect(res.indicesDetails[3].status).to.be('unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'empty'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus( + res.indicesDetails, + LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + 'unprivileged' + ); }); it(`Return unprivileged when missing access to score index`, async () => { @@ -165,14 +189,27 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('unprivileged'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('empty'); - expect(res.indicesDetails[3].status).to.be('unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'empty'); + assertIndexStatus( + res.indicesDetails, + LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + 'unprivileged' + ); }); it(`Return unprivileged when missing access to vulnerabilities_latest index`, async () => { @@ -199,14 +236,23 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('not-installed'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected not-installed but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('unprivileged'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('unprivileged'); - expect(res.indicesDetails[3].status).to.be('empty'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, 'empty'); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts index 53692014f767a1..bc6a44100dab01 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts @@ -91,7 +91,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('waiting_for_results'); + expect(res.kspm.status).to.eql( + 'waiting_for_results', + `expected kspm status to be waiting_for_results but got ${res.kspm.status} instead` + ); }); it(`Should return waiting_for_result when installed cspm, has no findings and it has been less than 10 minutes since the installation`, async () => { @@ -117,7 +120,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('waiting_for_results'); + expect(res.cspm.status).to.eql( + 'waiting_for_results', + `expected cspm status to be waiting_for_results but got ${res.cspm.status} instead` + ); }); it(`Should return waiting_for_result when installed cnvm, has no findings and it has been less than 4 hours minutes since the installation`, async () => { @@ -143,7 +149,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('waiting_for_results'); + expect(res.vuln_mgmt.status).to.eql( + 'waiting_for_results', + `expected vuln_mgmt status to be waiting_for_results but got ${res.vuln_mgmt.status} instead` + ); }); }); }); From 6731eb300846fc25440d30ec32c296139175bacc Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 4 Jul 2023 13:55:05 -0400 Subject: [PATCH 64/98] [Synthetics] Perform params API HTTP migration (#160575) Co-authored-by: shahzad31 --- .../monitor_management/synthetics_params.ts | 22 ++++++- .../global_params/add_param_flyout.tsx | 6 +- .../settings/global_params/add_param_form.tsx | 6 +- .../settings/global_params/delete_param.tsx | 4 +- .../settings/global_params/params_list.tsx | 4 +- .../settings/hooks/use_params_list.ts | 7 +-- .../apps/synthetics/state/certs/index.ts | 4 +- .../synthetics/state/global_params/actions.ts | 9 ++- .../synthetics/state/global_params/api.ts | 49 +++++++-------- .../synthetics/state/global_params/index.ts | 7 +-- .../public/utils/api_service/api_service.ts | 59 +++++++------------ .../server/routes/settings/add_param.ts | 41 +++++++++++-- .../server/routes/settings/delete_param.ts | 13 +++- .../server/routes/settings/edit_param.ts | 23 ++++++-- .../server/routes/settings/params.ts | 50 ++++++++++------ .../synthetics_service/synthetics_service.ts | 4 +- .../apis/synthetics/add_edit_params.ts | 54 +++++++++-------- .../apis/synthetics/sync_global_params.ts | 17 +++--- 18 files changed, 222 insertions(+), 157 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts index 078dfa7b45d049..9c2a5b1eb4ff14 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts @@ -7,10 +7,10 @@ import * as t from 'io-ts'; -export const SyntheticsParamSOCodec = t.intersection([ +export const SyntheticsParamsReadonlyCodec = t.intersection([ t.interface({ + id: t.string, key: t.string, - value: t.string, }), t.partial({ description: t.string, @@ -19,7 +19,23 @@ export const SyntheticsParamSOCodec = t.intersection([ }), ]); -export type SyntheticsParamSO = t.TypeOf; +export type SyntheticsParamsReadonly = t.TypeOf; + +export const SyntheticsParamsCodec = t.intersection([ + SyntheticsParamsReadonlyCodec, + t.interface({ value: t.string }), +]); + +export type SyntheticsParams = t.TypeOf; + +export type SyntheticsParamSOAttributes = t.TypeOf; + +export const DeleteParamsResponseCodec = t.interface({ + id: t.string, + deleted: t.boolean, +}); + +export type DeleteParamsResponse = t.TypeOf; export const SyntheticsParamRequestCodec = t.intersection([ t.interface({ diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx index 4181afdfd6a3e8..c79e5aec2177a1 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx @@ -31,7 +31,7 @@ import { } from '../../../state/global_params'; import { ClientPluginsStart } from '../../../../../plugin'; import { ListParamItem } from './params_list'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { useFormWrapped } from '../../../../../hooks/use_form_wrapped'; import { AddParamForm } from './add_param_form'; import { syncGlobalParamsAction } from '../../../state/settings'; @@ -49,7 +49,7 @@ export const AddParamFlyout = ({ const { id, ...dataToSave } = isEditingItem ?? {}; - const form = useFormWrapped({ + const form = useFormWrapped({ mode: 'onSubmit', reValidateMode: 'onChange', shouldFocusError: true, @@ -77,7 +77,7 @@ export const AddParamFlyout = ({ const { isSaving, savedData } = useSelector(selectGlobalParamState); - const onSubmit = (formData: SyntheticsParamSO) => { + const onSubmit = (formData: SyntheticsParams) => { const { namespaces, ...paramRequest } = formData; const shareAcrossSpaces = namespaces?.includes(ALL_SPACES_ID); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx index 240314dc3b06fe..1b219a0f6fec40 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Controller, useFormContext, useFormState } from 'react-hook-form'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { ListParamItem } from './params_list'; export const AddParamForm = ({ @@ -26,8 +26,8 @@ export const AddParamForm = ({ items: ListParamItem[]; isEditingItem: ListParamItem | null; }) => { - const { register, control } = useFormContext(); - const { errors } = useFormState(); + const { register, control } = useFormContext(); + const { errors } = useFormState(); const tagsList = items.reduce((acc, item) => { const tags = item.tags || []; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx index 21d3c158c33268..aa89829380044c 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx @@ -35,14 +35,14 @@ export const DeleteParam = ({ const { status } = useFetcher(() => { if (isDeleting) { - return deleteGlobalParams({ ids: items.map(({ id }) => id) }); + return deleteGlobalParams(items.map(({ id }) => id)); } }, [items, isDeleting]); const name = items .map(({ key }) => key) .join(', ') - .substr(0, 50); + .slice(0, 50); useEffect(() => { if (!isDeleting) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx index fc8aef5d567325..58769a7e688fea 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx @@ -24,12 +24,12 @@ import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/bas import { useDebounce } from 'react-use'; import { TableTitle } from '../../common/components/table_title'; import { ParamsText } from './params_text'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { useParamsList } from '../hooks/use_params_list'; import { AddParamFlyout } from './add_param_flyout'; import { DeleteParam } from './delete_param'; -export interface ListParamItem extends SyntheticsParamSO { +export interface ListParamItem extends SyntheticsParams { id: string; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts index 4f86ca5eb8d80b..40006c262923e5 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts @@ -20,12 +20,7 @@ export const useParamsList = () => { return useMemo(() => { return { - items: - listOfParams?.map((item) => ({ - id: item.id, - ...item.attributes, - namespaces: item.namespaces, - })) ?? [], + items: listOfParams ?? [], isLoading, }; }, [listOfParams, isLoading]); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts index f21df69bcbbce4..708e1bb004a742 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts @@ -6,7 +6,7 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { CertResult, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { CertResult, SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { getCertsListAction } from './actions'; @@ -15,7 +15,7 @@ export interface CertsListState { data?: CertResult; error: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: CertsListState = { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts index 14b5040282f52a..b1388bc2674b98 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts @@ -5,15 +5,14 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../../../common/runtime_types'; import { createAsyncAction } from '../utils/actions'; -export const getGlobalParamAction = createAsyncAction>>( +export const getGlobalParamAction = createAsyncAction( 'GET GLOBAL PARAMS' ); -export const addNewGlobalParamAction = createAsyncAction( +export const addNewGlobalParamAction = createAsyncAction( 'ADD NEW GLOBAL PARAM' ); @@ -22,5 +21,5 @@ export const editGlobalParamAction = createAsyncAction< id: string; paramRequest: SyntheticsParamRequest; }, - SyntheticsParamSO + SyntheticsParams >('EDIT GLOBAL PARAM'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts index 3fd5e8678d94bc..528921f1d5bf4c 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts @@ -5,23 +5,28 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; import { SYNTHETICS_API_URLS } from '../../../../../common/constants'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { + DeleteParamsResponse, + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamsCodec, + SyntheticsParamsReadonlyCodec, +} from '../../../../../common/runtime_types'; import { apiService } from '../../../../utils/api_service/api_service'; -export const getGlobalParams = async (): Promise>> => { - const result = (await apiService.get(SYNTHETICS_API_URLS.PARAMS)) as { - data: Array>; - }; - return result.data; +export const getGlobalParams = async (): Promise => { + return apiService.get( + SYNTHETICS_API_URLS.PARAMS, + undefined, + SyntheticsParamsReadonlyCodec + ); }; export const addGlobalParam = async ( paramRequest: SyntheticsParamRequest -): Promise => { - return apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest); -}; +): Promise => + apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest, SyntheticsParamsCodec); export const editGlobalParam = async ({ paramRequest, @@ -29,19 +34,17 @@ export const editGlobalParam = async ({ }: { id: string; paramRequest: SyntheticsParamRequest; -}): Promise => { - return apiService.put(SYNTHETICS_API_URLS.PARAMS, { - id, - ...paramRequest, - }); -}; +}): Promise => + apiService.put( + SYNTHETICS_API_URLS.PARAMS, + { + id, + ...paramRequest, + }, + SyntheticsParamsCodec + ); -export const deleteGlobalParams = async ({ - ids, -}: { - ids: string[]; -}): Promise => { - return apiService.delete(SYNTHETICS_API_URLS.PARAMS, { +export const deleteGlobalParams = async (ids: string[]): Promise => + apiService.delete(SYNTHETICS_API_URLS.PARAMS, { ids: JSON.stringify(ids), }); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts index 6555518b6c505f..89b3a0b7e19040 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts @@ -6,18 +6,17 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { addNewGlobalParamAction, editGlobalParamAction, getGlobalParamAction } from './actions'; export interface GlobalParamsState { isLoading?: boolean; - listOfParams?: Array>; + listOfParams?: SyntheticsParams[]; addError: IHttpSerializedFetchError | null; editError: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: GlobalParamsState = { diff --git a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts index b73b353f708f2e..9dead89809ee91 100644 --- a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts +++ b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts @@ -41,20 +41,7 @@ class ApiService { return ApiService.instance; } - public async get( - apiUrl: string, - params?: HttpFetchQuery, - decodeType?: any, - asResponse = false - ) { - const response = await this._http!.fetch({ - path: apiUrl, - query: params, - asResponse, - }); - - this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - + private parseResponse(response: Awaited, apiUrl: string, decodeType?: any): T { if (decodeType) { const decoded = decodeType.decode(response); if (isRight(decoded)) { @@ -69,10 +56,26 @@ class ApiService { ); } } - return response; } + public async get( + apiUrl: string, + params?: HttpFetchQuery, + decodeType?: any, + asResponse = false + ) { + const response = await this._http!.fetch({ + path: apiUrl, + query: params, + asResponse, + }); + + this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); + + return this.parseResponse(response, apiUrl, decodeType); + } + public async post(apiUrl: string, data?: any, decodeType?: any, params?: HttpFetchQuery) { const response = await this._http!.post(apiUrl, { method: 'POST', @@ -82,18 +85,7 @@ class ApiService { this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async put(apiUrl: string, data?: any, decodeType?: any) { @@ -102,18 +94,7 @@ class ApiService { body: JSON.stringify(data), }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async delete(apiUrl: string, params?: HttpFetchQuery) { diff --git a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts index b27ddf27a88b36..875e4da8694e13 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts @@ -8,8 +8,13 @@ import { schema } from '@kbn/config-schema'; import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; +import { IKibanaResponse } from '@kbn/core/server'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../common/runtime_types'; +import { + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamSOAttributes, +} from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +31,12 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ request, response, server, savedObjectsClient }): Promise => { + handler: async ({ + request, + response, + server, + savedObjectsClient, + }): Promise> => { try { const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -34,14 +44,33 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ const { share_across_spaces: shareAcrossSpaces, ...data } = request.body as SyntheticsParamRequest; - const result = await savedObjectsClient.create(syntheticsParamType, data, { - initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + const { + attributes: { key, tags, description }, + id, + namespaces, + } = await savedObjectsClient.create>( + syntheticsParamType, + data, + { + initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + } + ); + return response.ok({ + body: { + id, + description, + key, + namespaces, + tags, + value: data.value, + }, }); - return { data: result }; } catch (error) { if (error.output?.statusCode === 404) { const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; - return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } }); + return response.notFound({ + body: { message: `Kibana space '${spaceId}' does not exist` }, + }); } throw error; diff --git a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts index 7dd839a3210889..dc529902b730f6 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts @@ -5,10 +5,12 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { DeleteParamsResponse } from '../../../common/runtime_types'; export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'DELETE', @@ -19,7 +21,11 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + }): Promise> => { const { ids } = request.query as { ids: string }; const parsedIds = JSON.parse(ids) as string[]; @@ -27,7 +33,8 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => parsedIds.map((id) => ({ type: syntheticsParamType, id })), { force: true } ); - - return { data: result }; + return response.ok({ + body: result.statuses.map(({ id, success }) => ({ id, deleted: success })), + }); }, }); diff --git a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts index 0201f350249c62..b235d0b323c8b6 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts @@ -6,9 +6,10 @@ */ import { schema } from '@kbn/config-schema'; +import { IKibanaResponse, SavedObject } from '@kbn/core/server'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest } from '../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +27,12 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + server, + }): Promise> => { try { const { id: _spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -39,9 +45,18 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ id: string; }; - const result = await savedObjectsClient.update(syntheticsParamType, id, data); + const { value } = data; + const { + id: responseId, + attributes: { key, tags, description }, + namespaces, + } = (await savedObjectsClient.update( + syntheticsParamType, + id, + data + )) as SavedObject; - return { data: result }; + return response.ok({ body: { id: responseId, key, tags, description, namespaces, value } }); } catch (error) { if (error.output?.statusCode === 404) { const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; diff --git a/x-pack/plugins/synthetics/server/routes/settings/params.ts b/x-pack/plugins/synthetics/server/routes/settings/params.ts index 5622438ab47c0b..789761c529e846 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/params.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/params.ts @@ -5,52 +5,66 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server'; -import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { SyntheticsParams, SyntheticsParamsReadonly } from '../../../common/runtime_types'; -export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ +type SyntheticsParamsResponse = + | IKibanaResponse + | IKibanaResponse; +export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory< + SyntheticsParamsResponse +> = () => ({ method: 'GET', path: SYNTHETICS_API_URLS.PARAMS, validate: {}, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ savedObjectsClient, request, response, server, spaceId }) => { try { const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); - const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { - id: DEFAULT_SPACE_ID, - }; - const canSave = (await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false; if (canSave) { const finder = - await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({ - type: syntheticsParamType, - perPage: 1000, - namespaces: [spaceId], - }); + await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + { + type: syntheticsParamType, + perPage: 1000, + namespaces: [spaceId], + } + ); - const hits: SavedObjectsFindResult[] = []; + const hits: Array> = []; for await (const result of finder.find()) { hits.push(...result.saved_objects); } - return { data: hits }; + return response.ok({ + body: hits.map(({ id, attributes, namespaces }) => ({ + ...attributes, + id, + namespaces, + })), + }); } else { - const data = await savedObjectsClient.find({ + const data = await savedObjectsClient.find({ type: syntheticsParamType, perPage: 10000, }); - - return { data: data.saved_objects }; + return response.ok({ + body: data.saved_objects.map(({ id, attributes, namespaces }) => ({ + ...attributes, + namespaces, + id, + })), + }); } } catch (error) { if (error.output?.statusCode === 404) { - const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } }); } diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index a464e4ea0f9718..ecfb10cc1632f0 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -36,7 +36,7 @@ import { ServiceLocations, SyntheticsMonitorWithId, SyntheticsMonitorWithSecrets, - SyntheticsParamSO, + SyntheticsParams, ThrottlingOptions, } from '../../common/runtime_types'; import { getServiceLocations } from './get_service_locations'; @@ -599,7 +599,7 @@ export class SyntheticsService { const paramsBySpace: Record> = Object.create(null); const finder = - await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ + await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ type: syntheticsParamType, perPage: 1000, namespaces: spaceId ? [spaceId] : undefined, diff --git a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts index b052a06e8bf52b..f5d9256a13b4d6 100644 --- a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts @@ -4,13 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { v4 as uuidv4 } from 'uuid'; +import { pick } from 'lodash'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import expect from '@kbn/expect'; import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PrivateLocationTestService } from './services/private_location_test_service'; +function assertHas(actual: unknown, expected: object) { + expect(pick(actual, Object.keys(expected))).eql(expected); +} + export default function ({ getService }: FtrProviderContext) { describe('AddEditParams', function () { this.tags('skipCloud'); @@ -40,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam); + assertHas(getResponse.body[0], testParam); }); it('handles tags and description', async () => { @@ -63,11 +69,11 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam2); + assertHas(getResponse.body[0], testParam2); }); it('handles editing a param', async () => { - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -84,21 +90,21 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, id: param.id }) .expect(200); const updatedGetResponse = await supertestAPI .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(updatedParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('handles spaces', async () => { @@ -118,8 +124,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql([SPACE_ID]); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql([SPACE_ID]); + assertHas(getResponse.body[0], testParam); }); it('handles editing a param in spaces', async () => { @@ -128,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) { await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -145,21 +151,21 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, id: param.id }) .expect(200); const updatedGetResponse = await supertestAPI .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(updatedParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('does not allow editing a param in created in one space in a different space', async () => { @@ -188,8 +194,8 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); // space does exist so get request should be 200 await supertestAPI @@ -207,8 +213,8 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(testParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, testParam); }); it('handles invalid spaces', async () => { @@ -241,8 +247,8 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`) @@ -268,8 +274,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql(['*']); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql(['*']); + assertHas(getResponse.body[0], testParam); }); }); } diff --git a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts index 2840f8f3935f64..e8182d97e0fee2 100644 --- a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts @@ -7,7 +7,7 @@ import { ConfigKey, HTTPFields, - SyntheticsParamSO, + SyntheticsParams, } from '@kbn/synthetics-plugin/common/runtime_types'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { omit } from 'lodash'; @@ -15,7 +15,6 @@ import { secretKeys } from '@kbn/synthetics-plugin/common/constants/monitor_mana import { PackagePolicy } from '@kbn/fleet-plugin/common'; import expect from '@kbn/expect'; import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects'; -import { SavedObject } from '@kbn/core-saved-objects-server'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; @@ -157,8 +156,8 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.status).eql(200); - apiResponse.body.data.forEach(({ attributes }: SavedObject) => { - params[attributes.key] = attributes.value; + apiResponse.body.forEach(({ key, value }: SyntheticsParams) => { + params[key] = value; }); }); @@ -257,23 +256,25 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data.length).eql(2); + expect(getResponse.body.length).eql(2); - const paramsResponse = getResponse.body.data || []; + const paramsResponse = getResponse.body || []; const ids = paramsResponse.map((param: any) => param.id); - await supertestAPI + const deleteResponse = await supertestAPI .delete(SYNTHETICS_API_URLS.PARAMS) .query({ ids: JSON.stringify(ids) }) .set('kbn-xsrf', 'true') .expect(200); + expect(deleteResponse.body).to.have.length(2); + const getResponseAfterDelete = await supertestAPI .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - expect(getResponseAfterDelete.body.data.length).eql(0); + expect(getResponseAfterDelete.body.length).eql(0); await supertestAPI .get(SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS) From 803d139adc0df932146c6e21c2814c4fc2921bd3 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Tue, 4 Jul 2023 15:35:40 -0500 Subject: [PATCH 65/98] [data views] Fix overwrite param for create (#160953) ## Summary Under some circumstances passing `override` to `POST /api/data_views/data_view` would fail. Its now fixed. To test - Try using the override param from the Kibana dev console. I found it reproduced the problem before the fix and shows its resolved after the fix. The problem did not appear in the integration tests. I suspect the problem had to do with how quickly the delete was performed - if it completed before the create command then everything was fine. If it didn't then the error would appear. Passing the overwrite param to the saved object client eliminates the possibility of the delete failing to complete. Closes https://github.com/elastic/kibana/issues/161016 --- .../common/content_management/v1/cm_services.ts | 1 + .../common/content_management/v1/types.ts | 1 + .../data_views/common/data_views/data_views.ts | 15 ++++++++++----- src/plugins/data_views/common/types.ts | 2 +- .../data_views/fields_api/update_fields/main.ts | 1 + 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/data_views/common/content_management/v1/cm_services.ts b/src/plugins/data_views/common/content_management/v1/cm_services.ts index 7ff2d135a9d90e..e425a40cce4331 100644 --- a/src/plugins/data_views/common/content_management/v1/cm_services.ts +++ b/src/plugins/data_views/common/content_management/v1/cm_services.ts @@ -54,6 +54,7 @@ const dataViewSavedObjectSchema = savedObjectSchema(dataViewAttributesSchema); const dataViewCreateOptionsSchema = schema.object({ id: createOptionsSchemas.id, initialNamespaces: createOptionsSchemas.initialNamespaces, + overwrite: schema.maybe(createOptionsSchemas.overwrite), }); const dataViewSearchOptionsSchema = schema.object({ diff --git a/src/plugins/data_views/common/content_management/v1/types.ts b/src/plugins/data_views/common/content_management/v1/types.ts index 1bada30b8dd948..19637bb17e8c56 100644 --- a/src/plugins/data_views/common/content_management/v1/types.ts +++ b/src/plugins/data_views/common/content_management/v1/types.ts @@ -18,6 +18,7 @@ import { DataViewContentType } from './constants'; interface DataViewCreateOptions { id?: SavedObjectCreateOptions['id']; initialNamespaces?: SavedObjectCreateOptions['initialNamespaces']; + overwrite?: SavedObjectCreateOptions['overwrite']; } interface DataViewUpdateOptions { diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 947e8884bc7cc2..f51189f2409ea1 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -167,7 +167,7 @@ export interface DataViewsServicePublicMethods { */ createSavedObject: ( indexPattern: DataView, - override?: boolean, + overwrite?: boolean, displayErrors?: boolean ) => Promise; /** @@ -964,12 +964,16 @@ export class DataViewsService { async createAndSave( spec: DataViewSpec, - override = false, + overwrite = false, skipFetchFields = false, displayErrors = true ) { const indexPattern = await this.createFromSpec(spec, skipFetchFields, displayErrors); - const createdIndexPattern = await this.createSavedObject(indexPattern, override, displayErrors); + const createdIndexPattern = await this.createSavedObject( + indexPattern, + overwrite, + displayErrors + ); await this.setDefault(createdIndexPattern.id!); return createdIndexPattern!; } @@ -981,14 +985,14 @@ export class DataViewsService { * @param displayErrors - If set false, API consumer is responsible for displaying and handling errors. */ - async createSavedObject(dataView: DataView, override = false, displayErrors = true) { + async createSavedObject(dataView: DataView, overwrite = false, displayErrors = true) { if (!(await this.getCanSave())) { throw new DataViewInsufficientAccessError(); } const dupe = await findByName(this.savedObjectsClient, dataView.getName()); if (dupe) { - if (override) { + if (overwrite) { await this.delete(dupe.id); } else { throw new DuplicateDataViewError(`Duplicate data view: ${dataView.getName()}`); @@ -1000,6 +1004,7 @@ export class DataViewsService { const response: SavedObject = (await this.savedObjectsClient.create(body, { id: dataView.id, initialNamespaces: dataView.namespaces.length > 0 ? dataView.namespaces : undefined, + overwrite, })) as SavedObject; const createdIndexPattern = await this.initFromSavedObject(response, displayErrors); diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index 6c42664c90ffb6..aa157d53366850 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -297,7 +297,7 @@ export interface SavedObjectsClientCommon { create: ( attributes: DataViewAttributes, // SavedObjectsCreateOptions - options: { id?: string; initialNamespaces?: string[] } + options: { id?: string; initialNamespaces?: string[]; overwrite?: boolean } ) => Promise; /** * Delete a saved object by id diff --git a/test/api_integration/apis/data_views/fields_api/update_fields/main.ts b/test/api_integration/apis/data_views/fields_api/update_fields/main.ts index d48dd90396e169..40c03bbec46c12 100644 --- a/test/api_integration/apis/data_views/fields_api/update_fields/main.ts +++ b/test/api_integration/apis/data_views/fields_api/update_fields/main.ts @@ -437,6 +437,7 @@ export default function ({ getService }: FtrProviderContext) { const title = indexPattern.title; await supertest.delete(`${config.path}/${indexPattern.id}`); const response1 = await supertest.post(config.path).send({ + override: true, [config.serviceKey]: { title, fields: { From 38abb33c35473f42ef324508ae217b9c7748ef4e Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Wed, 5 Jul 2023 12:27:46 +1000 Subject: [PATCH 66/98] Fix errors in custom metric payload in SLO dev docs (#161141) --- x-pack/plugins/observability/dev_docs/slo.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/observability/dev_docs/slo.md b/x-pack/plugins/observability/dev_docs/slo.md index 908bf0a031be4c..ab605e51ffd27b 100644 --- a/x-pack/plugins/observability/dev_docs/slo.md +++ b/x-pack/plugins/observability/dev_docs/slo.md @@ -337,17 +337,17 @@ curl --request POST \ "field": "processor.processed" } ], - equation: 'A' + "equation": "A" }, "total": { "metrics": [ { "name": "A", "aggregation": "sum", - "processor.accepted" + "field": "processor.accepted" } ], - equation: 'A' + "equation": "A" }, "filter": "", "timestampField": "@timestamp" From 74c3658dd6625a15899210fb83b6ad980f955e10 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 5 Jul 2023 00:52:31 -0400 Subject: [PATCH 67/98] [api-docs] 2023-07-05 Daily api_docs build (#161225) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/389 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 4 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 44 ++----- api_docs/data.mdx | 4 +- api_docs/data_query.mdx | 4 +- api_docs/data_search.mdx | 4 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.devdocs.json | 120 ++++++++++-------- api_docs/data_views.mdx | 4 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 10 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/ess_security.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...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 +- 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 +- ...kbn_core_saved_objects_common.devdocs.json | 28 ---- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.devdocs.json | 32 +++++ api_docs/management.mdx | 4 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 10 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 549 files changed, 673 insertions(+), 669 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index ad17a9658141de..458a5e8c9a6003 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-04 +date: 2023-07-05 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 d34f6b34e8a88c..d9b48790601d4e 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 5d81becf0cec87..af01029abd03c2 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-04 +date: 2023-07-05 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 67ed79d64cdc42..c967aa3c52c1b8 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -3152,7 +3152,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -3168,7 +3168,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 83e91fe75b1de3..e676fa90129820 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-04 +date: 2023-07-05 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 db7a984011e21b..bb1ae41c78010b 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index f40dd137025257..ab465634b7fad8 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-04 +date: 2023-07-05 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 7d6e5adc83ee91..02eaf1c996052d 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-04 +date: 2023-07-05 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 2a2fb8a2a57987..88a9a1a56b539e 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-04 +date: 2023-07-05 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 a87c0da4c59a76..33b9d541849d55 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-04 +date: 2023-07-05 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 6a2cd6b1983233..732a105f75e1ac 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-04 +date: 2023-07-05 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 48885ef8148b90..7ec5590bc8cea6 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-04 +date: 2023-07-05 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 2700c0dafcff8e..750dbc1f0843dc 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 9f18be8b202d44..d1e2e01d8026dd 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 6506992af3dbb0..d56a91c08416a3 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 7fabe7cee93bd6..0f5aa80fa2e39f 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-04 +date: 2023-07-05 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 bc999ca7a36e4d..bbab50b2fcb67c 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-04 +date: 2023-07-05 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 73b6bdc2b3fedb..864b49b9dca8d2 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-04 +date: 2023-07-05 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 6a25bf5adb97a5..30f67a44a05457 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-04 +date: 2023-07-05 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 2529761f7d5dd0..758799ddfb73fb 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-04 +date: 2023-07-05 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 2318d55651cf42..d191620df4054f 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 040339a1919688..1a6ed1ab648bfa 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-04 +date: 2023-07-05 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 409fc55ae8097c..48fb0d4a13824c 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-04 +date: 2023-07-05 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 2d9cce85dce5a1..5ad5c977a1182a 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-04 +date: 2023-07-05 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 7a9159bc2af6ca..9899d1c60a960b 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-04 +date: 2023-07-05 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 6e1ba8e0ec9f56..d46b463e72cfad 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -13292,10 +13292,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -16822,7 +16818,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -16864,10 +16860,8 @@ "id": "def-server.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -16931,7 +16925,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -16973,10 +16967,8 @@ "id": "def-server.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -20951,10 +20943,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -25352,7 +25340,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25394,10 +25382,8 @@ "id": "def-common.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -25461,7 +25447,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25503,10 +25489,8 @@ "id": "def-common.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -28342,7 +28326,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -28358,7 +28342,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index e102c339d573da..604c99e7e8a774 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index ce23f808c4b9ba..6e46268866697c 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 5ecdb2c2554a4a..9806722c487869 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index d8be969b12b09d..1f9bc9babfa75a 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-04 +date: 2023-07-05 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 937820ce7b3329..b9fa2718553caf 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-04 +date: 2023-07-05 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 b01a33cf59a807..4d03b9127920be 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index c88fad679a3bb5..96ce68eb2e53c1 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -111,10 +111,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -4926,7 +4922,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -4968,10 +4964,8 @@ "id": "def-public.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -5035,7 +5029,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -5077,10 +5071,8 @@ "id": "def-public.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -7804,7 +7796,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -7879,6 +7871,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-public.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -8420,10 +8426,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -12276,7 +12278,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -12318,10 +12320,8 @@ "id": "def-server.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -12385,7 +12385,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -12427,10 +12427,8 @@ "id": "def-server.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -13877,7 +13875,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -13952,6 +13950,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-server.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -15784,10 +15796,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -20304,7 +20312,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -20346,10 +20354,8 @@ "id": "def-common.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -20413,7 +20419,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -20455,10 +20461,8 @@ "id": "def-common.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -22201,7 +22205,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean | undefined, displayErrors?: boolean | undefined) => Promise<", + ", overwrite?: boolean | undefined, displayErrors?: boolean | undefined) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -22241,10 +22245,8 @@ "id": "def-common.DataViewsServicePublicMethods.createSavedObject.$2", "type": "CompoundType", "tags": [], - "label": "override", - "description": [ - "- If true, save over existing data view" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean | undefined" ], @@ -25117,7 +25119,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -25192,6 +25194,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -25877,7 +25893,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25893,7 +25909,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index c1758ac2dd8050..eaa8b1d45813e0 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1048 | 0 | 258 | 2 | +| 1051 | 0 | 268 | 2 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index e5645a3a53631d..80d4eef21696b0 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 06e28d8a7044ca..1308d5a4c7eca4 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 1b374e702fef3b..9b3c748b492419 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1141,12 +1141,12 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion)+ 12 more | - | | | [dependencies_start_mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts#:~:text=indexPatterns) | - | | | [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion)+ 78 more | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 24 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 22 more | - | | | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.ts#:~:text=create) | - | | | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch) | - | | | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/eql/api.ts#:~:text=options) | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 24 more | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 7 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 22 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 6 more | - | | | [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 | | | [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) | 8.8.0 | @@ -1219,7 +1219,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [message_utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/tls_rule/message_utils.ts#:~:text=alertFactory), [common.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/common.ts#:~:text=alertFactory), [tls_rule.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule.ts#:~:text=alertFactory), [monitor_status_rule.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts#:~:text=alertFactory) | - | | | [stderr_logs.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/stderr_logs.tsx#:~:text=indexPatternId) | - | | | [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks) | - | -| | [actions.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts#:~:text=SavedObject), [actions.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts#:~:text=SavedObject), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject)+ 1 more | - | +| | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 4bcdd17947c739..dcd422b44a67fe 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 52b9af51f2c7b2..1290792db63e65 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-04 +date: 2023-07-05 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 418852fb9f6533..894901004224e8 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-04 +date: 2023-07-05 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 e2972d0dfd69aa..545838989fcef6 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-04 +date: 2023-07-05 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 c7bac8be8e9b6a..456815253add33 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ff9c75066c3b26..3c60597cb2aa2b 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-04 +date: 2023-07-05 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 ddce516c012ff4..3edd67dc167ff9 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-04 +date: 2023-07-05 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 b30797a3f95f06..ab3b8aef1a4aa1 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-04 +date: 2023-07-05 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 7572712578fac8..99cf9558d581df 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-04 +date: 2023-07-05 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 1585b322a90b5d..3ce1723b5ef7df 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 6eb352855c17e2..34a28e08b34e89 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index ebcaea8eb22de8..44608654af5f95 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 44e2bd875b10fb..e194316b7cea7f 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-04 +date: 2023-07-05 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 7bc6143ad981f4..3f0fc93227986e 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-04 +date: 2023-07-05 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 a7de02f274013b..6f91122bf39728 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-04 +date: 2023-07-05 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 cc271283bf0984..8f1352f3dd4372 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-04 +date: 2023-07-05 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 9f75050ead27a9..1b2d4b7cd79326 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-04 +date: 2023-07-05 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 6028515124c6fa..7a430e93b5ca03 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-04 +date: 2023-07-05 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 15a537e2d51f6e..06598f58ad8c50 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-04 +date: 2023-07-05 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 270077e1f90a40..4b1bb925243c7c 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-04 +date: 2023-07-05 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 c9c25bfb55849e..9cf2c80067ba26 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-04 +date: 2023-07-05 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 8fc7a7e9ed4fa5..bb2f0bec92f7fc 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-04 +date: 2023-07-05 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 2d1a7bc8c5c67c..2a403a81ce8832 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-04 +date: 2023-07-05 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 3b8c50f4f716cd..78fc76e45c6d63 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-04 +date: 2023-07-05 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 7c787d2e5ffdb6..5780d1614c2065 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-04 +date: 2023-07-05 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 1ebeebd4806c9a..bf4a68d0decfb7 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-04 +date: 2023-07-05 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 9c29344ace5f46..8f8e4b5650720e 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-04 +date: 2023-07-05 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 70bb1c475558ba..2e145b784ee3a2 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-04 +date: 2023-07-05 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 324fcd2d3e1d89..a412b86858f8d3 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-04 +date: 2023-07-05 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 e629b0856dfdc6..064abd699fcc12 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-04 +date: 2023-07-05 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 e4a966fdb1ab75..49cd766fb154ca 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-04 +date: 2023-07-05 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 b098d802536707..a12f1527b7bd6e 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-04 +date: 2023-07-05 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 b5ed85ea0dcec3..caa3f6999359d0 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 809ab35271d07d..8208e3d11b0a1b 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-04 +date: 2023-07-05 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 fe8c108d89c198..453c2c521f93b6 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-04 +date: 2023-07-05 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 f54b3f1c9193f7..8ced8b4d94d656 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-04 +date: 2023-07-05 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 ae22c32d050c67..a26b1a8bfb7a36 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-04 +date: 2023-07-05 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 3fa952261dfced..7cfa3c26ffc0f8 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-04 +date: 2023-07-05 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 a34f0e49250b81..f18e468e26e83c 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 b312a6e5805457..9405afd666b00f 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 a5fa5320a15ad6..eb30834e29d5e7 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 3016167dbadc96..19168524c29ba3 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-04 +date: 2023-07-05 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 92db3f9f5a869d..67e1b7f02158f8 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-04 +date: 2023-07-05 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 4447e5cac6cdf8..45cf012204d6e1 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index c7881e6db0d4dc..c17512a5f0b68f 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-04 +date: 2023-07-05 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 892fe8b449a2b1..00832a2176ad9c 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 0383b8294e7412..81f5d6b6ecabe8 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 09c8ce2b54e616..af7edc0d8a4971 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 b1cc6337c8b886..55907ec366571c 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-04 +date: 2023-07-05 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 05db7cccba3ee5..7291da859af3a7 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-04 +date: 2023-07-05 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 eaa250a5ecc478..d4b446a4feb9f5 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 29edbaff662f9b..cd833eb9c0c7d9 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 a8b8deafa8651b..a80d36504c5f87 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-04 +date: 2023-07-05 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 1020205dc4822e..0a11917654e18a 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-04 +date: 2023-07-05 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 05c90d17d081d4..989a7c56c4e025 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 86a3dde84ae357..653fb639d51182 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index f7dc2dc3b5cd97..71f6d6887ca2fa 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-04 +date: 2023-07-05 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 ffd76f5befb0ad..90eeda70308da2 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-04 +date: 2023-07-05 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 4ff52a33cd1063..a061cd8d5b9508 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-04 +date: 2023-07-05 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 e0e3d648396ed8..7169cbfa902dc8 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 08eb9822b39929..0d4bd7daabd644 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 6af0298297db23..6aec3f4c21c565 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-04 +date: 2023-07-05 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 ee145317c7a156..39aa5e354040a4 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-04 +date: 2023-07-05 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 0e1ff6a18c03d4..845c13ed3d5fff 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-04 +date: 2023-07-05 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 09d08081ede2d3..922efdf36bebf3 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-04 +date: 2023-07-05 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 5a8b540b7afd0e..ccb99fbe2c75a0 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-04 +date: 2023-07-05 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 c0d60d4e438b3e..6080c4b1147682 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-04 +date: 2023-07-05 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 f5fec23312d66e..c410b8266abdb5 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-04 +date: 2023-07-05 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 be02de2cfa2b66..c6ad6c25c58995 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-04 +date: 2023-07-05 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 e2c1441169e548..94e1ccec124a04 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 7f96b467760a90..1215355cd87c76 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index e8a553cc9d3e83..3984da8b0fc33a 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-04 +date: 2023-07-05 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 dfb0fc4bea1af1..8a2db1c927fb4f 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-04 +date: 2023-07-05 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 5840134a950a8a..462dfab3c9a2c0 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 04a87e07837bf2..cdf1e277d3d404 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-04 +date: 2023-07-05 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 1b1f33770ba25b..70f1c79666d8fe 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-04 +date: 2023-07-05 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 f1cf58b40fe784..936c643770e70a 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-04 +date: 2023-07-05 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 6637ae18de157b..49f1f8754acaa2 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 86878d5639e57f..4f96ce3f3326d7 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-04 +date: 2023-07-05 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 830c118143e970..890c6416b94057 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 008651ac785257..6ceaee7d6b2ef5 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 e96413c1a76ee1..51c64ffe9dd2da 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 38c692ab092815..5bf8c63c71e011 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c38f0f22c5c57a..651a6e4da1abb3 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-04 +date: 2023-07-05 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 4646a442f6da23..5407846be8d2ea 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 09a807b53a682b..48a3087decd9f0 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 edc0fe763f88f1..eb2314d6744621 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 2cc6de17e6ab87..1c35027756a2fe 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 538e6d007d3613..b73ae9f06c7460 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 6043c0fc6355c3..2a67df9211aa27 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-04 +date: 2023-07-05 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 019640cbbcc4e4..d2a25f38fb4d27 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 cc2727a24e0ab2..2acbf08a4c62ed 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 8a63df9777762d..12041897dce027 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 e0903c7183424b..488c71d92b97da 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 d002fd41f7ec5f..064cec1a5eed83 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-04 +date: 2023-07-05 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 3de35a97b476ae..c583484c2cdf66 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 619ca6aeb9bc82..6f76e1d155eb86 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 b97664c086f8f2..c1f11e04df7a61 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 bb705fe5edb525..4191ddb733757c 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-04 +date: 2023-07-05 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 295e6df862d871..66f3a1bb801d3e 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-04 +date: 2023-07-05 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 e93d15505034b5..2d5e5ff1e96a46 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 cb9f0af5035f85..b3c10ca9a18b58 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 0009d47b8a4a58..644b075c9c3b39 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 59d0fa8660c8c6..d69c3b79267927 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 4fb5fd22aad52f..24372e4bbdbcd9 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 c45e9944816bba..2cb8f66c49c4cb 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 7b6f25d3a912a0..95e58fc0c97775 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 e972c6cf04c961..d3dbd54ad92795 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-04 +date: 2023-07-05 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 110cd4e3f07f6e..9b1e7a87459492 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-04 +date: 2023-07-05 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 6a268409b8b8ef..77edb606cd11ae 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 fff01280c1b7e0..0e196b2bd08ae5 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 1d2525ad461f4a..8d8feab21d9249 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 2c6f2cb0c9f056..2c6385fe8c91ec 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 2244941546c14e..1bd4110d334f0c 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 a62a6b4eab1c2b..2c427d5efea093 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-04 +date: 2023-07-05 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 e8a9f111eefc13..a1284fa96f99bb 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-04 +date: 2023-07-05 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 ef32238172fc39..be8722ffae792c 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 ce299f14629b85..f10a0ed1c2066b 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 1b51cdc26d7cc6..64c3a41cadc0fc 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 f14ea8fedf2e3b..bf5b7f4a564dba 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c68c1db4cd4d67..4221cacdfd20ca 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-04 +date: 2023-07-05 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 ab05459266b273..1c815d6ecedc10 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 acdad0a739f8fa..bb9f2e2927c078 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 9cc3421ef11d93..ec38221f328ead 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 24e834d41a22c5..11d66e6acf880c 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-04 +date: 2023-07-05 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 a64e41ba3731ef..7f8038073112bd 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 35f51d36937d6b..3d3459d0d270f9 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 06577c4bfedef3..de0ccf46b3def1 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 5b05d23cf4e75c..f11befc3b29558 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 611747b140e5a6..510a3c7ac009f4 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 54ca347bac7b25..e8532585f92b9e 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 61bd3b7cf44ca4..26435a1ad19132 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 680e61cedd9f9f..d89a5b6b082292 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-04 +date: 2023-07-05 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 744c2f429b0bc7..a5e9e261771f9e 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-04 +date: 2023-07-05 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 7f7f44f139808d..c05397383fd58c 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 c62e6d381bcf74..a55127e548af97 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 54d4aae2e008ec..c43348023f87c5 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 b37260cd832445..44dd7858a0f8c2 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 2865f4b8275ad6..36b96d513bc870 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 00847cf8ece377..925fbf6464446e 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 ea3dc9f8213d17..f615bcb7abdaaa 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 886e0eb03817b7..7da6ed3f8cbb96 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-04 +date: 2023-07-05 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 7c3941e3a4b955..ba262b7bb2b84f 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 72c13da6384d70..10f606bdfd3392 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-04 +date: 2023-07-05 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 d05e402eba6db5..22d4e70d3173ea 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-04 +date: 2023-07-05 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 59b93a42e3f51a..19ca707814d45d 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 185c261cb8f1a3..4c9af7f15ace0c 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 70cdc4c6b44af9..2ba02ad258c150 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 be0d486c3c14c8..ffa0dbee6531d2 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 b2eeca5f96d65c..0a7c4cebfbf5b4 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-04 +date: 2023-07-05 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 697be80a43bd1a..990cd120d005d2 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 91dab3c567922d..0a32bbd81f22eb 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 5e29c1c8d5d5c6..5d486e605e5d90 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 96f5bbfc54ed85..53c20794034312 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 6e11aee7bff50d..fd637cf169891e 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-04 +date: 2023-07-05 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 8bfa1abdea3cfb..663505c4f9d590 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 c3531b95057c4f..7e54e172794001 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 71b2a0188555ac..b61ff43c5b540f 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 1cda5852cfb3a4..9dc6a88194b85b 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 c948050d4aae75..58fb313d243e23 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 b7e43c6383f0ea..e903f08994dedd 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 1487d3a5b95c7e..fe7be83756d284 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 e3bbfe6ae80413..3addbfc94941f7 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-04 +date: 2023-07-05 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 764e031107a698..1e4aca3b887cf5 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 f3425b129afa09..eed6ea4e108d53 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 9d145940a1d4cf..63e02d42af553f 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 63cf0b9ae89e98..0eba98df374b58 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-04 +date: 2023-07-05 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 2d6c7ea659c6e2..4da2a009012cc9 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 47f3b699358690..1b2a36ee8af4c3 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 f097b5f4ae190d..12aa4833fa6829 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 92e83e107aa3cf..f0ddb326d4b899 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 d074354d8bfccc..5615047cd64a6f 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-04 +date: 2023-07-05 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 436361e3a98bab..0b0bb11d0bfc5f 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 6afd1424146c43..0d0f7a04f1de5c 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 ce03c4ed395ea4..5f038e86d92dc7 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 01213c660eb388..807bab424b2d7f 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-04 +date: 2023-07-05 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 21153e4c20214e..0049ea05bae51e 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 22032b4cf15e8d..ef0ed68bd35771 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 04543a86d0f185..29fff333349798 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 1e02cdc66bcb0a..35e8dc6b2ba2f7 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 cb6065df415aaa..f8a3e9a121e1f1 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 57d8eab0e24600..3f3fe477b5a010 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 cd77277ba20553..53dcf1ad9aac0b 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 e421f830fefc87..c6b969274388a7 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 00d6841616eaf5..516617eea96966 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 b72c13a2524dc3..12ee8f08e34118 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index a2e52feb035fda..576d45988c5039 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-04 +date: 2023-07-05 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 f20f940bcb4b30..cbae006cbe3f5e 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 bbce5ccf2f3960..347a157cd85ba8 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-04 +date: 2023-07-05 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 482591c15c5d57..2ed786d7e5d5d8 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 fce578a024807d..a91692e09d9fdd 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 ca72a5e33e755b..73bb0667dc436f 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 971e6c1d5ad5cd..6e914a5a786eb4 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 e0424e272d2236..93332ea1f401b5 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 3242bd32717d1c..0d5927b0ee0180 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 a56edb7348e00c..b83e74136bc2ed 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-04 +date: 2023-07-05 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 b0f0185d613a56..928b33d7d50e4f 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 46e56a4600a34f..d9fc5e6bbea9e4 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 c30924e5d49445..4902d8d31c73aa 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 ecee99ce6b8e66..bafd0df0fdce09 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 e7a62377c54902..92665b7bcb74c0 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 17d7b701c8ae6b..b01436ed5928aa 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.devdocs.json b/api_docs/kbn_core_saved_objects_common.devdocs.json index 7b4695420afa3b..fbc383d88c59c9 100644 --- a/api_docs/kbn_core_saved_objects_common.devdocs.json +++ b/api_docs/kbn_core_saved_objects_common.devdocs.json @@ -1489,34 +1489,6 @@ "plugin": "data", "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts" - }, { "plugin": "synthetics", "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts" diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index c24e300c7ae767..893ac783826392 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-04 +date: 2023-07-05 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 0d038a4d8c4a2b..ad40ac69d5eba6 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 4caf846a211cbe..0be9a0e8206d21 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 a3dae1157c7b6a..8371af4f13cd80 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 37a950cf4a1e68..663dc071f28f27 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 d3b76b217c0416..24e76ceb5f53a0 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-04 +date: 2023-07-05 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 7041c9e794c0b2..e945f00f884ae1 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 aafe67cbc77e32..168156da1ddb9c 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c961a02353ad9d..1c5232d33b2149 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-04 +date: 2023-07-05 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 3e982bcdcdfbc7..98b0249f8e054a 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-04 +date: 2023-07-05 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 3f9b8ea6277ca6..2dbdc902c77e2a 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 4ef72b8729839c..0650139c640af4 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-04 +date: 2023-07-05 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 b31a27d321c667..a1dccd271d397d 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 8846edb7c118fa..b0abaa8abedf42 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 85d8cad3d4b1e3..1940f37349838f 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-04 +date: 2023-07-05 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 7bd36413cff198..bd42702bb76176 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 5a10893b25f65a..475de1f36a366d 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index e1172bfcf5736d..4f91385037bca2 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-04 +date: 2023-07-05 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 932f78c36e2f5b..96534af7d163a0 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 9ce1c80941fc06..2f2122a4c41ccd 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 8fbb1d68a59d95..f3596e6c9b4429 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index d6270e822e583e..7a72019e2a24ca 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c6c9e9db5e2e80..9323f3c818db85 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 5e61152ee78c7f..8b3058b3c42b44 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 ed527423205b08..d39b2db40ed503 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 4f3505d61acb46..938efa0a423a70 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-04 +date: 2023-07-05 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 4901fa31e1eef0..416334f6351b9f 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-04 +date: 2023-07-05 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 0261a6753fd871..2283b43fc865bb 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 59aad9446a7855..f6852008c99969 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c9eff7e0783263..b6967380d88209 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-04 +date: 2023-07-05 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 290460ff397721..bd939750029ced 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 ef72203c9a2492..f9412de052cf49 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 eab0737161af4b..a3cd79cb0f2a2d 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-04 +date: 2023-07-05 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 5bd975ff079a06..193e7472a60220 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 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 a9c9b44293c5b5..657bd8444eef1d 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 df2549a2dbd250..8116a3f0da0fff 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-04 +date: 2023-07-05 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 ca331bc0f110fa..50c1bc8a38b2e8 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index cd7a2d468959a4..b4e7d659b4b7f6 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index e0432f0678d1d4..ccf31fc5b622f9 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 367754dce9395a..631882a8f5a2bf 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-04 +date: 2023-07-05 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 3080e419eacc59..6431eb586768a7 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-04 +date: 2023-07-05 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 68575f9ab12326..a0f5ab936f828c 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-04 +date: 2023-07-05 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 074598f2cea122..cf43a8b6cdd8c6 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-04 +date: 2023-07-05 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 0c09bc615d5076..0517bf418e8995 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-04 +date: 2023-07-05 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 fc254f18c31215..3e428f46cae500 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-04 +date: 2023-07-05 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 b74ffd6153fd1e..edb11e1ef6bbdc 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-04 +date: 2023-07-05 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 b8dd1b16c1afec..81d527ce013727 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-04 +date: 2023-07-05 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 ae70bde03b62e3..d1c9856de5f31c 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-04 +date: 2023-07-05 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 e24b1368c737ca..a65dba1592e6a6 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-04 +date: 2023-07-05 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 8a8b442215eb1d..c4f24d090c74d9 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-04 +date: 2023-07-05 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 2f3ae44f970cc1..1510d767c6bf87 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-04 +date: 2023-07-05 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 6636b5c1150fbe..d28350f75cb2f4 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-04 +date: 2023-07-05 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 36f13e19990f54..1bf6c89dfe937d 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-04 +date: 2023-07-05 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 d27aaf7f123775..c95a7feb12ecc2 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 85fbfcea2892d5..33436d8bacdca5 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -658,7 +658,7 @@ "label": "observability", "description": [], "signature": [ - "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly threshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; readonly syntheticsCommandReference: string; readonly syntheticsProjectMonitors: string; readonly syntheticsMigrateFromIntegration: string; }" + "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly threshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; readonly syntheticsCommandReference: string; readonly syntheticsProjectMonitors: string; readonly syntheticsMigrateFromIntegration: string; readonly sloBurnRateRule: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index f8bb2a0756f610..ae81cabcc0fd80 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-04 +date: 2023-07-05 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 9ee7f091de121b..d72e51b1ab0385 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 525fe1ea499488..2a2740d570c364 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-04 +date: 2023-07-05 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 a1badcff4047a3..1c352448344112 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-04 +date: 2023-07-05 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 9a21b359569416..0f8efd19b9a295 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-04 +date: 2023-07-05 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 1380a5ce236068..12b55452a37989 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index fe13918be2778d..d7aa33323d970a 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 4c00487d2c921f..f817ec0859dc1a 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-04 +date: 2023-07-05 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 e130b85df50f81..d5c755b334ed84 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-04 +date: 2023-07-05 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 37ed6764d9d110..5718752bd3dd4e 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-04 +date: 2023-07-05 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 8cc7f32862d753..d59bb5ddd951de 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-04 +date: 2023-07-05 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 9993297aecd478..2081f038f43e49 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-04 +date: 2023-07-05 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 c6221cdd52fd8f..fccc76a9972c2b 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 13039abc93aeef..5e87a772ddaa4e 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-04 +date: 2023-07-05 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 a780a047abf91a..c76e5be48d94d3 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index a3ec886292f862..cc927d2563282c 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-04 +date: 2023-07-05 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 4cd3a8ffd83214..64285e4ea52d33 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 460933a2bda731..2a4252112f6a72 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-04 +date: 2023-07-05 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 1f0558a5682813..d450935d31331f 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-04 +date: 2023-07-05 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 93c368ed8344d9..bf78b04382785c 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 19055b5175f5be..0c18490fc9c0a7 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 6962f103e5e3a1..df7d4da812877f 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-04 +date: 2023-07-05 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 ca311d4625ffc8..76e2fcedb8f6bb 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-04 +date: 2023-07-05 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 980f8dae553bb1..707eb01fdfdd96 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 0995e7249e78aa..41f99fbe22ff62 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-04 +date: 2023-07-05 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 c70a2b6524a908..12b114d11419dc 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-04 +date: 2023-07-05 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 35ddd71105f386..40954ee038b464 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-04 +date: 2023-07-05 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 581a1ee645ad70..1e046a3e074ee3 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-04 +date: 2023-07-05 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 1d7212b47abc29..a09a6acb7966af 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-04 +date: 2023-07-05 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 9992c13c43ead5..3aa45aea29ce66 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-04 +date: 2023-07-05 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 87b444509c4857..69afe9c8be9d7f 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-04 +date: 2023-07-05 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 3c57cadc78fe70..3148ef143f5006 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-04 +date: 2023-07-05 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 f85b14c96f908a..2522ef44849347 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 3a09e78df1cbfe..fc145dbadb6c10 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-04 +date: 2023-07-05 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 689b4dcace1963..875b50dca5058d 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-04 +date: 2023-07-05 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 03cfccc40e4ef7..2882e4a85d6461 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-04 +date: 2023-07-05 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 5f8335522f806b..7e3446d54e9505 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-04 +date: 2023-07-05 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 24e0a861e8aea9..f0b0dee2e59a11 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index bd1a52c6f2b565..d8656d2c7b08ed 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-04 +date: 2023-07-05 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 ab60eff2f410e0..b874ca581b2ed3 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index f858ddf4a4fe8b..6427e57a560908 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-04 +date: 2023-07-05 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 e6575c26fe7ddf..4801a3d431dd76 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 25143b05f015d0..b36c548b3a256b 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 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 b431413f651d2e..1acfc03f758ed8 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-04 +date: 2023-07-05 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 c2964e6dd24df4..97ce255d43aff6 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 998583b2ee74ca..4b86e5a5d91da6 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 681d57a9343f91..81b7732d7d54dd 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 5028d47a4a19ae..67e7bebfd62cee 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 ee8cc92bd5d331..eb2bda204fb60d 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-04 +date: 2023-07-05 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 eeb84e42534a40..06cc579d58af8f 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-04 +date: 2023-07-05 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 4da916714865da..c79d46c85e15c0 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 855a5375ffb9dd..83f67640a203ff 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 72e71f0f709969..8a7723e9f4b526 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-04 +date: 2023-07-05 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 805fff1032625c..32266a258893e0 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-04 +date: 2023-07-05 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 02574a65870d16..902e61e596883f 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-04 +date: 2023-07-05 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 10d1a665a71ac7..d83547a5193d64 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-04 +date: 2023-07-05 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 55c743966dff97..c0bc51865d04d6 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-04 +date: 2023-07-05 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 aded4faf4a8d22..9bae59a6eacf9a 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 7174d6886a240a..2b05f974f82971 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 c1a1e0e7e81769..2f37f244dacfd1 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 d278a62e866909..f4cffc65523772 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 d5d4f8d961ad4f..deb6851a6694d4 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 ae87a6216452b0..53c42072a23a09 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-04 +date: 2023-07-05 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 a8ed779b2ecbc5..667e781b31b2c1 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 621b0bfebb6a99..81b827e7d47b9f 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 1e0d3e09b97a0e..b677020dbfd906 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-04 +date: 2023-07-05 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 c48dbe35421137..4c8b8c779ad233 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-04 +date: 2023-07-05 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 dda91509afd319..724aeb08bced6b 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 6722f507bb655a..fe46d23c82bf04 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-04 +date: 2023-07-05 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 c1489e0cc7527f..0ee301007ce39d 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-04 +date: 2023-07-05 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 b2f7f21f2f32bd..3de2f47c2a484e 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 9dfba7cb472a7c..c0a39fff7e0d90 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index d3f5e78d048a1f..35dadb27af4534 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-04 +date: 2023-07-05 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 5c0f830b0546c3..f825c8a465ca3c 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index fb47d883a1cce9..b5fbc1b7c5f3fc 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-04 +date: 2023-07-05 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 acced4c06f26ae..0b08ea73639673 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 96e1bdc0aa3af2..554d4dcb5af849 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-04 +date: 2023-07-05 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 46dad8550374e5..955ef83ff1cdc6 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-04 +date: 2023-07-05 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 ed5855fa5b5c79..2c9945dbba7301 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-04 +date: 2023-07-05 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 87cc3d28fa85d0..550a8eaf50a670 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-04 +date: 2023-07-05 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 3a09f1e40d2a31..43c1420846cef6 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 124a5c2af1f1a0..e259a39092f0c7 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index d64728cc9b7743..6d36cbbebda1ef 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-04 +date: 2023-07-05 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 62d73252b3566d..156c11bb3eb1eb 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 b64ddbbe16878a..fea62bc327b5f5 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 169d5449fb4f8f..04021ce24ff92f 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-04 +date: 2023-07-05 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 952785cc2c82bc..00ca6215b56974 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 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 c486fcc009901c..1ed0c4cc1bb23a 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-04 +date: 2023-07-05 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 1f971f26a38b1f..474af441e362e5 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-04 +date: 2023-07-05 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 eb8c16f7f01892..b0054b96656bec 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-04 +date: 2023-07-05 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 a876fa751d1e32..062ff3f7fd3683 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 499d71419f5493..a43b54c7e8be62 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-04 +date: 2023-07-05 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 e3bb28518da107..765aca6e6ccb2e 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-04 +date: 2023-07-05 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 f0f7cdb095b8ba..01b91c96f5fb87 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 965e0e6582db44..c6930ecbabacab 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-04 +date: 2023-07-05 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 e420ba825040dd..a49d0cf0ea1817 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-04 +date: 2023-07-05 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 9b1257fc1aede7..cc151193b5f4d7 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-04 +date: 2023-07-05 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 1a37c07efd5778..f262893b0d38eb 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 3bf2b2919ac108..9734f0e0acad9d 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-04 +date: 2023-07-05 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 454b191ee9481d..4e736d97d39723 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-04 +date: 2023-07-05 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 edcdff4b435264..5dbb710e0fc0c5 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-04 +date: 2023-07-05 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 7cb9ee7927615d..64601b6d4c4c92 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 2af94107cbe1bc..6393c27aa5b16d 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-04 +date: 2023-07-05 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 ed5633cdb8ccc4..8ae592064a6ff0 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-04 +date: 2023-07-05 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 d69dccadae991c..25d56bed1306c3 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-04 +date: 2023-07-05 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 f8cca2f10e94b3..642c8490fc15bb 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-04 +date: 2023-07-05 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 8dcac28c3bccc6..09988c969aed25 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index c2ca97af14a74f..66f94916d82837 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 5f1c36c201878d..9ff861f91a90db 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 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 c66885af1fee0a..b30b411128fa2a 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-04 +date: 2023-07-05 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 320ec0d432116a..1c1210832eaa19 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 5b7045a8d9f67e..531bc47c943a87 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 062ba46d30075f..2c912c64b30cf4 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index a71ec43d86a100..3c07ddc4652cfa 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index f8a35e8e438bb1..bd70bd98c3692c 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-04 +date: 2023-07-05 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 aed464bdb5c766..706bac4f59acdb 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-04 +date: 2023-07-05 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 2e90743efdc207..02102583a77b0f 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 fceef20809889c..ac8e0150cad760 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 6d3a402bf7d5c2..8e3c4ff5c8ec35 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-04 +date: 2023-07-05 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 d65184508e8298..ea250c4c3a7fb8 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-04 +date: 2023-07-05 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 6336eb2c934832..07b09f5f34f91a 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 de2e8566a93b2e..1d51faf21ef344 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 0711650d3ce910..b263a80e5f5d0c 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-04 +date: 2023-07-05 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 cb38e442dde465..03137d11e02743 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-04 +date: 2023-07-05 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 9e0a8eceb50476..3d18c0daf54619 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-04 +date: 2023-07-05 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 b97db006473182..6b4a7568839ba3 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-04 +date: 2023-07-05 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 9b3c6030a21c76..b255f6230f7878 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-04 +date: 2023-07-05 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 0de696514c58ca..27f167249ea838 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 8c9583a40f46c0..bc4473a08f23f9 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-04 +date: 2023-07-05 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 99b7dbc36a0691..886cb45856c00a 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 cefe9776163d16..811fc7c95e6899 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-04 +date: 2023-07-05 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 158776fd378f5a..3b0e8c63569a61 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 c736fbcbb0e4a9..fd74062daae013 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-04 +date: 2023-07-05 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 0e76431df5ff9f..91379e848e63e8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 b7e573b04a18bb..59ef177721ddff 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-04 +date: 2023-07-05 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 6e0970a5b0986e..0835f6dab888cf 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 24c3e122857c89..63b6cc21a36f85 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-04 +date: 2023-07-05 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 f024d4dc85e0bc..c7255c20774996 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-04 +date: 2023-07-05 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 6724eb0caa46b3..e218153d7da315 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 8bd4211647a70b..1a536d33157035 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 eb04cd0d0e7f9c..3e70d4567cc792 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-04 +date: 2023-07-05 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 fbb6a42471c952..8a598bc22cf94b 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-04 +date: 2023-07-05 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 6694f28ec422b2..75b73b8a877b32 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 758b8583895363..8c72280b0a6d1f 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-04 +date: 2023-07-05 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 1a564ec4b5f56a..987c7d0586ca7b 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-04 +date: 2023-07-05 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 792465bfb77348..c8b99990edbe98 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-04 +date: 2023-07-05 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 658b9eaec33b3d..e4fbe5a4291adc 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 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 aa88d77fe73888..ed436ac1cd0f06 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-04 +date: 2023-07-05 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 5d0d84ee986631..e106b8562a6019 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-04 +date: 2023-07-05 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 8f9700fc1cc019..ae23535f6b45f0 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-04 +date: 2023-07-05 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 44039e8d97ff6f..67ff55eefa97d0 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 84ffa7a7b6cc71..048c6f24c03b6e 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-04 +date: 2023-07-05 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 49574d65569d35..434f426e02a469 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-04 +date: 2023-07-05 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 867a30b1fde6db..024c14d8b5033e 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-04 +date: 2023-07-05 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 847ce7296955cc..6db2677eba7aec 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-04 +date: 2023-07-05 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 de2b67b4228fec..eb3509a798cda6 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index e4ab96c56f975e..1009301eb174f7 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-04 +date: 2023-07-05 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 7e1e26e6cdfff9..39bf68611d8d25 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-04 +date: 2023-07-05 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 246752490577ad..8923c6e8831e69 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-04 +date: 2023-07-05 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 8d47a3e0cf55a1..22cb1362d684ae 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 4794a40ac7e2c7..e4af602a22d078 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-04 +date: 2023-07-05 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 cc6b8a96809070..12fc03dc73aaaf 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-04 +date: 2023-07-05 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 dc397f344d19e2..21132d0b49effe 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-04 +date: 2023-07-05 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 26094e3a601e99..4b91f5241febde 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-04 +date: 2023-07-05 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 34523e2dff591b..4f49eeac558e5c 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index cd932d9d6849e2..60361fd6e2243d 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 29541b076aea1f..3828f42063e9d8 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index f09da062ff82e9..6439073eac9011 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-04 +date: 2023-07-05 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 bf4ca46684de00..ad7fcc1d9a86ec 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-04 +date: 2023-07-05 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 d23d2f88684eb6..1d3ad06f90eeca 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-04 +date: 2023-07-05 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 e6b5c16156af8b..8d09226d8cde8c 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index c465ac339244b2..085cecb17cd011 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 4164af8d68a6bb..6940bb92bfde05 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-04 +date: 2023-07-05 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 a470737c641856..88e2b49ec80e67 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-04 +date: 2023-07-05 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 f140aac1e0ac7f..fc785b8740ab7b 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-04 +date: 2023-07-05 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 b429f306614848..86f3e74f10c560 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-04 +date: 2023-07-05 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 374bac01d12b7d..67b3a0c09834d4 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-04 +date: 2023-07-05 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 6083771d6cefea..418c7d64716340 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-04 +date: 2023-07-05 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 23419ef04718ad..f78f30f5ea87ab 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 9cae783d8749ca..57ed54ac6f483e 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 38ce8789989f10..05c5960070511c 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.devdocs.json b/api_docs/management.devdocs.json index 6e970de9f2c57b..61f282b25ee2cf 100644 --- a/api_docs/management.devdocs.json +++ b/api_docs/management.devdocs.json @@ -805,6 +805,38 @@ ], "returnComment": [] }, + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setLandingPageRedirect", + "type": "Function", + "tags": [], + "label": "setLandingPageRedirect", + "description": [], + "signature": [ + "(landingPageRedirect: string) => void" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setLandingPageRedirect.$1", + "type": "string", + "tags": [], + "label": "landingPageRedirect", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "management", "id": "def-public.ManagementStart.setupCardsNavigation", diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 68bfbf4918408f..b7d9c0485d9604 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './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 | |-------------------|-----------|------------------------|-----------------| -| 45 | 0 | 45 | 7 | +| 47 | 0 | 47 | 7 | ## Client diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 6a1ed8133255c9..dbc775b5f1dbc3 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-04 +date: 2023-07-05 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 299ade9e71af26..b5d807b56d5a4a 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 16e46d18ead560..f58609b971172f 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 4133dfde906efe..41e3baa9bd4140 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-04 +date: 2023-07-05 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 97288b7b95e6d7..bd1a9da9085005 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-04 +date: 2023-07-05 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 530ffc11c7b280..10e65aecf96a6d 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-04 +date: 2023-07-05 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 31f20cff3b9e47..a6c451b4834975 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 53f267fa0477e4..88f460f7ef2740 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-04 +date: 2023-07-05 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 62e58fc3dc2cd6..71425278a3406b 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index e7f3a62632dfaa..2ccee1c31e89c9 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-04 +date: 2023-07-05 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 ae30125da3bbd5..0c300be82aaf02 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-04 +date: 2023-07-05 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 4bdeb7094a5e8c..49af78d45b3570 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index aeab64a07c161d..a847b1da1639fb 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70982 | 544 | 60792 | 1409 | +| 70987 | 544 | 60808 | 1409 | ## Plugin Directory @@ -56,11 +56,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 271 | 0 | 252 | 1 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 100 | 0 | 98 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 54 | 0 | 51 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3303 | 119 | 2579 | 27 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3303 | 119 | 2583 | 27 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 16 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Reusable data view field editor across Kibana | 72 | 0 | 33 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1048 | 0 | 258 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1051 | 0 | 268 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 10 | 0 | 8 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 97 | 0 | 71 | 14 | @@ -123,7 +123,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 210 | 0 | 94 | 51 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 47 | 0 | 47 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 266 | 0 | 265 | 28 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 32 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 45a4cedff2e771..c03517c32181d2 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-04 +date: 2023-07-05 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 44ddb29e58bb11..d38e2391829110 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 8151486dacb731..0dbe8450665c21 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-04 +date: 2023-07-05 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 462db023b77c87..66305771e23fc3 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 8c2c6bb90afea8..6ec11afb27a394 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index ec70b4249c6d37..6df07194789494 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-04 +date: 2023-07-05 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 ec82ecc994b0a1..01fee08efd10a6 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-04 +date: 2023-07-05 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 6de928bdb20374..ff1c503e48f9c4 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-04 +date: 2023-07-05 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 7c1875319e7390..6bf8190ccf2a39 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-04 +date: 2023-07-05 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 075b7695f7562e..773ef8d73391c5 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-04 +date: 2023-07-05 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 b67fe7179270e0..0cbb23923e783f 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-04 +date: 2023-07-05 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 7a4501f01b6ba9..90d1b3092d0570 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-04 +date: 2023-07-05 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 f3f2361a11ecef..922893523ded1f 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-04 +date: 2023-07-05 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 a62e45f86b8880..7dd50c518a8ba4 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-04 +date: 2023-07-05 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 494e76c3cf65ed..7507e2a9f95ddb 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-04 +date: 2023-07-05 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 1368ee6cbb76d1..e74025234fa808 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-04 +date: 2023-07-05 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 c1d5c218edbf2b..5057f57deedeea 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-04 +date: 2023-07-05 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 7e53e37b906f84..f49c4e732e19a3 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 41752046e3e9cb..b378e96dd1769d 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-04 +date: 2023-07-05 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 a598a191324439..086f5ddd62ae3d 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-04 +date: 2023-07-05 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 a9e04358d9ee4c..0e2906e0c48f7d 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index 1d9f4d95772716..d3f04f77aa7898 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index d8872d809c0410..9996b614d4f55a 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-04 +date: 2023-07-05 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 e5a6e44040e8f1..6fee690d24ee73 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-04 +date: 2023-07-05 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 961944a41153d6..b6414973bfac45 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-04 +date: 2023-07-05 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 4f3d26414eeab0..69d2bb90c629a9 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-04 +date: 2023-07-05 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 c19398e23ad5e2..3c4331805d1bc2 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-04 +date: 2023-07-05 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 51df18fc67a84f..ee04c17c8a08c7 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-04 +date: 2023-07-05 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 4768f6de5c0ef2..5cb5c232a8c2e2 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-04 +date: 2023-07-05 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 3f755385b93f64..46d841e2ff7f10 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-04 +date: 2023-07-05 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 462e3f94420701..bfd9aa4afee778 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-04 +date: 2023-07-05 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 091a41712240d1..e4b7f79a9375e1 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-04 +date: 2023-07-05 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 b2382d3b1b3748..5c2e12eebba7a5 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-04 +date: 2023-07-05 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 fe1ce3fbd05763..5888c1b29a8893 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-04 +date: 2023-07-05 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 bdacfa3854af80..007d55d57e774f 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-04 +date: 2023-07-05 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 4ce06eb6edb6c2..41fa43757d3848 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-04 +date: 2023-07-05 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 50af3624ae3d87..d913ae767c5514 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-04 +date: 2023-07-05 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 5ddab506cf1ed0..04571ec89b6748 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-04 +date: 2023-07-05 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 01839cd14fff61..1187fdb94ea9a8 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-04 +date: 2023-07-05 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 15f1205fe4731a..cd1ab232e8d84e 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 97d02724e627da..0197cf908f0e4e 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-04 +date: 2023-07-05 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 93fc2b40d9f5c8..9a44bd9bc3470e 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-04 +date: 2023-07-05 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 e9a3fe63e40f59..229cf508069708 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 8d01c6f9a2659b..c5232b0b57c257 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-04 +date: 2023-07-05 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 75e9132aae821b..1a6e7e8e985ee7 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-04 +date: 2023-07-05 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 ae8e52c16d8980..3c3b9dd888195e 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-04 +date: 2023-07-05 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 a9a0ab3cf7a196..bc101a54eee9cc 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-04 +date: 2023-07-05 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 453adeccb22d72..9b98623cf9ef67 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-04 +date: 2023-07-05 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 788974c703c980..7be1137b655315 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-04 +date: 2023-07-05 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 156f48abffdbdd..d624890761b2ae 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-04 +date: 2023-07-05 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 ab0cfaedd26d55..82fee9fc02d9e1 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-04 +date: 2023-07-05 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 27d898573845b7..a70dbf66e069dd 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-04 +date: 2023-07-05 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 bfc80aa1193e36..fcdf5f386295dc 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-04 +date: 2023-07-05 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 d5c328ee070e7b..bb7b848848e3f7 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-04 +date: 2023-07-05 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 dca311a74be707..b8397b606fbad3 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-04 +date: 2023-07-05 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 49b2ee08dababb..e62c03def083cc 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 66ffdc6dac8dad..e513affacd64f8 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 3b8f2591a11f08..6d60a643b0492f 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From d79e69a1ed944bc047eee56909891732efdffe38 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 5 Jul 2023 08:52:24 +0200 Subject: [PATCH 68/98] [Infrastructure UI] Add strict payload validation to inventory_views endpoint (#160852) closes [#157505](https://github.com/elastic/kibana/issues/157505) fixes [#157740](https://github.com/elastic/kibana/issues/157740) ## Summary This PR adds strict payload validation to `inventory_views` endpoint. I tried to make the types consistent between sever and frontend code and because of that more changes had to be made. I also refactored the `toolbar_control` component, decoupling them from Inventory View and Metrics Explorer View types ### How to test - Call the endpoint below trying to use invalid values. see [here](https://github.com/elastic/kibana/pull/160852/files#diff-058b21e249ebbe2795d450d07025d8904a58cfb07a97979e85975f87e931ffceR133-R143). ```bash [POST|PUT] kbn:/api/infra/inventory_views { "attributes": { "metric": { "type": [TYPE] }, "sort": { "by": "name" "direction": "desc" }, "groupBy": [], "nodeType": "host", "view": "map", "customOptions": [], "customMetrics": [], "boundsOverride": { "max": 1, "min": 0 }, "autoBounds": true, "accountId": "", "region": "", "autoReload": false, "filterQuery": { "expression": "", "kind": "kuery" }, "legend": { "palette": "cool", "steps": 10, "reverseColors": false }, "timelineOpen": false, "name": "test-uptime" } } ``` - Set up a local Kibana instance - Navigate to `Infrastructure` - In the UI, use the Saved View feature and try different field combinations --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../kbn-io-ts-utils/src/in_range_rt/index.ts | 14 ++- .../http_api/inventory_views/v1/common.ts | 31 +---- .../v1/create_inventory_view.ts | 20 ++-- .../inventory_views/v1/find_inventory_view.ts | 25 +--- .../inventory_views/v1/get_inventory_view.ts | 3 + .../v1/update_inventory_view.ts | 20 ++-- .../infra/common/inventory_views/types.ts | 107 ++++++++++++++++-- .../common/metrics_explorer_views/types.ts | 2 +- .../plugins/infra/common/saved_views/index.ts | 8 ++ .../plugins/infra/common/saved_views/types.ts | 70 ++++++++++++ .../saved_views/manage_views_flyout.tsx | 35 +++--- .../saved_views/toolbar_control.tsx | 43 ++++--- .../infra/public/hooks/use_inventory_views.ts | 73 ++++-------- .../hooks/use_metrics_explorer_views.ts | 73 ++++-------- x-pack/plugins/infra/public/lib/lib.ts | 14 +-- .../inventory_view/components/saved_views.tsx | 4 +- .../components/waffle/legend_controls.tsx | 8 +- .../components/waffle/palette_preview.tsx | 2 +- .../hooks/use_waffle_filters.ts | 29 ++--- .../hooks/use_waffle_options.ts | 68 +++-------- .../hooks/use_waffle_view_state.ts | 26 ++--- .../inventory_view/lib/create_legend.ts | 5 +- .../components/saved_views.tsx | 2 +- .../inventory_views/inventory_views_client.ts | 13 ++- .../public/services/inventory_views/types.ts | 13 ++- .../server/routes/inventory_views/README.md | 48 +++++++- .../saved_objects/inventory_view/types.ts | 70 +++++++++++- .../inventory_views/inventory_views_client.ts | 9 +- .../test/functional/apps/infra/home_page.ts | 2 - .../page_objects/infra_saved_views.ts | 5 +- 30 files changed, 497 insertions(+), 345 deletions(-) create mode 100644 x-pack/plugins/infra/common/saved_views/index.ts create mode 100644 x-pack/plugins/infra/common/saved_views/types.ts diff --git a/packages/kbn-io-ts-utils/src/in_range_rt/index.ts b/packages/kbn-io-ts-utils/src/in_range_rt/index.ts index b632173cb69d93..99d04b3f6abc66 100644 --- a/packages/kbn-io-ts-utils/src/in_range_rt/index.ts +++ b/packages/kbn-io-ts-utils/src/in_range_rt/index.ts @@ -16,11 +16,15 @@ export interface InRangeBrand { export type InRange = rt.Branded; export const inRangeRt = (start: number, end: number) => - rt.brand( - rt.number, // codec - (n): n is InRange => n >= start && n <= end, - // refinement of the number type - 'InRange' // name of this codec + new rt.Type( + 'InRange', + (input: unknown): input is number => + typeof input === 'number' && input >= start && input <= end, + (input: unknown, context: rt.Context) => + typeof input === 'number' && input >= start && input <= end + ? rt.success(input) + : rt.failure(input, context), + rt.identity ); export const inRangeFromStringRt = (start: number, end: number) => { diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts index 65e056f30e0d9b..f1eb9b24ee0393 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; + import * as rt from 'io-ts'; import { either } from 'fp-ts/Either'; +import { inventoryViewRT } from '../../../inventory_views'; export const INVENTORY_VIEW_URL = '/api/infra/inventory_views'; export const INVENTORY_VIEW_URL_ENTITY = `${INVENTORY_VIEW_URL}/{inventoryViewId}`; @@ -33,30 +34,8 @@ export const inventoryViewRequestQueryRT = rt.partial({ sourceId: rt.string, }); -export type InventoryViewRequestQuery = rt.TypeOf; - -const inventoryViewAttributesResponseRT = rt.intersection([ - rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, - }), - rt.UnknownRecord, -]); - -const inventoryViewResponseRT = rt.exact( - rt.intersection([ - rt.type({ - id: rt.string, - attributes: inventoryViewAttributesResponseRT, - }), - rt.partial({ - updatedAt: rt.number, - version: rt.string, - }), - ]) -); - export const inventoryViewResponsePayloadRT = rt.type({ - data: inventoryViewResponseRT, + data: inventoryViewRT, }); + +export type InventoryViewRequestQuery = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts index 8bad088b005421..67a3bd7df1a702 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts @@ -5,16 +5,18 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { inventoryViewAttributesRT, inventoryViewRT } from '../../../inventory_views'; -export const createInventoryViewAttributesRequestPayloadRT = rt.intersection([ - rt.type({ - name: nonEmptyStringRt, - }), - rt.UnknownRecord, - rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), -]); +export const createInventoryViewAttributesRequestPayloadRT = rt.exact( + rt.intersection([ + inventoryViewAttributesRT, + rt.partial({ + isDefault: rt.undefined, + isStatic: rt.undefined, + }), + ]) +); export type CreateInventoryViewAttributesRequestPayload = rt.TypeOf< typeof createInventoryViewAttributesRequestPayloadRT @@ -23,3 +25,5 @@ export type CreateInventoryViewAttributesRequestPayload = rt.TypeOf< export const createInventoryViewRequestPayloadRT = rt.type({ attributes: createInventoryViewAttributesRequestPayloadRT, }); + +export type CreateInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts index 17a9820a93a4da..3452a22a45d175 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts @@ -5,28 +5,11 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; - -export const findInventoryViewAttributesResponseRT = rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, -}); - -const findInventoryViewResponseRT = rt.exact( - rt.intersection([ - rt.type({ - id: rt.string, - attributes: findInventoryViewAttributesResponseRT, - }), - rt.partial({ - updatedAt: rt.number, - version: rt.string, - }), - ]) -); +import { singleInventoryViewRT } from '../../../inventory_views'; export const findInventoryViewResponsePayloadRT = rt.type({ - data: rt.array(findInventoryViewResponseRT), + data: rt.array(singleInventoryViewRT), }); + +export type FindInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts index 8e5cef06bb9162..a13541c1e8a44b 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts @@ -6,7 +6,10 @@ */ import * as rt from 'io-ts'; +import { inventoryViewRT } from '../../../inventory_views'; export const getInventoryViewRequestParamsRT = rt.type({ inventoryViewId: rt.string, }); + +export type GetInventoryViewResposePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts index b21bafbecec18e..5698ab2a0b2c97 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts @@ -5,16 +5,18 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { inventoryViewAttributesRT, inventoryViewRT } from '../../../inventory_views'; -export const updateInventoryViewAttributesRequestPayloadRT = rt.intersection([ - rt.type({ - name: nonEmptyStringRt, - }), - rt.UnknownRecord, - rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), -]); +export const updateInventoryViewAttributesRequestPayloadRT = rt.exact( + rt.intersection([ + inventoryViewAttributesRT, + rt.partial({ + isDefault: rt.undefined, + isStatic: rt.undefined, + }), + ]) +); export type UpdateInventoryViewAttributesRequestPayload = rt.TypeOf< typeof updateInventoryViewAttributesRequestPayloadRT @@ -23,3 +25,5 @@ export type UpdateInventoryViewAttributesRequestPayload = rt.TypeOf< export const updateInventoryViewRequestPayloadRT = rt.type({ attributes: updateInventoryViewAttributesRequestPayloadRT, }); + +export type UpdateInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/inventory_views/types.ts b/x-pack/plugins/infra/common/inventory_views/types.ts index 49979c1063efa3..a493d2332f2123 100644 --- a/x-pack/plugins/infra/common/inventory_views/types.ts +++ b/x-pack/plugins/infra/common/inventory_views/types.ts @@ -5,19 +5,89 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; +import { isoToEpochRt, nonEmptyStringRt, inRangeRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { + SnapshotCustomMetricInputRT, + SnapshotGroupByRT, + SnapshotMetricInputRT, +} from '../http_api/snapshot_api'; +import { ItemTypeRT } from '../inventory_models/types'; + +export const inventoryColorPaletteRT = rt.keyof({ + status: null, + temperature: null, + cool: null, + warm: null, + positive: null, + negative: null, +}); + +const inventoryLegendOptionsRT = rt.type({ + palette: inventoryColorPaletteRT, + steps: inRangeRt(2, 18), + reverseColors: rt.boolean, +}); + +export const inventorySortOptionRT = rt.type({ + by: rt.keyof({ name: null, value: null }), + direction: rt.keyof({ asc: null, desc: null }), +}); + +export const inventoryViewOptionsRT = rt.keyof({ table: null, map: null }); + +export const inventoryMapBoundsRT = rt.type({ + min: inRangeRt(0, 1), + max: inRangeRt(0, 1), +}); + +export const inventoryFiltersStateRT = rt.type({ + kind: rt.literal('kuery'), + expression: rt.string, +}); + +export const inventoryOptionsStateRT = rt.intersection([ + rt.type({ + accountId: rt.string, + autoBounds: rt.boolean, + boundsOverride: inventoryMapBoundsRT, + customMetrics: rt.array(SnapshotCustomMetricInputRT), + customOptions: rt.array( + rt.type({ + text: rt.string, + field: rt.string, + }) + ), + groupBy: SnapshotGroupByRT, + metric: SnapshotMetricInputRT, + nodeType: ItemTypeRT, + region: rt.string, + sort: inventorySortOptionRT, + view: inventoryViewOptionsRT, + }), + rt.partial({ legend: inventoryLegendOptionsRT, source: rt.string, timelineOpen: rt.boolean }), +]); + +export const inventoryViewBasicAttributesRT = rt.type({ + name: nonEmptyStringRt, +}); + +const inventoryViewFlagsRT = rt.partial({ isDefault: rt.boolean, isStatic: rt.boolean }); export const inventoryViewAttributesRT = rt.intersection([ - rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, + inventoryOptionsStateRT, + inventoryViewBasicAttributesRT, + inventoryViewFlagsRT, + rt.type({ + autoReload: rt.boolean, + filterQuery: inventoryFiltersStateRT, }), - rt.UnknownRecord, + rt.partial({ time: rt.number }), ]); -export type InventoryViewAttributes = rt.TypeOf; +const singleInventoryViewAttributesRT = rt.exact( + rt.intersection([inventoryViewBasicAttributesRT, inventoryViewFlagsRT]) +); export const inventoryViewRT = rt.exact( rt.intersection([ @@ -26,10 +96,31 @@ export const inventoryViewRT = rt.exact( attributes: inventoryViewAttributesRT, }), rt.partial({ - updatedAt: rt.number, + updatedAt: isoToEpochRt, + version: rt.string, + }), + ]) +); + +export const singleInventoryViewRT = rt.exact( + rt.intersection([ + rt.type({ + id: rt.string, + attributes: singleInventoryViewAttributesRT, + }), + rt.partial({ + updatedAt: isoToEpochRt, version: rt.string, }), ]) ); +export type InventoryColorPalette = rt.TypeOf; +export type InventoryFiltersState = rt.TypeOf; +export type InventoryLegendOptions = rt.TypeOf; +export type InventoryMapBounds = rt.TypeOf; +export type InventoryOptionsState = rt.TypeOf; +export type InventorySortOption = rt.TypeOf; export type InventoryView = rt.TypeOf; +export type InventoryViewAttributes = rt.TypeOf; +export type InventoryViewOptions = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/metrics_explorer_views/types.ts b/x-pack/plugins/infra/common/metrics_explorer_views/types.ts index 47ecb06ceace56..0d0c2fa3166e0b 100644 --- a/x-pack/plugins/infra/common/metrics_explorer_views/types.ts +++ b/x-pack/plugins/infra/common/metrics_explorer_views/types.ts @@ -9,7 +9,7 @@ import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; export const metricsExplorerViewAttributesRT = rt.intersection([ - rt.strict({ + rt.type({ name: nonEmptyStringRt, isDefault: rt.boolean, isStatic: rt.boolean, diff --git a/x-pack/plugins/infra/common/saved_views/index.ts b/x-pack/plugins/infra/common/saved_views/index.ts new file mode 100644 index 00000000000000..6cc0ccaa93a6d1 --- /dev/null +++ b/x-pack/plugins/infra/common/saved_views/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 * from './types'; diff --git a/x-pack/plugins/infra/common/saved_views/types.ts b/x-pack/plugins/infra/common/saved_views/types.ts new file mode 100644 index 00000000000000..01bf806da44d99 --- /dev/null +++ b/x-pack/plugins/infra/common/saved_views/types.ts @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + QueryObserverBaseResult, + UseMutateAsyncFunction, + UseMutateFunction, +} from '@tanstack/react-query'; + +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; + +export type ServerError = IHttpFetchError; + +export interface SavedViewState { + views?: SavedViewItem[]; + currentView?: TView | null; + isCreatingView: boolean; + isFetchingCurrentView: boolean; + isFetchingViews: boolean; + isUpdatingView: boolean; +} + +export interface SavedViewOperations< + TView extends { id: TView['id'] }, + TId extends TView['id'] = TView['id'], + TPayload = any, + TConfig = any +> { + createView: UseMutateAsyncFunction; + deleteViewById: UseMutateFunction>; + fetchViews: QueryObserverBaseResult['refetch']; + updateViewById: UseMutateAsyncFunction>; + switchViewById: (id: TId) => void; + setDefaultViewById: UseMutateFunction>; +} + +export interface SavedViewResult< + TView extends { + id: TView['id']; + }, + TId extends string = '', + TPayload = any, + TConfig = any +> extends SavedViewState, + SavedViewOperations {} + +export interface UpdateViewParams { + id: string; + attributes: TRequestPayload; +} + +export interface MutationContext { + id?: string; + previousViews?: TView[]; +} + +export interface BasicAttributes { + name?: string; + time?: number; + isDefault?: boolean; + isStatic?: boolean; +} +export interface SavedViewItem { + id: string; + attributes: BasicAttributes; +} diff --git a/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx b/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx index e503bdebafa037..67235c96a8bccd 100644 --- a/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx +++ b/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx @@ -24,21 +24,15 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBasicTableColumn } from '@elastic/eui'; import { EuiButtonIcon } from '@elastic/eui'; -import { MetricsExplorerView } from '../../../common/metrics_explorer_views'; -import type { InventoryView } from '../../../common/inventory_views'; -import { UseInventoryViewsResult } from '../../hooks/use_inventory_views'; -import { UseMetricsExplorerViewsResult } from '../../hooks/use_metrics_explorer_views'; +import { SavedViewOperations, SavedViewItem } from '../../../common/saved_views'; -type View = InventoryView | MetricsExplorerView; -type UseViewResult = UseInventoryViewsResult | UseMetricsExplorerViewsResult; - -export interface ManageViewsFlyoutProps { - views: UseViewResult['views']; +export interface ManageViewsFlyoutProps { + views?: SavedViewItem[]; loading: boolean; onClose(): void; - onMakeDefaultView: UseViewResult['setDefaultViewById']; - onSwitchView: UseViewResult['switchViewById']; - onDeleteView: UseViewResult['deleteViewById']; + onMakeDefaultView: SavedViewOperations['setDefaultViewById']; + onSwitchView: SavedViewOperations['switchViewById']; + onDeleteView: SavedViewOperations['deleteViewById']; } interface DeleteConfimationProps { @@ -50,18 +44,18 @@ const searchConfig = { box: { incremental: true }, }; -export function ManageViewsFlyout({ +export function ManageViewsFlyout({ onClose, views = [], onSwitchView, onMakeDefaultView, onDeleteView, loading, -}: ManageViewsFlyoutProps) { +}: ManageViewsFlyoutProps) { // Add name as top level property to allow in memory search const namedViews = useMemo(() => views.map(addOwnName), [views]); - const renderName = (name: string, item: View) => ( + const renderName = (name: string, item: SavedViewItem) => ( ); - const renderDeleteAction = (item: View) => { + const renderDeleteAction = (item: SavedViewItem) => { return ( { + const renderMakeDefaultAction = (item: SavedViewItem) => { return ( > = [ + const columns: Array> = [ { field: 'name', name: i18n.translate('xpack.infra.openView.columnNames.name', { defaultMessage: 'Name' }), @@ -193,4 +187,7 @@ const DeleteConfimation = ({ isDisabled, onConfirm }: DeleteConfimationProps) => /** * Helpers */ -const addOwnName = (view: View) => ({ ...view, name: view.attributes.name }); +const addOwnName = (view: TSavedViewState) => ({ + ...view, + name: view.attributes.name, +}); diff --git a/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx b/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx index b52d83cac60c6c..11d45a51a0b2c8 100644 --- a/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx +++ b/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx @@ -10,35 +10,30 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiPopover, EuiListGroup, EuiListGroupItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { NonEmptyString } from '@kbn/io-ts-utils'; +import { + SavedViewState, + SavedViewOperations, + SavedViewItem, + BasicAttributes, +} from '../../../common/saved_views'; import { ManageViewsFlyout } from './manage_views_flyout'; import { useBoolean } from '../../hooks/use_boolean'; import { UpsertViewModal } from './upsert_modal'; -import { UseInventoryViewsResult } from '../../hooks/use_inventory_views'; -import { UseMetricsExplorerViewsResult } from '../../hooks/use_metrics_explorer_views'; - -type UseViewProps = - | 'currentView' - | 'views' - | 'isFetchingViews' - | 'isFetchingCurrentView' - | 'isCreatingView' - | 'isUpdatingView'; - -type UseViewResult = UseInventoryViewsResult | UseMetricsExplorerViewsResult; -type InventoryViewsResult = Pick; -type MetricsExplorerViewsResult = Pick; - -interface Props extends InventoryViewsResult, MetricsExplorerViewsResult { - viewState: ViewState & { time?: number }; - onCreateView: UseViewResult['createView']; - onDeleteView: UseViewResult['deleteViewById']; - onUpdateView: UseViewResult['updateViewById']; - onLoadViews: UseViewResult['fetchViews']; - onSetDefaultView: UseViewResult['setDefaultViewById']; - onSwitchView: UseViewResult['switchViewById']; + +interface Props + extends SavedViewState { + viewState: TViewState & BasicAttributes; + onCreateView: SavedViewOperations['createView']; + onDeleteView: SavedViewOperations['deleteViewById']; + onUpdateView: SavedViewOperations['updateViewById']; + onLoadViews: SavedViewOperations['fetchViews']; + onSetDefaultView: SavedViewOperations['setDefaultViewById']; + onSwitchView: SavedViewOperations['switchViewById']; } -export function SavedViewsToolbarControls(props: Props) { +export function SavedViewsToolbarControls( + props: Props +) { const { currentView, views, diff --git a/x-pack/plugins/infra/public/hooks/use_inventory_views.ts b/x-pack/plugins/infra/public/hooks/use_inventory_views.ts index 5bbc52e17afdaf..93873a307d59db 100644 --- a/x-pack/plugins/infra/public/hooks/use_inventory_views.ts +++ b/x-pack/plugins/infra/public/hooks/use_inventory_views.ts @@ -9,63 +9,29 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { - QueryObserverBaseResult, - UseMutateAsyncFunction, - UseMutateFunction, - useMutation, - useQuery, - useQueryClient, -} from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useUiTracker } from '@kbn/observability-shared-plugin/public'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; -import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; import { - CreateInventoryViewAttributesRequestPayload, - UpdateInventoryViewAttributesRequestPayload, -} from '../../common/http_api/latest'; + MutationContext, + SavedViewResult, + ServerError, + UpdateViewParams, +} from '../../common/saved_views'; +import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; +import { CreateInventoryViewAttributesRequestPayload } from '../../common/http_api/latest'; import type { InventoryView } from '../../common/inventory_views'; import { useKibanaContextForPlugin } from './use_kibana'; import { useUrlState } from '../utils/use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; -interface UpdateViewParams { - id: string; - attributes: UpdateInventoryViewAttributesRequestPayload; -} - -export interface UseInventoryViewsResult { - views?: InventoryView[]; - currentView?: InventoryView | null; - createView: UseMutateAsyncFunction< - InventoryView, - ServerError, - CreateInventoryViewAttributesRequestPayload - >; - deleteViewById: UseMutateFunction; - fetchViews: QueryObserverBaseResult['refetch']; - updateViewById: UseMutateAsyncFunction; - switchViewById: (id: InventoryViewId) => void; - setDefaultViewById: UseMutateFunction< - MetricsSourceConfigurationResponse, - ServerError, - string, - MutationContext - >; - isCreatingView: boolean; - isFetchingCurrentView: boolean; - isFetchingViews: boolean; - isUpdatingView: boolean; -} - -type ServerError = IHttpFetchError; - -interface MutationContext { - id?: string; - previousViews?: InventoryView[]; -} +export type UseInventoryViewsResult = SavedViewResult< + InventoryView, + InventoryViewId, + CreateInventoryViewAttributesRequestPayload, + MetricsSourceConfigurationResponse +>; const queryKeys = { find: ['inventory-views-find'] as const, @@ -122,7 +88,7 @@ export const useInventoryViews = (): UseInventoryViewsResult => { MetricsSourceConfigurationResponse, ServerError, string, - MutationContext + MutationContext >({ mutationFn: (id) => updateSourceConfiguration({ inventoryDefaultView: id }), /** @@ -167,7 +133,7 @@ export const useInventoryViews = (): UseInventoryViewsResult => { const { mutateAsync: updateViewById, isLoading: isUpdatingView } = useMutation< InventoryView, ServerError, - UpdateViewParams + UpdateViewParams >({ mutationFn: ({ id, attributes }) => inventoryViews.client.updateInventoryView(id, attributes), onError: (error) => { @@ -178,7 +144,12 @@ export const useInventoryViews = (): UseInventoryViewsResult => { }, }); - const { mutate: deleteViewById } = useMutation({ + const { mutate: deleteViewById } = useMutation< + null, + ServerError, + string, + MutationContext + >({ mutationFn: (id: string) => inventoryViews.client.deleteInventoryView(id), /** * To provide a quick feedback, we perform an optimistic update on the list diff --git a/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts b/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts index 210a23a3b21ef0..f2c9500f9ea63b 100644 --- a/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts +++ b/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts @@ -9,63 +9,29 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { - QueryObserverBaseResult, - UseMutateAsyncFunction, - UseMutateFunction, - useMutation, - useQuery, - useQueryClient, -} from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useUiTracker } from '@kbn/observability-shared-plugin/public'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; -import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; import { - CreateMetricsExplorerViewAttributesRequestPayload, - UpdateMetricsExplorerViewAttributesRequestPayload, -} from '../../common/http_api/latest'; + MutationContext, + SavedViewResult, + ServerError, + UpdateViewParams, +} from '../../common/saved_views'; +import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; +import { CreateMetricsExplorerViewAttributesRequestPayload } from '../../common/http_api/latest'; import { MetricsExplorerView } from '../../common/metrics_explorer_views'; import { useKibanaContextForPlugin } from './use_kibana'; import { useUrlState } from '../utils/use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; -interface UpdateViewParams { - id: string; - attributes: UpdateMetricsExplorerViewAttributesRequestPayload; -} - -export interface UseMetricsExplorerViewsResult { - views?: MetricsExplorerView[]; - currentView?: MetricsExplorerView | null; - createView: UseMutateAsyncFunction< - MetricsExplorerView, - ServerError, - CreateMetricsExplorerViewAttributesRequestPayload - >; - deleteViewById: UseMutateFunction; - fetchViews: QueryObserverBaseResult['refetch']; - updateViewById: UseMutateAsyncFunction; - switchViewById: (id: MetricsExplorerViewId) => void; - setDefaultViewById: UseMutateFunction< - MetricsSourceConfigurationResponse, - ServerError, - string, - MutationContext - >; - isCreatingView: boolean; - isFetchingCurrentView: boolean; - isFetchingViews: boolean; - isUpdatingView: boolean; -} - -type ServerError = IHttpFetchError; - -interface MutationContext { - id?: string; - previousViews?: MetricsExplorerView[]; -} +export type UseMetricsExplorerViewsResult = SavedViewResult< + MetricsExplorerView, + MetricsExplorerViewId, + CreateMetricsExplorerViewAttributesRequestPayload, + MetricsSourceConfigurationResponse +>; const queryKeys = { find: ['metrics-explorer-views-find'] as const, @@ -122,7 +88,7 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { MetricsSourceConfigurationResponse, ServerError, string, - MutationContext + MutationContext >({ mutationFn: (id) => updateSourceConfiguration({ metricsExplorerDefaultView: id }), /** @@ -167,7 +133,7 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { const { mutateAsync: updateViewById, isLoading: isUpdatingView } = useMutation< MetricsExplorerView, ServerError, - UpdateViewParams + UpdateViewParams >({ mutationFn: ({ id, attributes }) => metricsExplorerViews.client.updateMetricsExplorerView(id, attributes), @@ -179,7 +145,12 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { }, }); - const { mutate: deleteViewById } = useMutation({ + const { mutate: deleteViewById } = useMutation< + null, + ServerError, + string, + MutationContext + >({ mutationFn: (id: string) => metricsExplorerViews.client.deleteMetricsExplorerView(id), /** * To provide a quick feedback, we perform an optimistic update on the list diff --git a/x-pack/plugins/infra/public/lib/lib.ts b/x-pack/plugins/infra/public/lib/lib.ts index a37a9af7d93200..ac6527b9cc9c31 100644 --- a/x-pack/plugins/infra/public/lib/lib.ts +++ b/x-pack/plugins/infra/public/lib/lib.ts @@ -7,14 +7,16 @@ import { i18n } from '@kbn/i18n'; import * as rt from 'io-ts'; -import { +import type { InventoryMapBounds } from '../../common/inventory_views'; +import type { InfraTimerangeInput, SnapshotGroupBy, SnapshotMetricInput, SnapshotNodeMetric, SnapshotNodePath, } from '../../common/http_api/snapshot_api'; -import { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options'; +import type { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options'; +export type { InventoryColorPalette } from '../../common/inventory_views'; export interface InfraWaffleMapNode { pathId: string; @@ -72,9 +74,6 @@ export const PALETTES = { }), }; -export const InventoryColorPaletteRT = rt.keyof(PALETTES); -export type InventoryColorPalette = rt.TypeOf; - export const StepRuleRT = rt.intersection([ rt.type({ value: rt.number, @@ -136,10 +135,7 @@ export interface InfraOptions { wafflemap: InfraWaffleMapOptions; } -export interface InfraWaffleMapBounds { - min: number; - max: number; -} +export type InfraWaffleMapBounds = InventoryMapBounds; export type InfraFormatter = (value: string | number) => string; export enum InfraFormatterType { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx index 4547b0dbb01471..feb5283a39dcbb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { useInventoryViews } from '../../../../hooks/use_inventory_views'; import { SavedViewsToolbarControls } from '../../../../components/saved_views/toolbar_control'; -import { useWaffleViewState, WaffleViewState } from '../hooks/use_waffle_view_state'; +import { useWaffleViewState } from '../hooks/use_waffle_view_state'; export const SavedViews = () => { const { viewState } = useWaffleViewState(); @@ -28,7 +28,7 @@ export const SavedViews = () => { } = useInventoryViews(); return ( - + { return true; }; -export const DEFAULT_WAFFLE_FILTERS_STATE: WaffleFiltersState = { kind: 'kuery', expression: '' }; +export const DEFAULT_WAFFLE_FILTERS_STATE: InventoryFiltersState = { + kind: 'kuery', + expression: '', +}; export const useWaffleFilters = () => { const { createDerivedIndexPattern } = useSourceContext(); const indexPattern = createDerivedIndexPattern(); - const [urlState, setUrlState] = useUrlState({ + const [urlState, setUrlState] = useUrlState({ defaultState: DEFAULT_WAFFLE_FILTERS_STATE, decodeUrlState, encodeUrlState, urlStateKey: 'waffleFilter', }); - const [state, setState] = useState(urlState); + const [state, setState] = useState(urlState); useEffect(() => setUrlState(state), [setUrlState, state]); @@ -61,7 +68,7 @@ export const useWaffleFilters = () => { [setState] ); - const applyFilterQuery = useCallback((filterQuery: WaffleFiltersState) => { + const applyFilterQuery = useCallback((filterQuery: InventoryFiltersState) => { setState(filterQuery); setFilterQueryDraft(filterQuery.expression); }, []); @@ -87,14 +94,10 @@ export const useWaffleFilters = () => { }; }; -export const WaffleFiltersStateRT = rt.type({ - kind: rt.literal('kuery'), - expression: rt.string, -}); - -export type WaffleFiltersState = rt.TypeOf; -const encodeUrlState = WaffleFiltersStateRT.encode; +// temporary +export type WaffleFiltersState = InventoryFiltersState; +const encodeUrlState = inventoryFiltersStateRT.encode; const decodeUrlState = (value: unknown) => - pipe(WaffleFiltersStateRT.decode(value), fold(constant(undefined), identity)); + pipe(inventoryFiltersStateRT.decode(value), fold(constant(undefined), identity)); export const WaffleFilters = createContainter(useWaffleFilters); export const [WaffleFiltersProvider, useWaffleFiltersContext] = WaffleFilters; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 8767be4f8a27e3..9151e591a09f17 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -6,23 +6,25 @@ */ import { useCallback, useState, useEffect } from 'react'; -import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainer from 'constate'; -import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; -import { InventoryColorPaletteRT } from '../../../../lib/lib'; +import { InventoryViewOptions } from '../../../../../common/inventory_views/types'; import { + type InventoryLegendOptions, + type InventoryOptionsState, + type InventorySortOption, + inventoryOptionsStateRT, +} from '../../../../../common/inventory_views'; +import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; +import type { SnapshotMetricInput, SnapshotGroupBy, SnapshotCustomMetricInput, - SnapshotMetricInputRT, - SnapshotGroupByRT, - SnapshotCustomMetricInputRT, } from '../../../../../common/http_api/snapshot_api'; import { useUrlState } from '../../../../utils/use_url_state'; -import { InventoryItemType, ItemTypeRT } from '../../../../../common/inventory_models/types'; +import type { InventoryItemType } from '../../../../../common/inventory_models/types'; export const DEFAULT_LEGEND: WaffleLegendOptions = { palette: 'cool', @@ -75,7 +77,7 @@ export const useWaffleOptions = () => { ); const changeView = useCallback( - (view: string) => setState((previous) => ({ ...previous, view })), + (view: string) => setState((previous) => ({ ...previous, view: view as InventoryViewOptions })), [setState] ); @@ -160,51 +162,15 @@ export const useWaffleOptions = () => { }; }; -const WaffleLegendOptionsRT = rt.type({ - palette: InventoryColorPaletteRT, - steps: rt.number, - reverseColors: rt.boolean, -}); - -export type WaffleLegendOptions = rt.TypeOf; - -export const WaffleSortOptionRT = rt.type({ - by: rt.keyof({ name: null, value: null }), - direction: rt.keyof({ asc: null, desc: null }), -}); - -export const WaffleOptionsStateRT = rt.intersection([ - rt.type({ - metric: SnapshotMetricInputRT, - groupBy: SnapshotGroupByRT, - nodeType: ItemTypeRT, - view: rt.string, - customOptions: rt.array( - rt.type({ - text: rt.string, - field: rt.string, - }) - ), - boundsOverride: rt.type({ - min: rt.number, - max: rt.number, - }), - autoBounds: rt.boolean, - accountId: rt.string, - region: rt.string, - customMetrics: rt.array(SnapshotCustomMetricInputRT), - sort: WaffleSortOptionRT, - }), - rt.partial({ source: rt.string, legend: WaffleLegendOptionsRT, timelineOpen: rt.boolean }), -]); - -export type WaffleSortOption = rt.TypeOf; -export type WaffleOptionsState = rt.TypeOf; -const encodeUrlState = (state: WaffleOptionsState) => { - return WaffleOptionsStateRT.encode(state); +export type WaffleLegendOptions = InventoryLegendOptions; +export type WaffleSortOption = InventorySortOption; +export type WaffleOptionsState = InventoryOptionsState; + +const encodeUrlState = (state: InventoryOptionsState) => { + return inventoryOptionsStateRT.encode(state); }; const decodeUrlState = (value: unknown) => { - const state = pipe(WaffleOptionsStateRT.decode(value), fold(constant(undefined), identity)); + const state = pipe(inventoryOptionsStateRT.decode(value), fold(constant(undefined), identity)); if (state) { state.source = 'url'; } diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts index 6e685a6cc105fb..c1ff4c67addbbc 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts @@ -6,17 +6,10 @@ */ import { useCallback } from 'react'; -import { - useWaffleOptionsContext, - DEFAULT_WAFFLE_OPTIONS_STATE, - WaffleOptionsState, -} from './use_waffle_options'; +import { InventoryViewAttributes } from '../../../../../common/inventory_views'; +import { useWaffleOptionsContext, DEFAULT_WAFFLE_OPTIONS_STATE } from './use_waffle_options'; import { useWaffleTimeContext, DEFAULT_WAFFLE_TIME_STATE } from './use_waffle_time'; -import { - useWaffleFiltersContext, - DEFAULT_WAFFLE_FILTERS_STATE, - WaffleFiltersState, -} from './use_waffle_filters'; +import { useWaffleFiltersContext, DEFAULT_WAFFLE_FILTERS_STATE } from './use_waffle_filters'; export const DEFAULT_WAFFLE_VIEW_STATE: WaffleViewState = { ...DEFAULT_WAFFLE_OPTIONS_STATE, @@ -65,8 +58,8 @@ export const useWaffleViewState = () => { }; const onViewChange = useCallback( - (newState) => { - const attributes = newState.attributes as WaffleViewState; + (newState: { attributes: WaffleViewState }) => { + const attributes = newState.attributes; setWaffleOptionsState({ sort: attributes.sort, @@ -102,8 +95,7 @@ export const useWaffleViewState = () => { }; }; -export type WaffleViewState = WaffleOptionsState & { - time: number; - autoReload: boolean; - filterQuery: WaffleFiltersState; -}; +export type WaffleViewState = Omit< + InventoryViewAttributes, + 'name' | 'isDefault' | 'isStatic' | 'source' +>; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts index c7015764ddf24b..cd37b0d8aab25b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { InventoryColorPalette, InfraWaffleMapSteppedGradientLegend } from '../../../../lib/lib'; +import type { + InventoryColorPalette, + InfraWaffleMapSteppedGradientLegend, +} from '../../../../lib/lib'; import { getColorPalette } from './get_color_palette'; export const createLegend = ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx index 2d329f121f0081..ddce0eac506feb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx @@ -31,7 +31,7 @@ export const SavedViews = ({ viewState }: Props) => { } = useMetricsExplorerViews(); return ( - + currentView={currentView} views={views} isFetchingViews={isFetchingViews} diff --git a/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts b/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts index eeabd15e60a4bb..5cfda02fa4c173 100644 --- a/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts +++ b/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts @@ -9,15 +9,18 @@ import { HttpStart } from '@kbn/core/public'; import { CreateInventoryViewAttributesRequestPayload, createInventoryViewRequestPayloadRT, + CreateInventoryViewResponsePayload, + FindInventoryViewResponsePayload, findInventoryViewResponsePayloadRT, + GetInventoryViewResposePayload, getInventoryViewUrl, inventoryViewResponsePayloadRT, UpdateInventoryViewAttributesRequestPayload, + UpdateInventoryViewResponsePayload, } from '../../../common/http_api/latest'; import { DeleteInventoryViewError, FetchInventoryViewError, - InventoryView, UpsertInventoryViewError, } from '../../../common/inventory_views'; import { decodeOrThrow } from '../../../common/runtime_types'; @@ -26,7 +29,7 @@ import { IInventoryViewsClient } from './types'; export class InventoryViewsClient implements IInventoryViewsClient { constructor(private readonly http: HttpStart) {} - async findInventoryViews(): Promise { + async findInventoryViews(): Promise { const response = await this.http.get(getInventoryViewUrl()).catch((error) => { throw new FetchInventoryViewError(`Failed to fetch inventory views: ${error}`); }); @@ -40,7 +43,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { return data; } - async getInventoryView(inventoryViewId: string): Promise { + async getInventoryView(inventoryViewId: string): Promise { const response = await this.http.get(getInventoryViewUrl(inventoryViewId)).catch((error) => { throw new FetchInventoryViewError( `Failed to fetch inventory view "${inventoryViewId}": ${error}` @@ -60,7 +63,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { async createInventoryView( inventoryViewAttributes: CreateInventoryViewAttributesRequestPayload - ): Promise { + ): Promise { const response = await this.http .post(getInventoryViewUrl(), { body: JSON.stringify( @@ -85,7 +88,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { async updateInventoryView( inventoryViewId: string, inventoryViewAttributes: UpdateInventoryViewAttributesRequestPayload - ): Promise { + ): Promise { const response = await this.http .put(getInventoryViewUrl(inventoryViewId), { body: JSON.stringify( diff --git a/x-pack/plugins/infra/public/services/inventory_views/types.ts b/x-pack/plugins/infra/public/services/inventory_views/types.ts index 573c144e9c4415..e2e26e6ef7f5b9 100644 --- a/x-pack/plugins/infra/public/services/inventory_views/types.ts +++ b/x-pack/plugins/infra/public/services/inventory_views/types.ts @@ -8,9 +8,12 @@ import { HttpStart } from '@kbn/core/public'; import { CreateInventoryViewAttributesRequestPayload, + CreateInventoryViewResponsePayload, + FindInventoryViewResponsePayload, + GetInventoryViewResposePayload, UpdateInventoryViewAttributesRequestPayload, + UpdateInventoryViewResponsePayload, } from '../../../common/http_api/latest'; -import type { InventoryView } from '../../../common/inventory_views'; export type InventoryViewsServiceSetup = void; @@ -23,14 +26,14 @@ export interface InventoryViewsServiceStartDeps { } export interface IInventoryViewsClient { - findInventoryViews(): Promise; - getInventoryView(inventoryViewId: string): Promise; + findInventoryViews(): Promise; + getInventoryView(inventoryViewId: string): Promise; createInventoryView( inventoryViewAttributes: CreateInventoryViewAttributesRequestPayload - ): Promise; + ): Promise; updateInventoryView( inventoryViewId: string, inventoryViewAttributes: UpdateInventoryViewAttributesRequestPayload - ): Promise; + ): Promise; deleteInventoryView(inventoryViewId: string): Promise; } diff --git a/x-pack/plugins/infra/server/routes/inventory_views/README.md b/x-pack/plugins/infra/server/routes/inventory_views/README.md index be7d1c37341577..6edf5a540536a4 100644 --- a/x-pack/plugins/infra/server/routes/inventory_views/README.md +++ b/x-pack/plugins/infra/server/routes/inventory_views/README.md @@ -130,26 +130,62 @@ Status code: 404 Creates a new inventory view. +`metric.type`: `"count" | "cpu" | "diskLatency" | "diskSpaceUsage" | "load" | "memory" | "memoryFree" | "memoryTotal" | "normalizedLoad1m" | "tx" | "rx" | "logRate" | "diskIOReadBytes" | "diskIOWriteBytes" | "s3TotalRequests" | "s3NumberOfObjects" | "s3BucketSize" | "s3DownloadBytes" | "s3UploadBytes" | "rdsConnections" | "rdsQueriesExecuted" | "rdsActiveTransactions" | "rdsLatency" | "sqsMessagesVisible" | "sqsMessagesDelayed" | "sqsMessagesSent" | "sqsMessagesEmpty" | "sqsOldestMessage"` + +`boundsOverride.max`: `range 0 to 1` +`boundsOverride.min`: `range 0 to 1` + +`sort.by`: `"name" | "value"` +`sort.direction`: `"asc | "desc"` + +`legend.pallete`: `"status" | "temperature" | "cool" | "warm" | "positive" | "negative"` + +`view`: `"map" | "table"` + ### Request - **Method**: POST - **Path**: /api/infra/inventory_views - **Request body**: + ```json { "attributes": { - "name": "View name", "metric": { - "type": "cpu" + "type": "cpu" }, "sort": { - "by": "name", - "direction": "desc" + "by": "name", + "direction": "desc" }, - //... + "groupBy": [], + "nodeType": "host", + "view": "map", + "customOptions": [], + "customMetrics": [], + "boundsOverride": { + "max": 1, + "min": 0 + }, + "autoBounds": true, + "accountId": "", + "region": "", + "autoReload": false, + "filterQuery": { + "expression": "", + "kind": "kuery" + }, + "legend": { + "palette": "cool", + "steps": 10, + "reverseColors": false + }, + "timelineOpen": false, + "name": "test-uptime" } } - ``` + +``` ### Response diff --git a/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts b/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts index 45e738f3920f15..30ab7068b7f40c 100644 --- a/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts +++ b/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts @@ -5,14 +5,76 @@ * 2.0. */ -import { isoToEpochRt, nonEmptyStringRt } from '@kbn/io-ts-utils'; +import { inRangeRt, isoToEpochRt, nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { ItemTypeRT } from '../../../common/inventory_models/types'; + +export const inventorySavedObjectColorPaletteRT = rt.keyof({ + status: null, + temperature: null, + cool: null, + warm: null, + positive: null, + negative: null, +}); + +const inventorySavedObjectLegendOptionsRT = rt.type({ + palette: inventorySavedObjectColorPaletteRT, + steps: inRangeRt(2, 18), + reverseColors: rt.boolean, +}); + +export const inventorySavedObjectSortOptionRT = rt.type({ + by: rt.keyof({ name: null, value: null }), + direction: rt.keyof({ asc: null, desc: null }), +}); + +export const inventorySavedObjectViewOptionsRT = rt.keyof({ table: null, map: null }); + +export const inventorySabedObjectMapBoundsRT = rt.type({ + min: inRangeRt(0, 1), + max: inRangeRt(0, 1), +}); + +export const inventorySavedObjectFiltersStateRT = rt.type({ + kind: rt.literal('kuery'), + expression: rt.string, +}); + +export const inventorySavedObjectOptionsStateRT = rt.intersection([ + rt.type({ + accountId: rt.string, + autoBounds: rt.boolean, + boundsOverride: inventorySabedObjectMapBoundsRT, + customMetrics: rt.UnknownArray, + customOptions: rt.array( + rt.type({ + text: rt.string, + field: rt.string, + }) + ), + groupBy: rt.UnknownArray, + metric: rt.UnknownRecord, + nodeType: ItemTypeRT, + region: rt.string, + sort: inventorySavedObjectSortOptionRT, + view: inventorySavedObjectViewOptionsRT, + }), + rt.partial({ + legend: inventorySavedObjectLegendOptionsRT, + source: rt.string, + timelineOpen: rt.boolean, + }), +]); export const inventoryViewSavedObjectAttributesRT = rt.intersection([ - rt.strict({ + inventorySavedObjectOptionsStateRT, + rt.type({ name: nonEmptyStringRt, + autoReload: rt.boolean, + filterQuery: inventorySavedObjectFiltersStateRT, }), - rt.UnknownRecord, + rt.partial({ time: rt.number, isDefault: rt.boolean, isStatic: rt.boolean }), ]); export const inventoryViewSavedObjectRT = rt.intersection([ @@ -25,3 +87,5 @@ export const inventoryViewSavedObjectRT = rt.intersection([ updated_at: isoToEpochRt, }), ]); + +export type InventoryViewSavedObject = rt.TypeOf; diff --git a/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts b/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts index 5efce009da4103..78c7007ed1d1ab 100644 --- a/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts +++ b/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts @@ -14,6 +14,7 @@ import { } from '@kbn/core/server'; import Boom from '@hapi/boom'; import { + inventoryViewAttributesRT, staticInventoryViewAttributes, staticInventoryViewId, } from '../../../common/inventory_views'; @@ -131,10 +132,10 @@ export class InventoryViewsClient implements IInventoryViewsClient { return this.savedObjectsClient.delete(inventoryViewSavedObjectName, inventoryViewId); } - private mapSavedObjectToInventoryView( - savedObject: SavedObject | SavedObjectsUpdateResponse, + private mapSavedObjectToInventoryView( + savedObject: SavedObject | SavedObjectsUpdateResponse, defaultViewId?: string - ) { + ): InventoryView { const inventoryViewSavedObject = decodeOrThrow(inventoryViewSavedObjectRT)(savedObject); return { @@ -142,7 +143,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { version: inventoryViewSavedObject.version, updatedAt: inventoryViewSavedObject.updated_at, attributes: { - ...inventoryViewSavedObject.attributes, + ...decodeOrThrow(inventoryViewAttributesRT)(inventoryViewSavedObject.attributes), isDefault: inventoryViewSavedObject.id === defaultViewId, isStatic: false, }, diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index 98481732be9d5b..59ea0e5d21702b 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -224,9 +224,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/157740 describe('Saved Views', () => { - this.tags('skipFirefox'); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); await pageObjects.infraHome.goToMetricExplorer(); diff --git a/x-pack/test/functional/page_objects/infra_saved_views.ts b/x-pack/test/functional/page_objects/infra_saved_views.ts index 56c6e0d1354fb6..218a7058f11418 100644 --- a/x-pack/test/functional/page_objects/infra_saved_views.ts +++ b/x-pack/test/functional/page_objects/infra_saved_views.ts @@ -54,7 +54,10 @@ export function InfraSavedViewsProvider({ getService }: FtrProviderContext) { async createNewSavedView(name: string) { await testSubjects.setValue('savedViewName', name); await testSubjects.click('createSavedViewButton'); - await testSubjects.missingOrFail('savedViews-upsertModal'); + + await retry.tryForTime(10 * 1000, async () => { + await testSubjects.missingOrFail('savedViews-upsertModal'); + }); }, async createView(name: string) { From 71da75408589a5718ac0b780eb7f8305a70fd1a1 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Wed, 5 Jul 2023 09:03:18 +0200 Subject: [PATCH 69/98] [SecuritySolutions] Remove filter actions from Cases alerts table and fix show_top_n action (#161150) issue https://github.com/elastic/kibana/issues/134442 ## Summary * Remove filter actions from the cases alerts page because it has no search bar (as suggested by Sergi). * Fix the `show_top_n` action not executing from inside a table cell * Fix the `show_top_n` action not preselecting alerts on the cases alerts table Warning: `show_top_n` uses the global `timerange` but the cases page doesn't have the time range picker. --- .../src/hooks/use_data_grid_column_cell_actions.tsx | 2 +- .../public/common/components/top_n/helpers.ts | 1 + .../trigger_actions_alert_table/use_cell_actions.tsx | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx b/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx index 5877added643fb..5820e7a971e90d 100644 --- a/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx +++ b/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx @@ -192,7 +192,7 @@ const getParentCellElement = (element?: HTMLElement | null): HTMLElement | null if (element == null) { return null; } - if (element.nodeName === 'div' && element.getAttribute('role') === 'gridcell') { + if (element.nodeName === 'DIV' && element.getAttribute('role') === 'gridcell') { return element; } return getParentCellElement(element.parentElement); diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts index 659aa08d754bf0..876f04393dcdc5 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts @@ -70,6 +70,7 @@ export interface TopNOption { export const detectionAlertsTables: string[] = [ TableId.alertsOnAlertsPage, TableId.alertsOnRuleDetailsPage, + TableId.alertsOnCasePage, TimelineId.casePage, ]; diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx index b6987f2fe29f61..e945e2c4828f2b 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx @@ -8,12 +8,11 @@ import type { BrowserField, TimelineNonEcsData } from '@kbn/timelines-plugin/common'; import type { AlertsTableConfigurationRegistry } from '@kbn/triggers-actions-ui-plugin/public/types'; import { useCallback, useMemo } from 'react'; -import { tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table'; -import type { TableId } from '@kbn/securitysolution-data-table'; +import { TableId, tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table'; import { getAllFieldsByName } from '../../../common/containers/source'; import type { UseDataGridColumnsSecurityCellActionsProps } from '../../../common/components/cell_actions'; import { useDataGridColumnsSecurityCellActions } from '../../../common/components/cell_actions'; -import { SecurityCellActionsTrigger } from '../../../actions/constants'; +import { SecurityCellActionsTrigger, SecurityCellActionType } from '../../../actions/constants'; import { VIEW_SELECTION } from '../../../../common/constants'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; @@ -89,12 +88,16 @@ export const getUseCellActionsHook = (tableId: TableId) => { [finalData] ); + const disabledActionTypes = + tableId === TableId.alertsOnCasePage ? [SecurityCellActionType.FILTER] : undefined; + const cellActions = useDataGridColumnsSecurityCellActions({ triggerId: SecurityCellActionsTrigger.DEFAULT, fields: cellActionsFields, getCellValue, metadata: cellActionsMetadata, dataGridRef, + disabledActionTypes, }); const getCellActions = useCallback( From 7be72ef2bfe123a5669e67229d3f7afcda0b88bf Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Wed, 5 Jul 2023 09:11:50 +0200 Subject: [PATCH 70/98] [Security Solutions] Fix CellActions component should hide ShowTopN action for nested fields (#159645) issue: https://github.com/elastic/kibana/issues/150347 ## Summary CellActions component should hide `ShowTopN` action for nested fields because Lens doesn't support it. * Add validations to exclude field that are not supported by Lens **After:** Screenshot 2023-06-30 at 14 26 09 ### How to test * Go to Security Solutions Alerts page * Add `Endpoint.policy.applied.artifacts.global.identifiers.name` field * Check if `ShowTopN` is displayed ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../cell_action/show_top_n.test.tsx | 38 ++++++++++++++----- .../show_top_n/cell_action/show_top_n.tsx | 9 ++--- .../public/common/utils/lens.ts | 18 +++++++++ .../components/alerts_kpis/common/hooks.ts | 6 +-- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/utils/lens.ts diff --git a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx index bb64a2a2bdac6d..87c920e7878953 100644 --- a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx +++ b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx @@ -17,6 +17,7 @@ import { createStore } from '../../../common/store'; import { createShowTopNCellActionFactory } from './show_top_n'; import React from 'react'; import { createStartServicesMock } from '../../../common/lib/kibana/kibana_react.mock'; +import { KBN_FIELD_TYPES } from '@kbn/field-types'; jest.mock('../../../common/lib/kibana'); @@ -45,7 +46,7 @@ describe('createShowTopNCellActionFactory', () => { value: 'the-value', field: { name: 'user.name', - type: 'keyword', + type: KBN_FIELD_TYPES.STRING, aggregatable: true, searchable: true, }, @@ -71,35 +72,54 @@ describe('createShowTopNCellActionFactory', () => { }); describe('isCompatible', () => { - it('should return true if everything is okay', async () => { - expect(await showTopNAction.isCompatible(context)).toEqual(true); - }); - - it('should return false if field esType does not support aggregations', async () => { + it('should return false if field is not aggregatable', async () => { expect( await showTopNAction.isCompatible({ ...context, data: [ { - field: { ...context.data[0].field, esTypes: ['text'] }, + field: { ...context.data[0].field, aggregatable: false }, }, ], }) ).toEqual(false); }); - it('should return false if field is not aggregatable', async () => { + it('should return false if field is nested', async () => { expect( await showTopNAction.isCompatible({ ...context, data: [ { - field: { ...context.data[0].field, aggregatable: false }, + field: { ...context.data[0].field, subType: { nested: { path: 'test_path' } } }, }, ], }) ).toEqual(false); }); + + describe.each([ + { type: KBN_FIELD_TYPES.STRING, expectedValue: true }, + { type: KBN_FIELD_TYPES.BOOLEAN, expectedValue: true }, + { type: KBN_FIELD_TYPES.NUMBER, expectedValue: true }, + { type: KBN_FIELD_TYPES.IP, expectedValue: true }, + { type: KBN_FIELD_TYPES.DATE, expectedValue: false }, + { type: KBN_FIELD_TYPES.GEO_SHAPE, expectedValue: false }, + { type: KBN_FIELD_TYPES.IP_RANGE, expectedValue: false }, + ])('lens supported KBN types', ({ type, expectedValue }) => { + it(`should return ${expectedValue} when type is ${type}`, async () => { + expect( + await showTopNAction.isCompatible({ + ...context, + data: [ + { + field: { ...context.data[0].field, type }, + }, + ], + }) + ).toEqual(expectedValue); + }); + }); }); describe('execute', () => { diff --git a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx index 0e1c419b0449e3..3491f0ffcc620a 100644 --- a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx +++ b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx @@ -12,7 +12,7 @@ import { Router } from '@kbn/shared-ux-router'; import { i18n } from '@kbn/i18n'; import { createCellActionFactory, type CellActionTemplate } from '@kbn/cell-actions'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; -import { ES_FIELD_TYPES } from '@kbn/field-types'; +import { isDataViewFieldSubtypeNested } from '@kbn/es-query'; import { KibanaContextProvider } from '../../../common/lib/kibana'; import { APP_NAME, DEFAULT_DARK_MODE } from '../../../../common/constants'; import type { SecurityAppStore } from '../../../common/store'; @@ -21,6 +21,7 @@ import { TopNAction } from '../show_top_n_component'; import type { StartServices } from '../../../types'; import type { SecurityCellAction } from '../../types'; import { SecurityCellActionType } from '../../constants'; +import { isLensSupportedType } from '../../../common/utils/lens'; const SHOW_TOP = (fieldName: string) => i18n.translate('xpack.securitySolution.actions.showTopTooltip', { @@ -29,7 +30,6 @@ const SHOW_TOP = (fieldName: string) => }); const ICON = 'visBarVertical'; -const UNSUPPORTED_ES_FIELD_TYPES = [ES_FIELD_TYPES.DATE, ES_FIELD_TYPES.TEXT]; export const createShowTopNCellActionFactory = createCellActionFactory( ({ @@ -51,9 +51,8 @@ export const createShowTopNCellActionFactory = createCellActionFactory( return ( data.length === 1 && fieldHasCellActions(field.name) && - (field.esTypes ?? []).every( - (esType) => !UNSUPPORTED_ES_FIELD_TYPES.includes(esType as ES_FIELD_TYPES) - ) && + isLensSupportedType(field.type) && + !isDataViewFieldSubtypeNested(field) && !!field.aggregatable ); }, diff --git a/x-pack/plugins/security_solution/public/common/utils/lens.ts b/x-pack/plugins/security_solution/public/common/utils/lens.ts new file mode 100644 index 00000000000000..047144ce55f6f8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/lens.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. + */ + +import { KBN_FIELD_TYPES } from '@kbn/field-types'; + +const SUPPORTED_LENS_TYPES = new Set([ + KBN_FIELD_TYPES.STRING, + KBN_FIELD_TYPES.BOOLEAN, + KBN_FIELD_TYPES.NUMBER, + KBN_FIELD_TYPES.IP, +]); + +export const isLensSupportedType = (fieldType: string | undefined) => + fieldType ? SUPPORTED_LENS_TYPES.has(fieldType as KBN_FIELD_TYPES) : false; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts index 2658a0af00d6b5..86c8719053c81c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts @@ -14,6 +14,7 @@ import type { BrowserField } from '@kbn/timelines-plugin/common'; import type { GlobalTimeArgs } from '../../../../common/containers/use_global_time'; import { getScopeFromPath, useSourcererDataView } from '../../../../common/containers/sourcerer'; import { getAllFieldsByName } from '../../../../common/containers/source'; +import { isLensSupportedType } from '../../../../common/utils/lens'; export interface UseInspectButtonParams extends Pick { response: string; @@ -65,11 +66,6 @@ export function isDataViewFieldSubtypeNested(field: Partial) { return !!subTypeNested?.nested?.path; } -export function isLensSupportedType(fieldType: string | undefined) { - const supportedTypes = new Set(['string', 'boolean', 'number', 'ip']); - return fieldType ? supportedTypes.has(fieldType) : false; -} - export interface GetAggregatableFields { [fieldName: string]: Partial; } From abe58cb0113e7c58f3bab3ab7d297e65ca01c0d9 Mon Sep 17 00:00:00 2001 From: Marco Antonio Ghiani Date: Wed, 5 Jul 2023 10:30:28 +0200 Subject: [PATCH 71/98] [Logs Shared] Move LogStream and LogView into new shared plugin (#161151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📓 Summary Closes #159128 Due to a dependencies issue when disabling a plugin in serverless mode, the LogStream feature and related logic were disabled for every consumer. We decided to split this shared component and endpoint into their own plugin of shared logs utilities, reducing to the minimum the required dependency that could disable the plugin. What we moved can be summarized with: - `infrastructure-monitoring-log-view` saved object definition and registration - LogViews server/client services (exposed with start contract) + related endpoints - LogEntries server service + related endpoints - LogEntriesDomain logic (exposed with start contract) - `` component - `` component and related logic - LogView state machine - Containers/Hooks to consume the moved APIs. - Common types/utils definition, now exported and consumed as a dependency from the `infra` plugin. ## 🤓 Review hints Most of the changes are just renaming and moving stuff into the new plugin, but for some operations was required to implement new logic, which may deserve a more critical review: - server/public `plugin.ts` files for the `infra` and `logs_shared` plugins. The new plugin now registers the fallback actions to retrieve a source configuration if there's no stored log view. It also set the configuration for the message field and registers the log view saved object. - the `logEntriesDomain` has also been moved inside the new plugin, but is also used by the logs-analysis endpoints, so it is exposed by the logs_shared plugin and consumed by `infra`. ## 👣 Following steps We currently are still using the `observability` plugin for consuming the CoPilot feature on our LogsStream flyout. The plugin dependency is marked as optional, so disabling the `observability` plugin in a serverless environment won't disable also the exposed features in this new plugin, but it'll affect only the CoPilot feature, which won't be loaded. In future, would be nice to extract the CoPilot feature into its own package/plugin, so that also serverless projects can consume it without depending on `observability. --------- Co-authored-by: Marco Antonio Ghiani Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + docs/developer/plugin-list.asciidoc | 4 + package.json | 1 + packages/kbn-optimizer/limits.yml | 1 + tsconfig.base.json | 2 + x-pack/.i18nrc.json | 1 + x-pack/plugins/apm/kibana.jsonc | 1 + .../components/app/service_logs/index.tsx | 2 +- .../transaction_tabs.tsx | 2 +- x-pack/plugins/apm/tsconfig.json | 1 + .../common/types/kibana_deps.ts | 2 - x-pack/plugins/enterprise_search/kibana.jsonc | 2 +- .../shared/log_stream/log_stream.tsx | 8 +- .../enterprise_search/server/plugin.ts | 14 +- .../plugins/enterprise_search/tsconfig.json | 2 +- x-pack/plugins/fleet/kibana.jsonc | 2 +- .../components/agent_logs/agent_logs.tsx | 2 +- x-pack/plugins/fleet/tsconfig.json | 2 +- .../alerting/logs/log_threshold/types.ts | 2 +- x-pack/plugins/infra/common/http_api/index.ts | 2 - .../plugins/infra/common/http_api/latest.ts | 2 - .../log_alerts/v1/chart_preview_data.ts | 2 +- .../results/v1/log_entry_anomalies.ts | 2 +- .../v1/log_entry_anomalies_datasets.ts | 2 +- .../results/v1/log_entry_categories.ts | 2 +- .../results/v1/log_entry_category_datasets.ts | 2 +- .../results/v1/log_entry_category_examples.ts | 6 +- .../results/v1/log_entry_examples.ts | 2 +- .../plugins/infra/common/locators/helpers.ts | 24 +- .../infra/common/locators/locators.test.ts | 2 +- .../infra/common/locators/logs_locator.ts | 2 +- .../log_entries/log_entries.ts | 7 +- .../log_entries/log_entry.ts | 7 +- .../url_state_storage_service.ts | 8 +- x-pack/plugins/infra/kibana.jsonc | 1 + .../components/explain_log_rate_spike.tsx | 9 +- .../alert_details_app_section/index.tsx | 6 +- .../components/alert_dropdown.tsx | 2 +- .../components/expression_editor/criteria.tsx | 2 +- .../expression_editor/criterion.tsx | 2 +- .../criterion_preview_chart.tsx | 2 +- .../components/expression_editor/editor.tsx | 8 +- .../hooks/use_chart_preview_data.tsx | 2 +- .../expression_editor/log_view_switcher.tsx | 2 +- .../infra/public/apps/discover_app.tsx | 2 +- .../context/fixtures/log_entries.ts | 2 +- .../asset_details/tabs/logs/logs.tsx | 4 +- .../public/components/asset_details/types.ts | 2 +- .../log_stream/log_stream_embeddable.tsx | 4 +- .../logging/log_minimap/density_chart.tsx | 2 +- .../logging/log_minimap/log_minimap.tsx | 13 +- .../logging/log_minimap/search_marker.tsx | 7 +- .../logging/log_minimap/search_markers.tsx | 4 +- .../log_search_buttons.tsx | 3 +- .../log_search_controls.tsx | 2 +- .../view_log_in_context.ts | 3 +- .../infra/public/hooks/use_log_view.mock.ts | 77 ----- x-pack/plugins/infra/public/index.ts | 2 - x-pack/plugins/infra/public/mocks.tsx | 2 - .../state/src/state_machine.ts | 4 +- .../log_stream_page/state/src/types.ts | 12 +- .../src/url_state_storage_service.ts | 11 + .../src/state_machine.ts | 2 +- .../src/url_state_storage_service.ts | 6 +- .../src/state_machine_playground.tsx | 2 +- .../public/pages/link_to/redirect_to_logs.tsx | 2 +- .../pages/link_to/redirect_to_node_logs.tsx | 2 +- .../log_entry_categories/page_content.tsx | 2 +- .../log_entry_categories/page_providers.tsx | 2 +- .../page_results_content.tsx | 2 +- .../top_categories/category_details_row.tsx | 2 +- .../category_example_message.tsx | 25 +- .../top_categories/top_categories_section.tsx | 2 +- .../top_categories/top_categories_table.tsx | 2 +- .../get_log_entry_category_datasets.ts | 2 +- .../get_log_entry_category_examples.ts | 2 +- .../get_top_log_entry_categories.ts | 2 +- .../use_log_entry_categories_results.ts | 2 +- .../use_log_entry_category_examples.tsx | 2 +- .../logs/log_entry_rate/page_content.tsx | 2 +- .../logs/log_entry_rate/page_providers.tsx | 2 +- .../log_entry_rate/page_results_content.tsx | 3 +- .../sections/anomalies/expanded_row.tsx | 2 +- .../sections/anomalies/log_entry_example.tsx | 8 +- .../service_calls/get_log_entry_anomalies.ts | 2 +- .../get_log_entry_anomalies_datasets.ts | 2 +- .../service_calls/get_log_entry_examples.ts | 2 +- .../use_log_entry_anomalies_results.ts | 2 +- .../log_entry_rate/use_log_entry_examples.ts | 2 +- .../public/pages/logs/page_providers.tsx | 12 +- .../index_names_configuration_panel.tsx | 2 +- .../index_pattern_configuration_panel.tsx | 2 +- .../indices_configuration_form_state.ts | 2 +- .../settings/indices_configuration_panel.tsx | 2 +- .../source_configuration_form_state.tsx | 2 +- .../source_configuration_settings.tsx | 2 +- .../pages/logs/shared/page_log_view_error.tsx | 4 +- .../infra/public/pages/logs/stream/page.tsx | 2 +- .../pages/logs/stream/page_logs_content.tsx | 38 ++- .../pages/logs/stream/page_providers.tsx | 15 +- .../public/pages/logs/stream/page_toolbar.tsx | 8 +- .../logs/stream/page_view_log_in_context.tsx | 4 +- .../tabs/logs/logs_link_to_stream.tsx | 2 +- .../components/tabs/logs/logs_tab_content.tsx | 2 +- .../hosts/hooks/use_log_view_reference.ts | 8 +- .../components/node_details/tabs/logs.tsx | 2 +- .../metric_detail/hooks/use_metrics_time.ts | 2 +- x-pack/plugins/infra/public/plugin.ts | 18 +- .../infra/public/test_utils/entries.ts | 11 +- x-pack/plugins/infra/public/types.ts | 8 +- .../public/utils/logs_overview_fetchers.ts | 14 +- .../utils/logs_overview_fetches.test.ts | 74 +++-- .../plugins/infra/public/utils/url_state.tsx | 2 +- .../infra/public/utils/use_url_state.ts | 2 +- x-pack/plugins/infra/server/features.ts | 2 +- x-pack/plugins/infra/server/infra_server.ts | 10 - .../lib/adapters/framework/adapter_types.ts | 3 + ...nventory_metric_threshold_executor.test.ts | 3 +- .../inventory_metric_threshold_executor.ts | 4 +- .../log_threshold_chart_preview.ts | 2 +- .../log_threshold/log_threshold_executor.ts | 4 +- .../log_threshold_references_manager.ts | 4 +- .../plugins/infra/server/lib/infra_types.ts | 4 +- .../lib/log_analysis/log_entry_anomalies.ts | 2 +- .../log_entry_categories_analysis.ts | 7 +- x-pack/plugins/infra/server/mocks.ts | 16 +- x-pack/plugins/infra/server/plugin.ts | 61 ++-- .../routes/log_alerts/chart_preview_data.ts | 6 +- .../results/log_entry_category_examples.ts | 6 +- .../results/log_entry_examples.ts | 6 +- .../infra/server/routes/snapshot/index.ts | 4 +- .../infra/server/saved_objects/index.ts | 1 - x-pack/plugins/infra/server/types.ts | 12 +- .../utils/elasticsearch_runtime_types.ts | 7 - .../utils/map_source_to_log_view.test.ts | 59 ++++ .../server/utils/map_source_to_log_view.ts | 38 +++ x-pack/plugins/infra/tsconfig.json | 2 +- x-pack/plugins/logs_shared/README.md | 3 + .../plugins/logs_shared/common/constants.ts | 10 + x-pack/plugins/logs_shared/common/dynamic.tsx | 30 ++ .../logs_shared/common/formatters/datetime.ts | 18 ++ .../logs_shared/common/http_api/index.ts | 13 + .../logs_shared/common/http_api/latest.ts | 9 + .../http_api/log_entries/v1/highlights.ts | 0 .../common/http_api/log_entries/v1/index.ts | 0 .../common/http_api/log_entries/v1/summary.ts | 0 .../log_entries/v1/summary_highlights.ts | 0 .../common/http_api/log_views/common.ts | 0 .../common/http_api/log_views/index.ts | 0 .../http_api/log_views/v1/get_log_view.ts | 0 .../common/http_api/log_views/v1/index.ts | 0 .../http_api/log_views/v1/put_log_view.ts | 0 x-pack/plugins/logs_shared/common/index.ts | 58 ++++ .../common/log_entry/index.ts | 0 .../common/log_entry/log_entry.ts | 0 .../common/log_entry/log_entry_cursor.ts | 0 .../common/log_text_scale/index.ts | 8 + .../common/log_text_scale/log_text_scale.ts | 12 + .../common/log_views/defaults.ts | 7 +- .../common/log_views/errors.ts | 0 .../common/log_views/index.ts | 1 - .../common/log_views/log_view.mock.ts | 0 .../log_views/resolved_log_view.mock.ts | 0 .../common/log_views/resolved_log_view.ts | 9 +- .../common/log_views/types.ts | 4 +- x-pack/plugins/logs_shared/common/mocks.ts | 8 + .../logs_shared/common/runtime_types.ts | 69 ++++ .../common/search_strategies/common/errors.ts | 43 +++ .../log_entries/log_entries.ts | 75 +++++ .../log_entries/log_entry.ts | 40 +++ .../plugins/logs_shared/common/time/index.ts | 8 + .../logs_shared/common/time/time_key.ts | 80 +++++ .../plugins/logs_shared/common/typed_json.ts | 26 ++ x-pack/plugins/logs_shared/jest.config.js | 17 + x-pack/plugins/logs_shared/kibana.jsonc | 22 ++ .../public/components/auto_sizer.tsx | 188 +++++++++++ .../components/centered_flyout_body.tsx | 0 .../data_search_error_callout.stories.tsx | 0 .../components/data_search_error_callout.tsx | 6 +- .../data_search_progress.stories.tsx | 0 .../components/data_search_progress.tsx | 2 +- .../public/components/empty_states/index.tsx | 8 + .../components/empty_states/no_data.tsx | 49 +++ .../public/components/formatted_time.tsx | 0 .../loading/__examples__/index.stories.tsx | 23 ++ .../public/components/loading/index.tsx | 49 +++ .../public/components/log_stream/index.ts | 0 .../log_stream/log_stream.stories.mdx | 22 +- .../log_stream/log_stream.stories.tsx | 0 .../log_stream.story_decorators.tsx | 0 .../components/log_stream/log_stream.tsx | 0 .../log_stream/log_stream_error_boundary.tsx | 4 +- .../logging/log_entry_flyout/index.tsx | 0 .../log_entry_actions_menu.test.tsx | 0 .../log_entry_actions_menu.tsx | 19 +- .../log_entry_fields_table.tsx | 8 +- .../log_entry_flyout/log_entry_flyout.tsx | 26 +- .../log_text_stream/column_headers.tsx | 4 +- .../logging/log_text_stream/field_value.tsx | 0 .../logging/log_text_stream/highlighting.tsx | 0 .../logging/log_text_stream/index.ts | 7 +- .../logging/log_text_stream/item.ts | 0 .../logging/log_text_stream/jump_to_tail.tsx | 4 +- .../log_text_stream/loading_item_view.tsx | 28 +- .../logging/log_text_stream/log_date_row.tsx | 0 .../log_text_stream/log_entry_column.tsx | 0 .../log_entry_context_menu.tsx | 2 +- .../log_entry_field_column.test.tsx | 0 .../log_entry_field_column.tsx | 0 .../log_entry_message_column.test.tsx | 0 .../log_entry_message_column.tsx | 0 .../logging/log_text_stream/log_entry_row.tsx | 6 +- .../log_entry_timestamp_column.tsx | 0 .../log_text_stream/log_text_separator.tsx | 0 .../log_text_stream/measurable_item_view.tsx | 0 .../scrollable_log_text_stream_view.tsx | 22 +- .../logging/log_text_stream/text_styles.tsx | 0 .../log_text_stream/vertical_scroll_panel.tsx | 0 .../components/resettable_error_boundary.tsx | 0 .../public/containers/logs/log_entry.ts | 0 .../api/fetch_log_entries_highlights.ts | 0 .../api/fetch_log_summary_highlights.ts | 0 .../containers/logs/log_highlights/index.ts | 0 .../log_highlights/log_entry_highlights.tsx | 2 +- .../logs/log_highlights/log_highlights.tsx | 7 +- .../log_highlights/log_summary_highlights.ts | 2 +- .../logs/log_highlights/next_and_previous.tsx | 0 .../containers/logs/log_position/index.ts | 0 .../logs/log_position/use_log_position.ts | 43 ++- .../containers/logs/log_stream/index.ts | 0 .../log_stream/use_fetch_log_entries_after.ts | 0 .../use_fetch_log_entries_around.ts | 0 .../use_fetch_log_entries_before.ts | 0 .../logs/log_summary/api/fetch_log_summary.ts | 0 .../logs/log_summary/bucket_size.ts | 0 .../containers/logs/log_summary/index.ts | 0 .../logs/log_summary/log_summary.test.tsx | 0 .../logs/log_summary/log_summary.tsx | 2 +- .../logs/log_summary/with_summary.ts | 20 +- .../logs_shared/public/hooks/use_kibana.tsx | 71 +++++ .../public/hooks/use_log_view.ts | 0 x-pack/plugins/logs_shared/public/index.ts | 92 ++++++ x-pack/plugins/logs_shared/public/mocks.tsx | 16 + .../log_view_state/README.md | 0 .../log_view_state/index.ts | 0 .../log_view_state/src/index.ts | 0 .../log_view_state/src/notifications.ts | 0 .../log_view_state/src/state_machine.ts | 0 .../log_view_state/src/types.ts | 0 .../src/url_state_storage_service.ts | 0 .../xstate_helpers/README.md | 3 + .../xstate_helpers/index.ts | 8 + .../xstate_helpers/src/index.ts | 9 + .../src/notification_channel.ts | 41 +++ .../xstate_helpers/src/types.ts | 43 +++ x-pack/plugins/logs_shared/public/plugin.ts | 38 +++ .../public/services/log_views/index.ts | 0 .../log_views/log_views_client.mock.ts | 0 .../services/log_views/log_views_client.ts | 0 .../log_views/log_views_service.mock.ts | 0 .../services/log_views/log_views_service.ts | 14 +- .../public/services/log_views/types.ts | 5 +- .../logs_shared/public/test_utils/entries.ts | 75 +++++ .../test_utils/use_global_storybook_theme.tsx | 59 ++++ x-pack/plugins/logs_shared/public/types.ts | 57 ++++ .../utils/data_search/data_search.stories.mdx | 152 +++++++++ .../flatten_data_search_response.ts | 30 ++ .../public/utils/data_search/index.ts | 13 + .../normalize_data_search_responses.ts | 81 +++++ .../public/utils/data_search/types.ts | 50 +++ .../use_data_search_request.test.tsx | 198 ++++++++++++ .../data_search/use_data_search_request.ts | 104 ++++++ .../use_data_search_response_state.ts | 36 +++ ...test_partial_data_search_response.test.tsx | 121 +++++++ ...use_latest_partial_data_search_response.ts | 43 +++ .../logs_shared/public/utils/datemath.ts | 293 +++++++++++++++++ .../logs_shared/public/utils/dev_mode.ts | 12 + .../logs_shared/public/utils/handlers.ts | 25 ++ .../utils/log_column_render_configuration.tsx | 64 ++++ .../public/utils/log_entry/index.ts | 0 .../public/utils/log_entry/log_entry.ts | 0 .../utils/log_entry/log_entry_highlight.ts | 0 .../public/utils/styles.ts | 0 .../public/utils/typed_react.tsx} | 10 +- .../public/utils/use_kibana_query_settings.ts | 31 ++ .../public/utils/use_kibana_ui_setting.ts | 53 ++++ .../public/utils/use_observable.ts | 152 +++++++++ .../public/utils/use_tracked_promise.ts | 299 ++++++++++++++++++ .../public/utils/use_visibility_state.ts | 26 ++ x-pack/plugins/logs_shared/server/index.ts | 21 ++ .../lib/adapters/framework/adapter_types.ts | 96 ++++++ .../server/lib/adapters/framework/index.ts | 8 + .../framework/kibana_framework_adapter.ts | 179 +++++++++++ .../log_entries/kibana_log_entries_adapter.ts | 10 +- .../lib/domains/log_entries_domain/index.ts | 0 .../log_entries_domain.mock.ts | 19 ++ .../log_entries_domain/log_entries_domain.ts | 62 +++- .../queries/log_entry_datasets.ts | 2 - .../server/lib/logs_shared_types.ts | 24 ++ .../logs_shared/server/logs_shared_server.ts | 21 ++ x-pack/plugins/logs_shared/server/mocks.ts | 35 ++ x-pack/plugins/logs_shared/server/plugin.ts | 98 ++++++ .../server/routes/log_entries/highlights.ts | 4 +- .../server/routes/log_entries/index.ts | 0 .../server/routes/log_entries/summary.ts | 15 +- .../routes/log_entries/summary_highlights.ts | 4 +- .../server/routes/log_views/get_log_view.ts | 4 +- .../server/routes/log_views/index.ts | 4 +- .../server/routes/log_views/put_log_view.ts | 4 +- .../logs_shared/server/saved_objects/index.ts | 8 + .../server/saved_objects/log_view/index.ts | 0 .../log_view/log_view_saved_object.ts | 2 +- .../log_view/references/index.ts | 0 .../log_view/references/log_indices.ts | 12 +- .../server/saved_objects/log_view/types.ts | 2 + .../server/saved_objects/references.test.ts | 121 +++++++ .../server/saved_objects/references.ts | 78 +++++ .../server/services/log_entries/index.ts | 0 .../log_entries_search_strategy.test.ts | 0 .../log_entries_search_strategy.ts | 0 .../log_entries/log_entries_service.ts | 0 .../log_entry_search_strategy.test.ts | 0 .../log_entries/log_entry_search_strategy.ts | 0 .../builtin_rules/filebeat_apache2.test.ts | 0 .../message/builtin_rules/filebeat_apache2.ts | 0 .../builtin_rules/filebeat_auditd.test.ts | 0 .../message/builtin_rules/filebeat_auditd.ts | 0 .../builtin_rules/filebeat_haproxy.test.ts | 0 .../message/builtin_rules/filebeat_haproxy.ts | 0 .../builtin_rules/filebeat_icinga.test.ts | 0 .../message/builtin_rules/filebeat_icinga.ts | 0 .../builtin_rules/filebeat_iis.test.ts | 0 .../message/builtin_rules/filebeat_iis.ts | 0 .../builtin_rules/filebeat_kafka.test.ts | 0 .../builtin_rules/filebeat_logstash.test.ts | 0 .../builtin_rules/filebeat_logstash.ts | 0 .../builtin_rules/filebeat_mongodb.test.ts | 0 .../message/builtin_rules/filebeat_mongodb.ts | 0 .../builtin_rules/filebeat_mysql.test.ts | 0 .../message/builtin_rules/filebeat_mysql.ts | 0 .../builtin_rules/filebeat_nginx.test.ts | 0 .../message/builtin_rules/filebeat_nginx.ts | 0 .../builtin_rules/filebeat_osquery.test.ts | 0 .../message/builtin_rules/filebeat_osquery.ts | 0 .../message/builtin_rules/filebeat_redis.ts | 0 .../message/builtin_rules/filebeat_system.ts | 0 .../builtin_rules/filebeat_traefik.test.ts | 0 .../message/builtin_rules/filebeat_traefik.ts | 0 .../message/builtin_rules/generic.test.ts | 0 .../message/builtin_rules/generic.ts | 0 .../builtin_rules/generic_webserver.ts | 0 .../message/builtin_rules/helpers.ts | 0 .../message/builtin_rules/index.ts | 0 .../services/log_entries/message/index.ts | 0 .../services/log_entries/message/message.ts | 0 .../log_entries/message/rule_types.ts | 0 .../services/log_entries/queries/common.ts | 0 .../log_entries/queries/log_entries.ts | 0 .../services/log_entries/queries/log_entry.ts | 0 .../server/services/log_entries/types.ts | 0 .../server/services/log_views/errors.ts | 9 + .../server/services/log_views/index.ts | 0 .../log_views/log_views_client.mock.ts | 0 .../log_views/log_views_client.test.ts | 52 +-- .../services/log_views/log_views_client.ts | 51 +-- .../log_views/log_views_service.mock.ts | 2 + .../services/log_views/log_views_service.ts | 33 +- .../server/services/log_views/types.ts | 13 +- x-pack/plugins/logs_shared/server/types.ts | 48 +++ .../utils/elasticsearch_runtime_types.ts | 41 +++ .../server/utils/serialized_query.ts | 30 ++ .../server/utils/typed_search_strategy.ts | 0 x-pack/plugins/logs_shared/tsconfig.json | 31 ++ x-pack/plugins/monitoring/kibana.jsonc | 1 + ...{init_infra_source.ts => init_log_view.ts} | 8 +- .../collection/get_collection_status.test.ts | 2 + x-pack/plugins/monitoring/server/plugin.ts | 4 +- x-pack/plugins/monitoring/server/types.ts | 2 + x-pack/plugins/monitoring/tsconfig.json | 1 + .../translations/translations/fr-FR.json | 82 ++--- .../translations/translations/ja-JP.json | 82 ++--- .../translations/translations/zh-CN.json | 82 ++--- x-pack/plugins/upgrade_assistant/kibana.jsonc | 3 +- .../upgrade_assistant/server/plugin.ts | 8 +- .../plugins/upgrade_assistant/tsconfig.json | 2 +- .../api_integration/apis/logs_ui/log_views.ts | 4 +- .../apis/metrics_ui/log_entry_highlights.ts | 2 +- .../apis/metrics_ui/log_summary.ts | 2 +- .../test/common/services/infra_log_views.ts | 4 +- x-pack/test/tsconfig.json | 1 + yarn.lock | 4 + 391 files changed, 4955 insertions(+), 836 deletions(-) rename x-pack/plugins/infra/common/{log_views => }/url_state_storage_service.ts (90%) delete mode 100644 x-pack/plugins/infra/public/hooks/use_log_view.mock.ts create mode 100644 x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts create mode 100644 x-pack/plugins/infra/server/utils/map_source_to_log_view.ts create mode 100755 x-pack/plugins/logs_shared/README.md create mode 100644 x-pack/plugins/logs_shared/common/constants.ts create mode 100644 x-pack/plugins/logs_shared/common/dynamic.tsx create mode 100644 x-pack/plugins/logs_shared/common/formatters/datetime.ts create mode 100644 x-pack/plugins/logs_shared/common/http_api/index.ts create mode 100644 x-pack/plugins/logs_shared/common/http_api/latest.ts rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/summary.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/summary_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/common.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/get_log_view.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/put_log_view.ts (100%) create mode 100644 x-pack/plugins/logs_shared/common/index.ts rename x-pack/plugins/{infra => logs_shared}/common/log_entry/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_entry/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_entry/log_entry_cursor.ts (100%) create mode 100644 x-pack/plugins/logs_shared/common/log_text_scale/index.ts create mode 100644 x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts rename x-pack/plugins/{infra => logs_shared}/common/log_views/defaults.ts (82%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/errors.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/index.ts (89%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/log_view.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/resolved_log_view.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/resolved_log_view.ts (91%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/types.ts (96%) create mode 100644 x-pack/plugins/logs_shared/common/mocks.ts create mode 100644 x-pack/plugins/logs_shared/common/runtime_types.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts create mode 100644 x-pack/plugins/logs_shared/common/time/index.ts create mode 100644 x-pack/plugins/logs_shared/common/time/time_key.ts create mode 100644 x-pack/plugins/logs_shared/common/typed_json.ts create mode 100644 x-pack/plugins/logs_shared/jest.config.js create mode 100644 x-pack/plugins/logs_shared/kibana.jsonc create mode 100644 x-pack/plugins/logs_shared/public/components/auto_sizer.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/centered_flyout_body.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_error_callout.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_error_callout.tsx (92%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_progress.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_progress.tsx (93%) create mode 100644 x-pack/plugins/logs_shared/public/components/empty_states/index.tsx create mode 100644 x-pack/plugins/logs_shared/public/components/empty_states/no_data.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/formatted_time.tsx (100%) create mode 100644 x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx create mode 100644 x-pack/plugins/logs_shared/public/components/loading/index.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.stories.mdx (91%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.story_decorators.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream_error_boundary.tsx (93%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/index.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx (90%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx (90%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_flyout.tsx (91%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/column_headers.tsx (96%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/field_value.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/highlighting.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/index.ts (79%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/item.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/jump_to_tail.tsx (93%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/loading_item_view.tsx (89%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_date_row.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_context_menu.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_field_column.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_field_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_message_column.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_message_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_row.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_text_separator.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/measurable_item_view.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx (95%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/text_styles.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/vertical_scroll_panel.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/resettable_error_boundary.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_entry_highlights.tsx (98%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_highlights.tsx (96%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_summary_highlights.ts (97%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/next_and_previous.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_position/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_position/use_log_position.ts (80%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_after.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_around.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_before.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/api/fetch_log_summary.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/bucket_size.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/log_summary.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/log_summary.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/with_summary.ts (66%) create mode 100644 x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx rename x-pack/plugins/{infra => logs_shared}/public/hooks/use_log_view.ts (100%) create mode 100644 x-pack/plugins/logs_shared/public/index.ts create mode 100644 x-pack/plugins/logs_shared/public/mocks.tsx rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/README.md (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/notifications.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/state_machine.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/url_state_storage_service.ts (100%) create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts create mode 100644 x-pack/plugins/logs_shared/public/plugin.ts rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_client.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_client.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_service.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_service.ts (61%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/types.ts (90%) create mode 100644 x-pack/plugins/logs_shared/public/test_utils/entries.ts create mode 100644 x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx create mode 100644 x-pack/plugins/logs_shared/public/types.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/index.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/types.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/datemath.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/dev_mode.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/handlers.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/log_entry_highlight.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/styles.ts (100%) rename x-pack/plugins/{infra/public/components/log_stream/lazy_log_stream_wrapper.tsx => logs_shared/public/utils/typed_react.tsx} (50%) create mode 100644 x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_observable.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts create mode 100644 x-pack/plugins/logs_shared/server/index.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts rename x-pack/plugins/{infra => logs_shared}/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts (96%) rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/index.ts (100%) create mode 100644 x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/log_entries_domain.ts (84%) rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts (96%) create mode 100644 x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts create mode 100644 x-pack/plugins/logs_shared/server/logs_shared_server.ts create mode 100644 x-pack/plugins/logs_shared/server/mocks.ts create mode 100644 x-pack/plugins/logs_shared/server/plugin.ts rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/highlights.ts (96%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/summary.ts (83%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/summary_highlights.ts (95%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/get_log_view.ts (92%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/index.ts (82%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/put_log_view.ts (93%) create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/index.ts rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/log_view_saved_object.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/references/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/references/log_indices.ts (85%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/types.ts (95%) create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/references.test.ts create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/references.ts rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_search_strategy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_search_strategy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_service.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entry_search_strategy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entry_search_strategy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_iis.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_redis.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_system.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic_webserver.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/helpers.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/message.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/rule_types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/common.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/log_entries.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/errors.ts (65%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.test.ts (88%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.ts (77%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_service.mock.ts (90%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_service.ts (65%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/types.ts (81%) create mode 100644 x-pack/plugins/logs_shared/server/types.ts create mode 100644 x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts create mode 100644 x-pack/plugins/logs_shared/server/utils/serialized_query.ts rename x-pack/plugins/{infra => logs_shared}/server/utils/typed_search_strategy.ts (100%) create mode 100644 x-pack/plugins/logs_shared/tsconfig.json rename x-pack/plugins/monitoring/server/lib/logs/{init_infra_source.ts => init_log_view.ts} (74%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9f41080bd5a59f..4248bd86c7d5b5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -468,6 +468,7 @@ examples/locator_examples @elastic/kibana-app-services examples/locator_explorer @elastic/kibana-app-services packages/kbn-logging @elastic/kibana-core packages/kbn-logging-mocks @elastic/kibana-core +x-pack/plugins/logs_shared @elastic/infra-monitoring-ui x-pack/plugins/logstash @elastic/logstash packages/kbn-managed-vscode-config @elastic/kibana-operations packages/kbn-managed-vscode-config-cli @elastic/kibana-operations diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 919703efff78f2..8e001dcd6fdc6f 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -628,6 +628,10 @@ the infrastructure monitoring use-case within Kibana. using the CURL scripts in the scripts folder. +|{kib-repo}blob/{branch}/x-pack/plugins/logs_shared/README.md[logsShared] +|Exposes the shared components and APIs to access and visualize logs. + + |{kib-repo}blob/{branch}/x-pack/plugins/logstash[logstash] |WARNING: Missing README. diff --git a/package.json b/package.json index 9a3366b65ee29d..7658626741ea1d 100644 --- a/package.json +++ b/package.json @@ -487,6 +487,7 @@ "@kbn/locator-explorer-plugin": "link:examples/locator_explorer", "@kbn/logging": "link:packages/kbn-logging", "@kbn/logging-mocks": "link:packages/kbn-logging-mocks", + "@kbn/logs-shared-plugin": "link:x-pack/plugins/logs_shared", "@kbn/logstash-plugin": "link:x-pack/plugins/logstash", "@kbn/management-cards-navigation": "link:packages/kbn-management/cards_navigation", "@kbn/management-plugin": "link:src/plugins/management", diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index eb7ca100c56f8b..c0a9f99b09d4c0 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -88,6 +88,7 @@ pageLoadAssetSize: licenseManagement: 41817 licensing: 29004 lists: 22900 + logsShared: 281060 logstash: 53548 management: 46112 maps: 90000 diff --git a/tsconfig.base.json b/tsconfig.base.json index 6db4864f58f05b..1f70f847156465 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -930,6 +930,8 @@ "@kbn/logging/*": ["packages/kbn-logging/*"], "@kbn/logging-mocks": ["packages/kbn-logging-mocks"], "@kbn/logging-mocks/*": ["packages/kbn-logging-mocks/*"], + "@kbn/logs-shared-plugin": ["x-pack/plugins/logs_shared"], + "@kbn/logs-shared-plugin/*": ["x-pack/plugins/logs_shared/*"], "@kbn/logstash-plugin": ["x-pack/plugins/logstash"], "@kbn/logstash-plugin/*": ["x-pack/plugins/logstash/*"], "@kbn/managed-vscode-config": ["packages/kbn-managed-vscode-config"], diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index eea7dced5e278f..2fa461531b4995 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -37,6 +37,7 @@ "xpack.idxMgmt": "plugins/index_management", "xpack.indexLifecycleMgmt": "plugins/index_lifecycle_management", "xpack.infra": "plugins/infra", + "xpack.logsShared": "plugins/logs_shared", "xpack.fleet": "plugins/fleet", "xpack.ingestPipelines": "plugins/ingest_pipelines", "xpack.kubernetesSecurity": "plugins/kubernetes_security", diff --git a/x-pack/plugins/apm/kibana.jsonc b/x-pack/plugins/apm/kibana.jsonc index ac33a0ee0b844b..0b248bbbe53f6d 100644 --- a/x-pack/plugins/apm/kibana.jsonc +++ b/x-pack/plugins/apm/kibana.jsonc @@ -15,6 +15,7 @@ "embeddable", "features", "infra", + "logsShared", "inspector", "licensing", "observability", diff --git a/x-pack/plugins/apm/public/components/app/service_logs/index.tsx b/x-pack/plugins/apm/public/components/app/service_logs/index.tsx index 83cf09b3e586e5..bde1749f33d35a 100644 --- a/x-pack/plugins/apm/public/components/app/service_logs/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_logs/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import moment from 'moment'; -import { LogStream } from '@kbn/infra-plugin/public'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { useFetcher } from '../../../hooks/use_fetcher'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx index 7e363d50ae666d..78e6a89d306205 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx @@ -7,7 +7,7 @@ import { EuiSpacer, EuiTab, EuiTabs, EuiSkeletonText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { LogStream } from '@kbn/infra-plugin/public'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import React, { useMemo } from 'react'; import { Transaction } from '../../../../../typings/es_schemas/ui/transaction'; import { TransactionMetadata } from '../../../shared/metadata_table/transaction_metadata'; diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json index 40526935236120..6947c8cfcd628c 100644 --- a/x-pack/plugins/apm/tsconfig.json +++ b/x-pack/plugins/apm/tsconfig.json @@ -92,6 +92,7 @@ "@kbn/dashboard-plugin", "@kbn/controls-plugin", "@kbn/core-http-server", + "@kbn/logs-shared-plugin", "@kbn/unified-field-list", "@kbn/slo-schema", "@kbn/discover-plugin" 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 2bc2fed33aa4fb..1e268aad1f73ca 100644 --- a/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts +++ b/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts @@ -11,7 +11,6 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; import type { FeaturesPluginStart } from '@kbn/features-plugin/public'; import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public'; -import type { InfraClientStartExports } from '@kbn/infra-plugin/public'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; @@ -24,7 +23,6 @@ export interface KibanaDeps { discover: DiscoverStart; features: FeaturesPluginStart; guidedOnboarding: GuidedOnboardingPluginStart; - infra: InfraClientStartExports; licensing: LicensingPluginStart; security: SecurityPluginStart; share: SharePluginStart; diff --git a/x-pack/plugins/enterprise_search/kibana.jsonc b/x-pack/plugins/enterprise_search/kibana.jsonc index 0a6d3ebee52aee..01e43542e84f75 100644 --- a/x-pack/plugins/enterprise_search/kibana.jsonc +++ b/x-pack/plugins/enterprise_search/kibana.jsonc @@ -17,7 +17,7 @@ "data", "discover", "charts", - "infra", + "logsShared", "cloud", "esUiShared", "guidedOnboarding", diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx index d655a7c57a9711..5f3af9a500b9b3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx @@ -7,17 +7,17 @@ import React from 'react'; -import { LogStream, LogStreamProps } from '@kbn/infra-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { LogStream, LogStreamProps } from '@kbn/logs-shared-plugin/public'; /* - * EnterpriseSearchLogStream is a light wrapper on top of infra's embeddable LogStream component. + * EnterpriseSearchLogStream is a light wrapper on top of logsShared's embeddable LogStream component. * It prepopulates our log source ID (set in server/plugin.ts) and sets a basic 24-hours-ago * default for timestamps. All other props get passed as-is to the underlying LogStream. * * Documentation links for reference: - * - https://github.com/elastic/kibana/blob/main/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx - * - Run `yarn storybook infra` for live docs + * - https://github.com/elastic/kibana/blob/main/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx + * - Run `yarn storybook logsShared` for live docs */ interface Props extends Omit { diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index b072fbdf515030..041a295ff4831d 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -21,7 +21,7 @@ import { DataPluginStart } from '@kbn/data-plugin/server/plugin'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/server'; import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server'; -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import { SpacesPluginStart } from '@kbn/spaces-plugin/server'; @@ -88,7 +88,7 @@ interface PluginsSetup { features: FeaturesPluginSetup; globalSearch: GlobalSearchPluginSetup; guidedOnboarding: GuidedOnboardingPluginSetup; - infra: InfraPluginSetup; + logsShared: LogsSharedPluginSetup; ml?: MlPluginSetup; security: SecurityPluginSetup; usageCollection?: UsageCollectionSetup; @@ -125,7 +125,7 @@ export class EnterpriseSearchPlugin implements Plugin { security, features, globalSearch, - infra, + logsShared, customIntegrations, ml, guidedOnboarding, @@ -261,9 +261,9 @@ export class EnterpriseSearchPlugin implements Plugin { /* * Register logs source configuration, used by LogStream components - * @see https://github.com/elastic/kibana/blob/main/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx#with-a-source-configuration + * @see https://github.com/elastic/kibana/blob/main/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx#with-a-source-configuration */ - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_RELEVANCE_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_RELEVANCE_LOGS_SOURCE_ID, { logIndices: { indexName: 'logs-app_search.search_relevance_suggestions-*', type: 'index_name', @@ -271,7 +271,7 @@ export class EnterpriseSearchPlugin implements Plugin { name: 'Enterprise Search Search Relevance Logs', }); - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_AUDIT_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_AUDIT_LOGS_SOURCE_ID, { logIndices: { indexName: 'logs-enterprise_search*', type: 'index_name', @@ -279,7 +279,7 @@ export class EnterpriseSearchPlugin implements Plugin { name: 'Enterprise Search Audit Logs', }); - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID, { logIndices: { indexName: 'behavioral_analytics-events-*', type: 'index_name', diff --git a/x-pack/plugins/enterprise_search/tsconfig.json b/x-pack/plugins/enterprise_search/tsconfig.json index f8407385478f5b..39758cb5111031 100644 --- a/x-pack/plugins/enterprise_search/tsconfig.json +++ b/x-pack/plugins/enterprise_search/tsconfig.json @@ -22,7 +22,6 @@ "@kbn/usage-collection-plugin", "@kbn/cloud-plugin", "@kbn/cloud-chat-plugin", - "@kbn/infra-plugin", "@kbn/features-plugin", "@kbn/lens-plugin", "@kbn/licensing-plugin", @@ -60,6 +59,7 @@ "@kbn/core-elasticsearch-server-mocks", "@kbn/shared-ux-link-redirect-app", "@kbn/global-search-plugin", + "@kbn/logs-shared-plugin", "@kbn/share-plugin", "@kbn/core-saved-objects-migration-server-internal", ] diff --git a/x-pack/plugins/fleet/kibana.jsonc b/x-pack/plugins/fleet/kibana.jsonc index f86c9394564454..f0b01080db22dd 100644 --- a/x-pack/plugins/fleet/kibana.jsonc +++ b/x-pack/plugins/fleet/kibana.jsonc @@ -40,7 +40,7 @@ "kibanaReact", "cloudChat", "esUiShared", - "infra", + "logsShared", "kibanaUtils", "usageCollection", "unifiedSearch" diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx index 4af6b30c99fb4c..e6dae29cea8817 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx @@ -30,7 +30,7 @@ import semverCoerce from 'semver/functions/coerce'; import { createStateContainerReactHelpers } from '@kbn/kibana-utils-plugin/public'; import { RedirectAppLinks } from '@kbn/kibana-react-plugin/public'; import type { TimeRange } from '@kbn/es-query'; -import { LogStream, type LogStreamProps } from '@kbn/infra-plugin/public'; +import { LogStream, type LogStreamProps } from '@kbn/logs-shared-plugin/public'; import type { Agent, AgentPolicy } from '../../../../../types'; import { useLink, useStartServices } from '../../../../../hooks'; diff --git a/x-pack/plugins/fleet/tsconfig.json b/x-pack/plugins/fleet/tsconfig.json index dc858ff5029a85..4e8ec7de3fcc7d 100644 --- a/x-pack/plugins/fleet/tsconfig.json +++ b/x-pack/plugins/fleet/tsconfig.json @@ -42,7 +42,7 @@ "@kbn/cloud-chat-plugin", "@kbn/kibana-react-plugin", "@kbn/es-ui-shared-plugin", - "@kbn/infra-plugin", + "@kbn/logs-shared-plugin", "@kbn/kibana-utils-plugin", "@kbn/unified-search-plugin", "@kbn/storybook", diff --git a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts index 2eec5b035c7939..4f5b977dd3b827 100644 --- a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts +++ b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types'; export const LOG_DOCUMENT_COUNT_RULE_TYPE_ID = 'logs.alert.document.count'; diff --git a/x-pack/plugins/infra/common/http_api/index.ts b/x-pack/plugins/infra/common/http_api/index.ts index 9f63896dbca9fd..cfa4841d9aa576 100644 --- a/x-pack/plugins/infra/common/http_api/index.ts +++ b/x-pack/plugins/infra/common/http_api/index.ts @@ -20,6 +20,4 @@ export * as inventoryViewsV1 from './inventory_views/v1'; export * as logAlertsV1 from './log_alerts/v1'; export * as logAnalysisResultsV1 from './log_analysis/results/v1'; export * as logAnalysisValidationV1 from './log_analysis/validation/v1'; -export * as logEntriesV1 from './log_entries/v1'; -export * as logViewsV1 from './log_views/v1'; export * as metricsExplorerViewsV1 from './metrics_explorer_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/latest.ts b/x-pack/plugins/infra/common/http_api/latest.ts index 28cdf220f710ec..98787a2c581a24 100644 --- a/x-pack/plugins/infra/common/http_api/latest.ts +++ b/x-pack/plugins/infra/common/http_api/latest.ts @@ -9,6 +9,4 @@ export * from './inventory_views/v1'; export * from './log_alerts/v1'; export * from './log_analysis/results/v1'; export * from './log_analysis/validation/v1'; -export * from './log_entries/v1'; -export * from './log_views/v1'; export * from './metrics_explorer_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts b/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts index 5647b9d09bdccd..7f0424f0df53b4 100644 --- a/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts +++ b/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts @@ -6,6 +6,7 @@ */ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { ThresholdRT, countCriteriaRT, @@ -13,7 +14,6 @@ import { timeSizeRT, groupByRT, } from '../../../alerting/logs/log_threshold/types'; -import { persistedLogViewReferenceRT } from '../../../log_views'; export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts index 56ee97a4684629..35539620639904 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { timeRangeRT, routeTimingMetadataRT } from '../../../shared'; import { logEntryAnomalyRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts index 8de55d96ba3c05..c07007be051150 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts @@ -6,7 +6,7 @@ */ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts index 9e838174bb6a12..e84825b8c6835a 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, forbiddenErrorRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts index 6523559103fdca..e051e313d9b8e3 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts @@ -7,13 +7,13 @@ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, forbiddenErrorRT, timeRangeRT, routeTimingMetadataRT, } from '../../../shared'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH = '/api/infra/log_analysis/results/log_entry_category_datasets'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts index 00fff8aabf9d1a..fc6ece5d7b7f76 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts @@ -5,16 +5,14 @@ * 2.0. */ +import { logEntryContextRT, persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import * as rt from 'io-ts'; - -import { persistedLogViewReferenceRT } from '../../../../log_views'; import { badRequestErrorRT, forbiddenErrorRT, - timeRangeRT, routeTimingMetadataRT, + timeRangeRT, } from '../../../shared'; -import { logEntryContextRT } from '../../../../log_entry'; export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH = '/api/infra/log_analysis/results/log_entry_category_examples'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts index 8233962df6bfac..ebc78693f49836 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts @@ -6,7 +6,7 @@ */ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { logEntryExampleRT } from '../../../../log_analysis'; import { badRequestErrorRT, diff --git a/x-pack/plugins/infra/common/locators/helpers.ts b/x-pack/plugins/infra/common/locators/helpers.ts index 9ede09e7f1b1ab..b4258053a0c010 100644 --- a/x-pack/plugins/infra/common/locators/helpers.ts +++ b/x-pack/plugins/infra/common/locators/helpers.ts @@ -5,23 +5,25 @@ * 2.0. */ -import { flowRight } from 'lodash'; import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; -import { findInventoryFields } from '../inventory_models'; -import { MESSAGE_FIELD, TIMESTAMP_FIELD } from '../constants'; -import type { TimeRange } from '../time'; -import type { LogsLocatorParams } from './logs_locator'; -import type { InfraClientCoreSetup } from '../../public/types'; import { DEFAULT_LOG_VIEW, LogViewColumnConfiguration, LogViewReference, + ResolvedLogView, +} from '@kbn/logs-shared-plugin/common'; +import { flowRight } from 'lodash'; +import type { InfraClientCoreSetup } from '../../public/types'; +import { MESSAGE_FIELD, TIMESTAMP_FIELD } from '../constants'; +import { findInventoryFields } from '../inventory_models'; +import type { TimeRange } from '../time'; +import { replaceLogFilterInQueryString, replaceLogPositionInQueryString, replaceLogViewInQueryString, - ResolvedLogView, -} from '../log_views'; +} from '../url_state_storage_service'; +import type { LogsLocatorParams } from './logs_locator'; import type { NodeLogsLocatorParams } from './node_logs_locator'; interface LocationToDiscoverParams { @@ -59,9 +61,9 @@ export const getLocationToDiscover = async ({ filter, logView = DEFAULT_LOG_VIEW, }: LocationToDiscoverParams) => { - const [, plugins, pluginStart] = await core.getStartServices(); - const { discover } = plugins; - const { logViews } = pluginStart; + const [, plugins] = await core.getStartServices(); + const { discover, logsShared } = plugins; + const { logViews } = logsShared; const resolvedLogView = await logViews.client.getResolvedLogView(logView); const discoverParams: DiscoverAppLocatorParams = { diff --git a/x-pack/plugins/infra/common/locators/locators.test.ts b/x-pack/plugins/infra/common/locators/locators.test.ts index 5a4ea0047e2d71..c0573d942e7578 100644 --- a/x-pack/plugins/infra/common/locators/locators.test.ts +++ b/x-pack/plugins/infra/common/locators/locators.test.ts @@ -13,7 +13,7 @@ import type { NodeLogsLocatorParams } from './node_logs_locator'; import { coreMock } from '@kbn/core/public/mocks'; import { findInventoryFields } from '../inventory_models'; import moment from 'moment'; -import { DEFAULT_LOG_VIEW, LogViewReference } from '../log_views'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; const setupLogsLocator = async () => { const deps: LogsLocatorDependencies = { diff --git a/x-pack/plugins/infra/common/locators/logs_locator.ts b/x-pack/plugins/infra/common/locators/logs_locator.ts index f4e65634aa762c..ee9006f359e665 100644 --- a/x-pack/plugins/infra/common/locators/logs_locator.ts +++ b/x-pack/plugins/infra/common/locators/logs_locator.ts @@ -7,7 +7,7 @@ import type { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/public'; import { SerializableRecord } from '@kbn/utility-types'; -import type { LogViewReference } from '../log_views'; +import type { LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { TimeRange } from '../time'; import type { InfraClientCoreSetup } from '../../public/types'; diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts index f8daaa1b9227b3..c6b53abee7143a 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts @@ -6,14 +6,15 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import * as rt from 'io-ts'; import { logEntryAfterCursorRT, logEntryBeforeCursorRT, logEntryCursorRT, logEntryRT, -} from '../../log_entry'; -import { logViewColumnConfigurationRT, logViewReferenceRT } from '../../log_views'; + logViewColumnConfigurationRT, + logViewReferenceRT, +} from '@kbn/logs-shared-plugin/common'; +import * as rt from 'io-ts'; import { jsonObjectRT } from '../../typed_json'; import { searchStrategyErrorRT } from '../common/errors'; diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts index 6d2a7891264d19..131450d588c0f4 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts @@ -5,9 +5,12 @@ * 2.0. */ +import { + logEntryCursorRT, + logEntryFieldRT, + logViewReferenceRT, +} from '@kbn/logs-shared-plugin/common'; import * as rt from 'io-ts'; -import { logEntryCursorRT, logEntryFieldRT } from '../../log_entry'; -import { logViewReferenceRT } from '../../log_views'; import { searchStrategyErrorRT } from '../common/errors'; export const LOG_ENTRY_SEARCH_STRATEGY = 'infra-log-entry'; diff --git a/x-pack/plugins/infra/common/log_views/url_state_storage_service.ts b/x-pack/plugins/infra/common/url_state_storage_service.ts similarity index 90% rename from x-pack/plugins/infra/common/log_views/url_state_storage_service.ts rename to x-pack/plugins/infra/common/url_state_storage_service.ts index 973fcd53ca98c6..5d701ad1876bb0 100644 --- a/x-pack/plugins/infra/common/log_views/url_state_storage_service.ts +++ b/x-pack/plugins/infra/common/url_state_storage_service.ts @@ -10,15 +10,15 @@ import { encode } from '@kbn/rison'; import type { Query } from '@kbn/es-query'; import { parse, stringify } from 'query-string'; import moment, { DurationInputObject } from 'moment'; -import type { FilterStateInUrl } from '../../public/observability_logs/log_stream_query_state'; -import type { PositionStateInUrl } from '../../public/observability_logs/log_stream_position_state/src/url_state_storage_service'; import { defaultFilterStateKey, defaultPositionStateKey, DEFAULT_REFRESH_INTERVAL, LogViewReference, -} from '.'; -import type { TimeRange } from '../time'; +} from '@kbn/logs-shared-plugin/common'; +import type { FilterStateInUrl } from '../public/observability_logs/log_stream_query_state'; +import type { PositionStateInUrl } from '../public/observability_logs/log_stream_position_state/src/url_state_storage_service'; +import type { TimeRange } from './time'; export const defaultLogViewKey = 'logView'; diff --git a/x-pack/plugins/infra/kibana.jsonc b/x-pack/plugins/infra/kibana.jsonc index c9a9ca0e186743..973d979ed90aae 100644 --- a/x-pack/plugins/infra/kibana.jsonc +++ b/x-pack/plugins/infra/kibana.jsonc @@ -20,6 +20,7 @@ "features", "fieldFormats", "lens", + "logsShared", "observability", "observabilityShared", "ruleRegistry", diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx index b51c9beae3836e..a8acacd8debd13 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx @@ -52,7 +52,7 @@ export const ExplainLogRateSpikes: FC { const { services } = useKibanaContextForPlugin(); - const { dataViews, logViews } = services; + const { dataViews, logsShared } = services; const [dataView, setDataView] = useState(); const [esSearchQuery, setEsSearchQuery] = useState(); const [logSpikeParams, setLogSpikeParams] = useState< @@ -61,9 +61,8 @@ export const ExplainLogRateSpikes: FC { const getDataView = async () => { - const { timestampField, dataViewReference } = await logViews.client.getResolvedLogView( - rule.params.logView - ); + const { timestampField, dataViewReference } = + await logsShared.logViews.client.getResolvedLogView(rule.params.logView); if (dataViewReference.id) { const logDataView = await dataViews.get(dataViewReference.id); @@ -94,7 +93,7 @@ export const ExplainLogRateSpikes: FC import('./components/logs_history_chart')); @@ -44,7 +44,7 @@ const AlertDetailsAppSection = ({ alert, setAlertSummaryFields, }: AlertDetailsAppSectionProps) => { - const { observability, logViews } = useKibanaContextForPlugin().services; + const { observability, logsShared } = useKibanaContextForPlugin().services; const theme = useTheme(); const timeRange = getPaddedAlertTimeRange(alert.fields[ALERT_START]!, alert.fields[ALERT_END]); const alertEnd = alert.fields[ALERT_END] ? moment(alert.fields[ALERT_END]).valueOf() : undefined; @@ -66,7 +66,7 @@ const AlertDetailsAppSection = ({ const { derivedDataView } = useLogView({ initialLogViewReference: rule.params.logView, - logViews: logViews.client, + logViews: logsShared.logViews.client, }); const { hasAtLeast } = useLicense(); diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index df324169c98e0c..bb2dbc7afdc36b 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -9,7 +9,7 @@ import React, { useState, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiContextMenuItem, EuiContextMenuPanel, EuiHeaderLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useLogViewContext } from '../../../hooks/use_log_view'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { AlertFlyout } from './alert_flyout'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx index c5af2938f54567..33f63fe6a49c3a 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import type { PersistedLogViewReference, ResolvedLogViewField, -} from '../../../../../common/log_views'; +} from '@kbn/logs-shared-plugin/common'; import { Criterion } from './criterion'; import { PartialRuleParams, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx index 2e394bb093ec8a..f2bb1d8ed57854 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx @@ -22,12 +22,12 @@ import { i18n } from '@kbn/i18n'; import { isFinite, isNumber } from 'lodash'; import React, { useCallback, useMemo, useState } from 'react'; import type { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public'; +import type { ResolvedLogViewField } from '@kbn/logs-shared-plugin/common'; import { Comparator, ComparatorToi18nMap, Criterion as CriterionType, } from '../../../../../common/alerting/logs/log_threshold/types'; -import type { ResolvedLogViewField } from '../../../../../common/log_views'; const firstCriterionFieldPrefix = i18n.translate( 'xpack.infra.logs.alertFlyout.firstCriterionFieldPrefix', diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx index b8dbc56402b2b7..6b2357a4f4611f 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx @@ -21,9 +21,9 @@ import { } from '@elastic/charts'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getChartTheme } from '../../../../utils/get_chart_theme'; import { useIsDarkMode } from '../../../../hooks/use_is_dark_mode'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; import { ExecutionTimeRange } from '../../../../types'; import { ChartContainer, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index d9275a1ff01780..475bb0b1fbdef7 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -13,7 +13,8 @@ import { ForLastExpression, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { PersistedLogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; +import { LogViewProvider, useLogViewContext } from '@kbn/logs-shared-plugin/public'; +import { PersistedLogViewReference, ResolvedLogViewField } from '@kbn/logs-shared-plugin/common'; import { Comparator, isOptimizableGroupedThreshold, @@ -28,7 +29,6 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; import { ObjectEntries } from '../../../../../common/utility_types'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; -import { LogViewProvider, useLogViewContext } from '../../../../hooks/use_log_view'; import { GroupByExpression } from '../../../common/group_by_expression/group_by_expression'; import { errorsRT } from '../../validation'; import { Criteria } from './criteria'; @@ -95,7 +95,7 @@ export const ExpressionEditor: React.FC< > = (props) => { const isInternal = props.metadata?.isInternal ?? false; const { - services: { logViews }, + services: { logsShared }, } = useKibanaContextForPlugin(); // injected during alert registration return ( @@ -105,7 +105,7 @@ export const ExpressionEditor: React.FC< ) : ( - + diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx index d633a055c46efc..ad042d77a584cb 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx @@ -8,6 +8,7 @@ import { HttpHandler } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useMemo, useState } from 'react'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { isRatioRule } from '../../../../../../common/alerting/logs/log_threshold'; import { GetLogAlertsChartPreviewDataAlertParamsSubset, @@ -16,7 +17,6 @@ import { getLogAlertsChartPreviewDataSuccessResponsePayloadRT, LOG_ALERTS_CHART_PREVIEW_DATA_PATH, } from '../../../../../../common/http_api'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; import { decodeOrThrow } from '../../../../../../common/runtime_types'; import { ExecutionTimeRange } from '../../../../../types'; import { useTrackedPromise } from '../../../../../utils/use_tracked_promise'; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx index f3988002a7f7e4..8dfa7295b6769a 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFlexItem, EuiFlexGroup, EuiExpression, EuiToolTip } from '@elastic/eui'; -import { ResolvedLogView } from '../../../../../common/log_views'; +import { ResolvedLogView } from '@kbn/logs-shared-plugin/common'; const description = i18n.translate('xpack.infra.logs.alertFlyout.logViewDescription', { defaultMessage: 'Log View', diff --git a/x-pack/plugins/infra/public/apps/discover_app.tsx b/x-pack/plugins/infra/public/apps/discover_app.tsx index dd99a5e4dd6258..2ea704fa9b21f0 100644 --- a/x-pack/plugins/infra/public/apps/discover_app.tsx +++ b/x-pack/plugins/infra/public/apps/discover_app.tsx @@ -6,8 +6,8 @@ */ import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import type { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { getLogViewReferenceFromUrl } from '@kbn/logs-shared-plugin/public'; import type { InfraClientStartExports } from '../types'; -import { getLogViewReferenceFromUrl } from '../observability_logs/log_view_state'; export const renderApp = ( core: CoreStart, diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts index 6212c256647efc..35549673701fcd 100644 --- a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts @@ -11,11 +11,11 @@ import type { IKibanaSearchResponse, ISearchOptions, } from '@kbn/data-plugin/public'; +import { defaultLogViewAttributes } from '@kbn/logs-shared-plugin/common'; import { type LogEntriesSearchResponsePayload, LOG_ENTRIES_SEARCH_STRATEGY, } from '../../../../../../common/search_strategies/log_entries/log_entries'; -import { defaultLogViewAttributes } from '../../../../../../common/log_views'; import { generateFakeEntries } from '../../../../../test_utils/entries'; export const getLogEntries = ({ params }: IKibanaSearchRequest, options?: ISearchOptions) => { diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx index d928eda5a21379..d2311b91fa1b2e 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx @@ -11,10 +11,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; -import { DEFAULT_LOG_VIEW, LogViewReference } from '../../../../../common/log_views'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { InventoryItemType } from '../../../../../common/inventory_models/types'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; -import { LogStream } from '../../../log_stream'; import { findInventoryFields } from '../../../../../common/inventory_models'; import { InfraLoadingPanel } from '../../../loading'; diff --git a/x-pack/plugins/infra/public/components/asset_details/types.ts b/x-pack/plugins/infra/public/components/asset_details/types.ts index c42953ab8fb3ea..a3d519641da3a3 100644 --- a/x-pack/plugins/infra/public/components/asset_details/types.ts +++ b/x-pack/plugins/infra/public/components/asset_details/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { LogViewReference } from '../../../common/log_views'; +import { LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { InventoryItemType } from '../../../common/inventory_models/types'; import type { InfraAssetMetricType, SnapshotCustomMetricInput } from '../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx b/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx index d2d59fe5193538..1986354b5e9bdd 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx +++ b/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx @@ -13,10 +13,10 @@ import { Subscription } from 'rxjs'; import type { TimeRange } from '@kbn/es-query'; import { Embeddable, EmbeddableInput, IContainer } from '@kbn/embeddable-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { CoreProviders } from '../../apps/common_providers'; import { InfraClientStartDeps, InfraClientStartExports } from '../../types'; import { datemathToEpochMillis } from '../../utils/datemath'; -import { LazyLogStreamWrapper } from './lazy_log_stream_wrapper'; export const LOG_STREAM_EMBEDDABLE = 'LOG_STREAM_EMBEDDABLE'; @@ -90,7 +90,7 @@ export class LogStreamEmbeddable extends Embeddable { >
- void; diff --git a/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx b/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx index e60a606ce0ce39..6533bebf74fc64 100644 --- a/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import classNames from 'classnames'; import * as React from 'react'; -import { LogEntryTime } from '../../../../common/log_entry'; +import { LogEntryTime } from '@kbn/logs-shared-plugin/common'; import { LogSearchButtons } from './log_search_buttons'; import { LogSearchInput } from './log_search_input'; diff --git a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts index 1ea8f71da129e7..8327a14c282563 100644 --- a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts +++ b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts @@ -7,8 +7,7 @@ import { useState } from 'react'; import createContainer from 'constate'; -import { LogViewReference } from '../../../../common/log_views'; -import { LogEntry } from '../../../../common/log_entry'; +import { LogEntry, LogViewReference } from '@kbn/logs-shared-plugin/common'; interface ViewLogInContextProps { logViewReference: LogViewReference; diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts deleted file mode 100644 index 3d95dfb72abb07..00000000000000 --- a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts +++ /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 { interpret } from 'xstate'; -import { createLogViewMock } from '../../common/log_views/log_view.mock'; -import { createResolvedLogViewMockFromAttributes } from '../../common/log_views/resolved_log_view.mock'; -import { - createLogViewNotificationChannel, - createPureLogViewStateMachine, -} from '../observability_logs/log_view_state/src'; -import { useLogView } from './use_log_view'; - -type UseLogView = typeof useLogView; -type IUseLogView = ReturnType; - -const defaultLogViewId = 'default'; - -export const createUninitializedUseLogViewMock = - (logViewId: string = defaultLogViewId) => - (): IUseLogView => ({ - derivedDataView: undefined, - hasFailedLoading: false, - hasFailedLoadingLogView: false, - hasFailedLoadingLogViewStatus: false, - hasFailedResolvingLogView: false, - isLoading: false, - isLoadingLogView: false, - isLoadingLogViewStatus: false, - isResolvingLogView: false, - isUninitialized: true, - latestLoadLogViewFailures: [], - load: jest.fn(), - retry: jest.fn(), - logView: undefined, - logViewReference: { type: 'log-view-reference', logViewId }, - logViewStatus: undefined, - resolvedLogView: undefined, - update: jest.fn(), - changeLogViewReference: jest.fn(), - revertToDefaultLogView: jest.fn(), - logViewStateService: interpret( - createPureLogViewStateMachine({ logViewReference: { type: 'log-view-reference', logViewId } }) - ), - logViewStateNotifications: createLogViewNotificationChannel(), - isPersistedLogView: false, - isInlineLogView: false, - }); - -export const createLoadingUseLogViewMock = - (logViewId: string = defaultLogViewId) => - (): IUseLogView => ({ - ...createUninitializedUseLogViewMock(logViewId)(), - isLoading: true, - isLoadingLogView: true, - isLoadingLogViewStatus: true, - isResolvingLogView: true, - }); - -export const createLoadedUseLogViewMock = async (logViewId: string = defaultLogViewId) => { - const logView = createLogViewMock(logViewId); - const resolvedLogView = await createResolvedLogViewMockFromAttributes(logView.attributes); - - return (): IUseLogView => { - return { - ...createUninitializedUseLogViewMock(logViewId)(), - logView, - resolvedLogView, - logViewStatus: { - index: 'available', - }, - }; - }; -}; diff --git a/x-pack/plugins/infra/public/index.ts b/x-pack/plugins/infra/public/index.ts index 4bd094b3d79f4e..49a0257a22b386 100644 --- a/x-pack/plugins/infra/public/index.ts +++ b/x-pack/plugins/infra/public/index.ts @@ -29,6 +29,4 @@ export { InfraFormatterType } from './lib/lib'; export type InfraAppId = 'logs' | 'metrics'; // Shared components -export { LazyLogStreamWrapper as LogStream } from './components/log_stream/lazy_log_stream_wrapper'; -export type { LogStreamProps } from './components/log_stream'; export type { InfraClientStartExports } from './types'; diff --git a/x-pack/plugins/infra/public/mocks.tsx b/x-pack/plugins/infra/public/mocks.tsx index d977e13ddd9807..9b232c515ce812 100644 --- a/x-pack/plugins/infra/public/mocks.tsx +++ b/x-pack/plugins/infra/public/mocks.tsx @@ -8,14 +8,12 @@ import React from 'react'; import { createLocatorMock } from '../common/locators/locators.mock'; import { createInventoryViewsServiceStartMock } from './services/inventory_views/inventory_views_service.mock'; -import { createLogViewsServiceStartMock } from './services/log_views/log_views_service.mock'; import { createMetricsExplorerViewsServiceStartMock } from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; import { createTelemetryServiceMock } from './services/telemetry/telemetry_service.mock'; import { InfraClientStartExports } from './types'; export const createInfraPluginStartMock = () => ({ inventoryViews: createInventoryViewsServiceStartMock(), - logViews: createLogViewsServiceStartMock(), metricsExplorerViews: createMetricsExplorerViewsServiceStartMock(), telemetry: createTelemetryServiceMock(), locators: createLocatorMock(), diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts index b7c02e916dc57a..d2a71c65702ebb 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts @@ -8,7 +8,8 @@ import { RefreshInterval } from '@kbn/data-plugin/public'; import { TimeRange } from '@kbn/es-query'; import { actions, ActorRefFrom, createMachine, EmittedFrom } from 'xstate'; -import { DEFAULT_REFRESH_INTERVAL } from '../../../../../common/log_views'; +import { DEFAULT_REFRESH_INTERVAL } from '@kbn/logs-shared-plugin/common'; +import type { LogViewNotificationChannel } from '@kbn/logs-shared-plugin/public'; import { datemathToEpochMillis } from '../../../../utils/datemath'; import { createLogStreamPositionStateMachine } from '../../../log_stream_position_state/src/state_machine'; import { @@ -16,7 +17,6 @@ import { DEFAULT_TIMERANGE, LogStreamQueryStateMachineDependencies, } from '../../../log_stream_query_state'; -import type { LogViewNotificationChannel } from '../../../log_view_state'; import { OmitDeprecatedState } from '../../../xstate_helpers'; import { waitForInitialQueryParameters, diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts index eb42dccdf2486c..12c707ebb91fd4 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts @@ -6,8 +6,13 @@ */ import { TimeRange } from '@kbn/es-query'; +import type { LogViewStatus } from '@kbn/logs-shared-plugin/common'; +import type { + LogViewContextWithError, + LogViewContextWithResolvedLogView, + LogViewNotificationEvent, +} from '@kbn/logs-shared-plugin/public'; import { TimeKey } from '../../../../../common/time'; -import type { LogViewStatus } from '../../../../../common/log_views'; import { JumpToTargetPositionEvent, LogStreamPositionContext, @@ -22,11 +27,6 @@ import { UpdateTimeRangeEvent, } from '../../../log_stream_query_state'; import { LogStreamQueryNotificationEvent } from '../../../log_stream_query_state/src/notifications'; -import type { - LogViewContextWithError, - LogViewContextWithResolvedLogView, - LogViewNotificationEvent, -} from '../../../log_view_state'; export interface ReceivedInitialQueryParametersEvent { type: 'RECEIVED_INITIAL_QUERY_PARAMETERS'; diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts index 5607bf92070547..c98ab9e1474441 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts @@ -10,6 +10,7 @@ import { IKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugi import * as Either from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/function'; import { InvokeCreator } from 'xstate'; +import { replaceStateKeyInQueryString } from '../../../../common/url_state_storage_service'; import { minimalTimeKeyRT, pickTimeKey } from '../../../../common/time'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; import type { LogStreamPositionContext, LogStreamPositionEvent } from './types'; @@ -97,3 +98,13 @@ export type PositionStateInUrl = rt.TypeOf; const decodePositionQueryValueFromUrl = (queryValueFromUrl: unknown) => { return positionStateInUrlRT.decode(queryValueFromUrl); }; + +export const replaceLogPositionInQueryString = (time?: number) => + Number.isNaN(time) || time == null + ? (value: string) => value + : replaceStateKeyInQueryString(defaultPositionStateKey, { + position: { + time, + tiebreaker: 0, + }, + }); diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts index 1a69642037d197..1c0de464121c80 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts @@ -14,7 +14,7 @@ import type { import { EsQueryConfig } from '@kbn/es-query'; import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { actions, ActorRefFrom, createMachine, SpecialTargets, send } from 'xstate'; -import { DEFAULT_REFRESH_INTERVAL } from '../../../../common/log_views'; +import { DEFAULT_REFRESH_INTERVAL } from '@kbn/logs-shared-plugin/common'; import { OmitDeprecatedState, sendIfDefined } from '../../xstate_helpers'; import { logStreamQueryNotificationEventSelectors } from './notifications'; import { diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts index 448fb941e037c3..fb65fcd987a112 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts @@ -16,9 +16,11 @@ import { defaultFilterStateKey, defaultPositionStateKey, DEFAULT_REFRESH_INTERVAL, - getTimeRangeStartFromTime, +} from '@kbn/logs-shared-plugin/common'; +import { getTimeRangeEndFromTime, -} from '../../../../common/log_views'; + getTimeRangeStartFromTime, +} from '../../../../common/url_state_storage_service'; import { minimalTimeKeyRT } from '../../../../common/time'; import { datemathStringRT } from '../../../utils/datemath'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx index 78f1c5f15dee96..5a40bd5d322920 100644 --- a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx @@ -7,7 +7,7 @@ import { EuiButton } from '@elastic/eui'; import React, { useCallback } from 'react'; -import { useLogViewContext } from '../../../hooks/use_log_view'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; export const StateMachinePlayground = () => { const { changeLogViewReference, revertToDefaultLogView, update, isLoading, logViewStateService } = diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx index 3bbe00c5314cf4..663df4c0f4d1a6 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx @@ -7,7 +7,7 @@ import { useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; -import { DEFAULT_LOG_VIEW } from '../../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { getFilterFromLocation, getTimeFromLocation } from './query_params'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 66898bf38b4b47..e3382d43c0e15d 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -7,7 +7,7 @@ import { useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; -import { DEFAULT_LOG_VIEW } from '../../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { InventoryItemType } from '../../../common/inventory_models/types'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx index bde85aa99ec7fc..d6a1e9f2ddc5e3 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect } from 'react'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -22,7 +23,6 @@ import { import { SubscriptionSplashPage } from '../../../components/subscription_splash_content'; import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { LogEntryCategoriesResultsContent } from './page_results_content'; import { LogEntryCategoriesSetupContent } from './page_setup_content'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 6e1d3f4a4f0bdc..5cb6a12166c537 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -6,12 +6,12 @@ */ import React from 'react'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx index f26f8768a44591..e1e317136deedd 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx @@ -15,6 +15,7 @@ import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { MLJobsAwaitingNodeWarning, ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { TimeRange } from '../../../../common/time/time_range'; import { CategoryJobNoticesSection } from '../../../components/logging/log_analysis_job_status'; import { AnalyzeInMlButton } from '../../../components/logging/log_analysis_results'; @@ -24,7 +25,6 @@ import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_ import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { PageViewLogInContext } from '../stream/page_view_log_in_context'; import { TopCategoriesSection } from './sections/top_categories'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx index dbf143f95d0bc6..34cced7d92ffd9 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect } from 'react'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { useLogEntryCategoryExamples } from '../../use_log_entry_category_examples'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; import { TimeRange } from '../../../../../../common/time/time_range'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx index 96c0a23ac755e8..0811ec1708530b 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx @@ -5,28 +5,27 @@ * 2.0. */ -import React, { useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; +import { LogEntry, LogEntryContext } from '@kbn/logs-shared-plugin/common'; +import { + LogEntryColumn, + LogEntryContextMenu, + LogEntryFieldColumn, + LogEntryMessageColumn, + LogEntryRowWrapper, + LogEntryTimestampColumn, +} from '@kbn/logs-shared-plugin/public'; +import { useLinkProps, useUiTracker } from '@kbn/observability-shared-plugin/public'; import { encode } from '@kbn/rison'; import moment from 'moment'; - -import { useUiTracker, useLinkProps } from '@kbn/observability-shared-plugin/public'; -import { LogEntry, LogEntryContext } from '../../../../../../common/log_entry'; -import { TimeRange } from '../../../../../../common/time'; +import React, { useCallback, useState } from 'react'; import { getFriendlyNameForPartitionId, partitionField, } from '../../../../../../common/log_analysis'; +import { TimeRange } from '../../../../../../common/time'; import { useViewLogInProviderContext } from '../../../../../containers/logs/view_log_in_context'; -import { - LogEntryColumn, - LogEntryFieldColumn, - LogEntryMessageColumn, - LogEntryRowWrapper, - LogEntryTimestampColumn, -} from '../../../../../components/logging/log_text_stream'; import { LogColumnConfiguration } from '../../../../../utils/source_configuration'; -import { LogEntryContextMenu } from '../../../../../components/logging/log_text_stream/log_entry_context_menu'; export const exampleMessageScale = 'medium' as const; export const exampleTimestampFormat = 'dateTime' as const; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx index c9f93ee618ddb9..6dd07a80c8652e 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx @@ -9,7 +9,7 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategory } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time'; import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx index 3d06a212fe5813..f119a08cbd10a2 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx @@ -12,7 +12,7 @@ import React, { useMemo, useCallback } from 'react'; import useSet from 'react-use/lib/useSet'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategory, LogEntryCategoryDataset, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts index db17c0b866b7b7..14e7ebfbebd35d 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoryDatasetsRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts index a27e734235c3b5..3e4947ca1e84ff 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoryExamplesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts index 5104ad897c8806..c4a1b6d095a291 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoriesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts index 7ef8d57b29d9fb..20f7adb106857e 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts @@ -7,7 +7,7 @@ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { GetLogEntryCategoriesSuccessResponsePayload, GetLogEntryCategoryDatasetsSuccessResponsePayload, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx index 8152cae426448f..c5516fdbc02f92 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx @@ -6,7 +6,7 @@ */ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategoryExample } from '../../../../common/http_api'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx index 1f6fe04e59161d..533381dcbf7c33 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { memo, useCallback, useEffect } from 'react'; import useInterval from 'react-use/lib/useInterval'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -24,7 +25,6 @@ import { SubscriptionSplashPage } from '../../../components/subscription_splash_ import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogEntryRateModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { LogEntryRateResultsContent } from './page_results_content'; import { LogEntryRateSetupContent } from './page_setup_content'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 7e1381cbd4f214..46ce90cff63cc3 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; @@ -13,7 +14,6 @@ import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_a import { LogEntryRateModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx index b535c1fd155de7..a4d861e38ade18 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx @@ -14,6 +14,7 @@ import { encode } from '@kbn/rison'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { MLJobsAwaitingNodeWarning } from '@kbn/ml-plugin/public'; import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext, LogEntryFlyout } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { TimeKey } from '../../../../common/time'; import { @@ -23,12 +24,10 @@ import { import { DatasetsSelector } from '../../../components/logging/log_analysis_results/datasets_selector'; import { ManageJobsButton } from '../../../components/logging/log_analysis_setup/manage_jobs_button'; import { useLogAnalysisSetupFlyoutStateContext } from '../../../components/logging/log_analysis_setup/setup_flyout'; -import { LogEntryFlyout } from '../../../components/logging/log_entry_flyout'; import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis/log_analysis_capabilities'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogEntryRateModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { useLogEntryFlyoutContext } from '../../../containers/logs/log_flyout'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { AnomaliesResults } from './sections/anomalies'; import { useDatasetFiltering } from './use_dataset_filtering'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx index 493b5c4077c69c..5fe150e3c27240 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx @@ -11,10 +11,10 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import useMount from 'react-use/lib/useMount'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isCategoryAnomaly, LogEntryAnomaly } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; -import { useLogViewContext } from '../../../../../hooks/use_log_view'; import { useLogEntryExamples } from '../../use_log_entry_examples'; import { LogEntryExampleMessage, LogEntryExampleMessageHeaders } from './log_entry_example'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx index 5b23f5f9e2a459..288fc3df39c8e2 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx @@ -12,8 +12,6 @@ import { i18n } from '@kbn/i18n'; import { useMlHref, ML_PAGES } from '@kbn/ml-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useLinkProps, shouldHandleLinkEvent } from '@kbn/observability-shared-plugin/public'; -import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana'; -import { getFriendlyNameForPartitionId } from '../../../../../../common/log_analysis'; import { LogEntryColumn, LogEntryFieldColumn, @@ -23,11 +21,11 @@ import { LogEntryContextMenu, LogEntryColumnWidths, iconColumnId, -} from '../../../../../components/logging/log_text_stream'; -import { LogColumnHeadersWrapper, LogColumnHeader, -} from '../../../../../components/logging/log_text_stream/column_headers'; +} from '@kbn/logs-shared-plugin/public'; +import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana'; +import { getFriendlyNameForPartitionId } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { partitionField } from '../../../../../../common/log_analysis/job_parameters'; import { LogEntryExample, isCategoryAnomaly } from '../../../../../../common/log_analysis'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts index dc8ab4772473df..b6a515ae6f1349 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryAnomaliesRequestPayloadRT, getLogEntryAnomaliesSuccessReponsePayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts index 093a9060085829..a93712c5d5a86d 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { decodeOrThrow } from '../../../../../common/runtime_types'; import { getLogEntryAnomaliesDatasetsRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts index f6d90692ad4700..6cf35b95868e10 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryExamplesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts index db4fc779641736..745b5a7cd5aec7 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts @@ -7,7 +7,7 @@ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; import useMount from 'react-use/lib/useMount'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise'; import { callGetLogEntryAnomaliesAPI } from './service_calls/get_log_entry_anomalies'; import { callGetLogEntryAnomaliesDatasetsAPI } from './service_calls/get_log_entry_anomalies_datasets'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts index a678f5deaf07a7..4301f08ab41da0 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts @@ -6,7 +6,7 @@ */ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryExample } from '../../../../common/log_analysis'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx index e185a62ea96467..f4112b7bd0a05f 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx @@ -6,21 +6,21 @@ */ import React, { useState } from 'react'; -import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; -import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; -import { LogViewProvider } from '../../hooks/use_log_view'; import { + LogViewProvider, initializeFromUrl as createInitializeFromUrl, updateContextInUrl as createUpdateContextInUrl, listenForUrlChanges as createListenForUrlChanges, -} from '../../observability_logs/log_view_state/src/url_state_storage_service'; +} from '@kbn/logs-shared-plugin/public'; +import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context'; export const LogsPageProviders: React.FunctionComponent = ({ children }) => { const { services: { notifications: { toasts: toastsService }, - logViews: { client }, + logsShared, }, } = useKibanaContextForPlugin(); @@ -38,7 +38,7 @@ export const LogsPageProviders: React.FunctionComponent = ({ children }) => { return ( { return ( - + {({ buckets, start, end }) => ( )} - + ); }} @@ -293,6 +299,16 @@ export const StreamPageLogsContent = React.memo<{ ); }); +const WithSummaryAndQuery = (props: Omit) => { + const serializedParsedQuery = useSelector(useLogStreamPageStateContext(), (logStreamPageState) => + logStreamPageState.matches({ hasLogViewIndices: 'initialized' }) + ? stringify(logStreamPageState.context.parsedQuery) + : null + ); + + return ; +}; + type InitializedLogStreamPageState = MatchedStateFromActor< LogStreamPageActorRef, { hasLogViewIndices: 'initialized' } diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx index 0a9f5ae9395e3e..9b058bd03acd37 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx @@ -7,20 +7,21 @@ import stringify from 'json-stable-stringify'; import React, { useMemo } from 'react'; +import { + LogHighlightsStateProvider, + LogPositionStateProvider, + LogStreamProvider, + useLogPositionStateContext, + useLogStreamContext, + useLogViewContext, +} from '@kbn/logs-shared-plugin/public'; import { LogStreamPageActorRef, LogStreamPageCallbacks, } from '../../../observability_logs/log_stream_page/state'; import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; -import { LogHighlightsStateProvider } from '../../../containers/logs/log_highlights/log_highlights'; -import { - LogPositionStateProvider, - useLogPositionStateContext, -} from '../../../containers/logs/log_position'; -import { LogStreamProvider, useLogStreamContext } from '../../../containers/logs/log_stream'; import { LogViewConfigurationProvider } from '../../../containers/logs/log_view_configuration'; import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; const ViewLogInContext: React.FC = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx index 99c9d498fc6cc4..9ea8e60eef0b97 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx @@ -8,15 +8,17 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useMemo } from 'react'; +import { + useLogHighlightsStateContext, + useLogPositionStateContext, + useLogViewContext, +} from '@kbn/logs-shared-plugin/public'; import { LogCustomizationMenu } from '../../../components/logging/log_customization_menu'; import { LogHighlightsMenu } from '../../../components/logging/log_highlights_menu'; import { LogTextScaleControls } from '../../../components/logging/log_text_scale_controls'; import { LogTextWrapControls } from '../../../components/logging/log_text_wrap_controls'; -import { useLogHighlightsStateContext } from '../../../containers/logs/log_highlights/log_highlights'; -import { useLogPositionStateContext } from '../../../containers/logs/log_position'; import { useLogViewConfigurationContext } from '../../../containers/logs/log_view_configuration'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { StreamLiveButton } from './components/stream_live_button'; export const LogsToolbar = () => { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx index 15dbbcca7ce9f4..2917b7b21d78fa 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx @@ -17,10 +17,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { isEmpty } from 'lodash'; import React, { useCallback, useMemo } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { LogEntry } from '../../../../common/log_entry'; +import { LogEntry } from '@kbn/logs-shared-plugin/common'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { useViewLogInProviderContext } from '../../../containers/logs/view_log_in_context'; import { useViewportDimensions } from '../../../utils/use_viewport_dimensions'; -import { LogStream } from '../../../components/log_stream'; const MODAL_MARGIN = 25; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx index ac3981026ea8ef..cd2537418e46c3 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { EuiButtonEmpty } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { LogViewReference } from '../../../../../../../common/log_views'; +import { LogViewReference } from '@kbn/logs-shared-plugin/common'; import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana'; interface LogsLinkToStreamProps { diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx index 6fe796d33e909c..66cbc9d1c1b1ba 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx @@ -8,8 +8,8 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { InfraLoadingPanel } from '../../../../../../components/loading'; -import { LogStream } from '../../../../../../components/log_stream'; import { useHostsViewContext } from '../../../hooks/use_hosts_view'; import { useUnifiedSearchContext } from '../../../hooks/use_unified_search'; import { useLogsSearchUrlState } from '../../../hooks/use_logs_search_url_state'; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts index 73358551895265..46a062001bb74d 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts @@ -8,8 +8,8 @@ // import { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { v4 as uuidv4 } from 'uuid'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; import { useLazyRef } from '../../../../hooks/use_lazy_ref'; -import { DEFAULT_LOG_VIEW, type LogViewReference } from '../../../../../common/log_views'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; interface Props { @@ -18,13 +18,11 @@ interface Props { } export const useLogViewReference = ({ id, extraFields = [] }: Props) => { const { - services: { - logViews: { client }, - }, + services: { logsShared }, } = useKibanaContextForPlugin(); const { loading, value: defaultLogView } = useAsync( - () => client.getLogView(DEFAULT_LOG_VIEW), + () => logsShared.logViews.client.getLogView(DEFAULT_LOG_VIEW), [] ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx index 3024ff3d1bd067..ddbf4ae52788bf 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx @@ -14,9 +14,9 @@ import { EuiFlexGroup } from '@elastic/eui'; import { EuiFlexItem } from '@elastic/eui'; import { EuiButtonEmpty } from '@elastic/eui'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana'; import { TabContent, TabProps } from './shared'; -import { LogStream } from '../../../../../../components/log_stream'; import { useWaffleOptionsContext } from '../../../hooks/use_waffle_options'; import { findInventoryFields } from '../../../../../../../common/inventory_models'; diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts index 73b09017fecc04..9b48b9391f9bd2 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts @@ -13,7 +13,7 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { replaceStateKeyInQueryString } from '../../../../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../../../../common/url_state_storage_service'; import { useUrlState } from '../../../../utils/use_url_state'; const parseRange = (range: MetricsTimeInput) => { diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index 36c873c3b22dfa..7ea1dbdfa7cd23 100644 --- a/x-pack/plugins/infra/public/plugin.ts +++ b/x-pack/plugins/infra/public/plugin.ts @@ -19,7 +19,6 @@ import { ObservabilityTriggerId } from '@kbn/observability-shared-plugin/common' import { BehaviorSubject, combineLatest, from } from 'rxjs'; import { map } from 'rxjs/operators'; import { DISCOVER_APP_TARGET, LOGS_APP_TARGET } from '../common/constants'; -import { defaultLogViewsStaticConfig } from '../common/log_views'; import { InfraPublicConfig } from '../common/plugin_config_types'; import { createInventoryMetricRuleType } from './alerting/inventory'; import { createLogThresholdRuleType } from './alerting/log_threshold'; @@ -39,7 +38,6 @@ import { import { createMetricsFetchData, createMetricsHasData } from './metrics_overview_fetchers'; import { registerFeatures } from './register_feature'; import { InventoryViewsService } from './services/inventory_views'; -import { LogViewsService } from './services/log_views'; import { MetricsExplorerViewsService } from './services/metrics_explorer_views'; import { TelemetryService } from './services/telemetry'; import { @@ -56,7 +54,6 @@ import { getLogsHasDataFetcher, getLogsOverviewDataFetcher } from './utils/logs_ export class Plugin implements InfraClientPluginClass { public config: InfraPublicConfig; private inventoryViews: InventoryViewsService; - private logViews: LogViewsService; private metricsExplorerViews: MetricsExplorerViewsService; private telemetry: TelemetryService; private locators?: InfraLocators; @@ -68,10 +65,6 @@ export class Plugin implements InfraClientPluginClass { this.config = context.config.get(); this.inventoryViews = new InventoryViewsService(); - this.logViews = new LogViewsService({ - messageFields: - this.config.sources?.default?.fields?.message ?? defaultLogViewsStaticConfig.messageFields, - }); this.metricsExplorerViews = new MetricsExplorerViewsService(); this.telemetry = new TelemetryService(); this.appTarget = this.config.logs.app_target; @@ -106,6 +99,10 @@ export class Plugin implements InfraClientPluginClass { fetchData: createMetricsFetchData(core.getStartServices), }); + pluginsSetup.logsShared.logViews.setLogViewsStaticConfig({ + messageFields: this.config.sources?.default?.fields?.message, + }); + const startDep$AndHostViewFlag$ = combineLatest([ from(core.getStartServices()), core.uiSettings.get$(enableInfrastructureHostsView), @@ -342,12 +339,6 @@ export class Plugin implements InfraClientPluginClass { http: core.http, }); - const logViews = this.logViews.start({ - http: core.http, - dataViews: plugins.dataViews, - search: plugins.data.search, - }); - const metricsExplorerViews = this.metricsExplorerViews.start({ http: core.http, }); @@ -356,7 +347,6 @@ export class Plugin implements InfraClientPluginClass { const startContract: InfraClientStartExports = { inventoryViews, - logViews, metricsExplorerViews, telemetry, locators: this.locators!, diff --git a/x-pack/plugins/infra/public/test_utils/entries.ts b/x-pack/plugins/infra/public/test_utils/entries.ts index 4dc3732fd49d5d..35dad808cdf4f1 100644 --- a/x-pack/plugins/infra/public/test_utils/entries.ts +++ b/x-pack/plugins/infra/public/test_utils/entries.ts @@ -6,16 +6,7 @@ */ import faker from 'faker'; -import { LogEntry } from '../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../common/log_views'; - -export const ENTRIES_EMPTY = { - data: { - entries: [], - topCursor: null, - bottomCursor: null, - }, -}; +import { LogEntry, LogViewColumnConfiguration } from '@kbn/logs-shared-plugin/common'; export function generateFakeEntries( count: number, diff --git a/x-pack/plugins/infra/public/types.ts b/x-pack/plugins/infra/public/types.ts index 5c78c1534a5a4c..488d92573e7461 100644 --- a/x-pack/plugins/infra/public/types.ts +++ b/x-pack/plugins/infra/public/types.ts @@ -38,6 +38,10 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import { CasesUiStart } from '@kbn/cases-plugin/public'; import { DiscoverStart } from '@kbn/discover-plugin/public'; import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import { + LogsSharedClientSetupExports, + LogsSharedClientStartExports, +} from '@kbn/logs-shared-plugin/public'; import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { UnwrapPromise } from '../common/utility_types'; @@ -46,7 +50,6 @@ import type { UseNodeMetricsTableOptions, } from './components/infrastructure_node_metrics_tables/shared'; import { InventoryViewsServiceStart } from './services/inventory_views'; -import { LogViewsServiceStart } from './services/log_views'; import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views'; import { ITelemetryClient } from './services/telemetry'; import type { InfraLocators } from '../common/locators'; @@ -58,7 +61,6 @@ export interface InfraClientSetupExports { export interface InfraClientStartExports { inventoryViews: InventoryViewsServiceStart; - logViews: LogViewsServiceStart; metricsExplorerViews: MetricsExplorerViewsServiceStart; telemetry: ITelemetryClient; locators: InfraLocators; @@ -74,6 +76,7 @@ export interface InfraClientStartExports { } export interface InfraClientSetupDeps { + logsShared: LogsSharedClientSetupExports; home?: HomePublicPluginSetup; observability: ObservabilityPublicSetup; observabilityShared: ObservabilitySharedPluginSetup; @@ -97,6 +100,7 @@ export interface InfraClientStartDeps { embeddable?: EmbeddableStart; kibanaVersion?: string; lens: LensPublicStart; + logsShared: LogsSharedClientStartExports; ml: MlPluginStart; observability: ObservabilityPublicStart; observabilityShared: ObservabilitySharedPluginStart; diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts index 5ebacc0e7773b2..186e4c9bc1ed05 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts @@ -12,7 +12,7 @@ import { FetchDataParams, LogsFetchDataResponse, } from '@kbn/observability-plugin/public'; -import { DEFAULT_LOG_VIEW } from '../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { TIMESTAMP_FIELD } from '../../common/constants'; import { InfraClientStartDeps, InfraClientStartServicesAccessor } from '../types'; @@ -38,9 +38,11 @@ type StatsAndSeries = Pick; export function getLogsHasDataFetcher(getStartServices: InfraClientStartServicesAccessor) { return async () => { - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); - const logViewStatus = await logViews.client.getResolvedLogViewStatus(resolvedLogView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); + const logViewStatus = await logsShared.logViews.client.getResolvedLogViewStatus( + resolvedLogView + ); const hasData = logViewStatus.index === 'available'; const indices = resolvedLogView.indices; @@ -56,8 +58,8 @@ export function getLogsOverviewDataFetcher( getStartServices: InfraClientStartServicesAccessor ): FetchData { return async (params) => { - const [, { data }, { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); + const [, { data, logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); const { stats, series } = await fetchLogsOverview( { diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts index dad3dedc4bb460..85d7f145869136 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts @@ -6,10 +6,11 @@ */ import { CoreStart } from '@kbn/core/public'; -import { of } from 'rxjs'; import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; -import { createResolvedLogViewMock } from '../../common/log_views/resolved_log_view.mock'; +import { createResolvedLogViewMock } from '@kbn/logs-shared-plugin/common/mocks'; +import { createLogsSharedPluginStartMock } from '@kbn/logs-shared-plugin/public/mocks'; +import { of } from 'rxjs'; import { createInfraPluginStartMock } from '../mocks'; import { InfraClientStartDeps, InfraClientStartExports } from '../types'; import { getLogsHasDataFetcher, getLogsOverviewDataFetcher } from './logs_overview_fetchers'; @@ -24,10 +25,18 @@ const DEFAULT_PARAMS = { function setup() { const core = coreMock.createStart(); const data = dataPluginMock.createStartContract(); + const logsShared = createLogsSharedPluginStartMock(); const pluginStart = createInfraPluginStartMock(); - const pluginDeps = { data } as InfraClientStartDeps; + const pluginDeps = { data, logsShared } as unknown as InfraClientStartDeps; const dataSearch = data.search.search as jest.MockedFunction; + const getResolvedLogView = logsShared.logViews.client.getResolvedLogView as jest.MockedFunction< + typeof logsShared.logViews.client.getResolvedLogView + >; + const getResolvedLogViewStatus = logsShared.logViews.client + .getResolvedLogViewStatus as jest.MockedFunction< + typeof logsShared.logViews.client.getResolvedLogViewStatus + >; const mockedGetStartServices = jest.fn(() => Promise.resolve<[CoreStart, InfraClientStartDeps, InfraClientStartExports]>([ @@ -36,7 +45,15 @@ function setup() { pluginStart, ]) ); - return { core, dataSearch, mockedGetStartServices, pluginStart }; + return { + core, + dataSearch, + mockedGetStartServices, + pluginDeps, + pluginStart, + getResolvedLogView, + getResolvedLogViewStatus, + }; } describe('Logs UI Observability Homepage Functions', () => { @@ -46,62 +63,59 @@ describe('Logs UI Observability Homepage Functions', () => { describe('getLogsHasDataFetcher()', () => { it('should return true when non-empty indices exist', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'available', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'available' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: true, indices: 'test-index' }); }); it('should return false when only empty indices exist', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'empty', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'empty' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: false, indices: 'test-index' }); }); it('should return false when no index exists', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'missing', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'missing' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: false, indices: 'test-index' }); }); }); describe('getLogsOverviewDataFetcher()', () => { it('should work', async () => { - const { mockedGetStartServices, dataSearch, pluginStart } = setup(); + const { mockedGetStartServices, dataSearch, getResolvedLogView } = setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue(createResolvedLogViewMock()); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock()); dataSearch.mockReturnValue( of({ diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index 8fc4961bba2213..a07b8afbc68f88 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { Route } from '@kbn/shared-ux-router'; import { decode, RisonValue } from '@kbn/rison'; import { throttle } from 'lodash'; -import { replaceStateKeyInQueryString } from '../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../common/url_state_storage_service'; interface UrlStateContainerProps { urlState: UrlState | undefined; diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index 3d269f9eb058c8..8fc03d2d9dda22 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -10,7 +10,7 @@ import { Location } from 'history'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { decode, RisonValue } from '@kbn/rison'; import { useHistory } from 'react-router-dom'; -import { replaceStateKeyInQueryString } from '../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../common/url_state_storage_service'; export const useUrlState = ({ defaultState, diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index a1b1a7b7291930..e9fec4a5b4f5d2 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '../common/alerting/logs/log_threshold/types'; import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, @@ -14,7 +15,6 @@ import { } from '../common/alerting/metrics'; import { LOGS_FEATURE_ID, METRICS_FEATURE_ID } from '../common/constants'; import { infraSourceConfigurationSavedObjectName } from './lib/sources/saved_object_type'; -import { logViewSavedObjectName } from './saved_objects'; export const METRICS_FEATURE = { id: METRICS_FEATURE_ID, diff --git a/x-pack/plugins/infra/server/infra_server.ts b/x-pack/plugins/infra/server/infra_server.ts index 4d29974ceb75f9..e54713faba76af 100644 --- a/x-pack/plugins/infra/server/infra_server.ts +++ b/x-pack/plugins/infra/server/infra_server.ts @@ -22,12 +22,6 @@ import { initValidateLogAnalysisDatasetsRoute, initValidateLogAnalysisIndicesRoute, } from './routes/log_analysis'; -import { - initLogEntriesHighlightsRoute, - initLogEntriesSummaryHighlightsRoute, - initLogEntriesSummaryRoute, -} from './routes/log_entries'; -import { initLogViewRoutes } from './routes/log_views'; import { initMetadataRoute } from './routes/metadata'; import { initMetricsAPIRoute } from './routes/metrics_api'; import { initMetricExplorerRoute } from './routes/metrics_explorer'; @@ -55,10 +49,6 @@ export const initInfraServer = (libs: InfraBackendLibs) => { initValidateLogAnalysisDatasetsRoute(libs); initValidateLogAnalysisIndicesRoute(libs); initGetLogEntryExamplesRoute(libs); - initLogEntriesHighlightsRoute(libs); - initLogEntriesSummaryRoute(libs); - initLogEntriesSummaryHighlightsRoute(libs); - initLogViewRoutes(libs); initMetricExplorerRoute(libs); initMetricsExplorerViewRoutes(libs); initMetricsAPIRoute(libs); diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index 22351750fbab48..61c8b935806ac2 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -24,6 +24,7 @@ import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plu import { MlPluginSetup } from '@kbn/ml-plugin/server'; import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; +import { LogsSharedPluginSetup, LogsSharedPluginStart } from '@kbn/logs-shared-plugin/server'; import { VersionedRouteConfig } from '@kbn/core-http-server'; export interface InfraServerPluginSetupDeps { @@ -38,11 +39,13 @@ export interface InfraServerPluginSetupDeps { usageCollection: UsageCollectionSetup; visTypeTimeseries: VisTypeTimeseriesSetup; ml?: MlPluginSetup; + logsShared: LogsSharedPluginSetup; } export interface InfraServerPluginStartDeps { data: DataPluginStart; dataViews: DataViewsPluginStart; + logsShared: LogsSharedPluginStart; } export interface CallWithRequestParams extends estypes.RequestBase { diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts index 0860da5c7a1848..d0a301726138e0 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts @@ -29,6 +29,7 @@ import { createInventoryMetricThresholdExecutor } from './inventory_metric_thres import { ConditionResult } from './evaluate_condition'; import { InfraBackendLibs } from '../../infra_types'; import { infraPluginMock } from '../../../mocks'; +import { logsSharedPluginMock } from '@kbn/logs-shared-plugin/server/mocks'; jest.mock('./evaluate_condition', () => ({ evaluateCondition: jest.fn() })); @@ -121,7 +122,7 @@ const mockLibs = { }, getStartServices: () => [ null, - infraPluginMock.createSetupContract(), + { logsShared: logsSharedPluginMock.createStartContract() }, infraPluginMock.createStartContract(), ], configuration: createMockStaticConfiguration({}), diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 5a1dba9faae146..0754c79a99688d 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -162,8 +162,8 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = } const source = await libs.sources.getSourceConfiguration(savedObjectsClient, sourceId); - const [, , { logViews }] = await libs.getStartServices(); - const logQueryFields: LogQueryFields | undefined = await logViews + const [, { logsShared }] = await libs.getStartServices(); + const logQueryFields: LogQueryFields | undefined = await logsShared.logViews .getClient(savedObjectsClient, esClient) .getResolvedLogView({ type: 'log-view-reference', diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts index 97c43ea578e738..f54334ef22e5cc 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { ResolvedLogView } from '@kbn/logs-shared-plugin/common'; import { ExecutionTimeRange, GroupedSearchQueryResponse, @@ -19,7 +20,6 @@ import { Point, Series, } from '../../../../common/http_api'; -import { ResolvedLogView } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; import type { InfraPluginRequestHandlerContext } from '../../../types'; import { KibanaFramework } from '../../adapters/framework/kibana_framework_adapter'; diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 7091fc62a2bbac..9b93e021ae8f1f 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -201,12 +201,12 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => return alert; }; - const [, , { logViews }] = await libs.getStartServices(); + const [, { logsShared }] = await libs.getStartServices(); try { const validatedParams = decodeOrThrow(ruleParamsRT)(params); - const { indices, timestampField, runtimeMappings } = await logViews + const { indices, timestampField, runtimeMappings } = await logsShared.logViews .getClient(savedObjectsClient, scopedClusterClient.asCurrentUser) .getResolvedLogView(validatedParams.logView); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts index 7a44311b40fcdb..12b67b6f260e43 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts @@ -6,9 +6,9 @@ */ import type { SavedObjectReference } from '@kbn/core-saved-objects-common'; -import { logViewSavedObjectName } from '../../../saved_objects'; +import { logViewReferenceRT } from '@kbn/logs-shared-plugin/common'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { RuleParams, ruleParamsRT } from '../../../../common/alerting/logs/log_threshold'; -import { logViewReferenceRT } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; export const LOG_VIEW_REFERENCE_NAME = 'log-view-reference-0'; diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index f9fe976f692a54..e31bad1b5ffeb2 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -10,18 +10,18 @@ import type { IBasePath } from '@kbn/core/server'; import type { handleEsError } from '@kbn/es-ui-shared-plugin/server'; import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; import type { LocatorPublic } from '@kbn/share-plugin/common'; +import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server'; import { RulesServiceSetup } from '../services/rules'; import { InfraConfig, InfraPluginStartServicesAccessor } from '../types'; import { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; import { InfraFieldsDomain } from './domains/fields_domain'; -import { InfraLogEntriesDomain } from './domains/log_entries_domain'; import { InfraMetricsDomain } from './domains/metrics_domain'; import { InfraSources } from './sources'; import { InfraSourceStatus } from './source_status'; export interface InfraDomainLibs { fields: InfraFieldsDomain; - logEntries: InfraLogEntriesDomain; + logEntries: ILogsSharedLogEntriesDomain; metrics: InfraMetricsDomain; } diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index b17afa68d2d4db..591376450be385 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -6,6 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { PersistedLogViewReference, ResolvedLogView } from '@kbn/logs-shared-plugin/common'; import { AnomaliesSort, getJobId, @@ -16,7 +17,6 @@ import { logEntryRateJobTypes, Pagination, } from '../../../common/log_analysis'; -import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan, TracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts index d8eb18e4890b5b..88678f4c79c53b 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts @@ -7,6 +7,11 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient } from '@kbn/core/server'; +import { + LogEntryContext, + PersistedLogViewReference, + ResolvedLogView, +} from '@kbn/logs-shared-plugin/common'; import { CategoriesSort, compareDatasetsByMaximumAnomalyScore, @@ -14,8 +19,6 @@ import { jobCustomSettingsRT, logEntryCategoriesJobTypes, } from '../../../common/log_analysis'; -import { LogEntryContext } from '../../../common/log_entry'; -import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { MlAnomalyDetectors, MlSystem } from '../../types'; diff --git a/x-pack/plugins/infra/server/mocks.ts b/x-pack/plugins/infra/server/mocks.ts index 7e5a349cb1e012..a15575572a076c 100644 --- a/x-pack/plugins/infra/server/mocks.ts +++ b/x-pack/plugins/infra/server/mocks.ts @@ -5,18 +5,21 @@ * 2.0. */ -import { createInventoryViewsServiceStartMock } from './services/inventory_views/inventory_views_service.mock'; import { - createLogViewsServiceSetupMock, - createLogViewsServiceStartMock, -} from './services/log_views/log_views_service.mock'; -import { createMetricsExplorerViewsServiceStartMock } from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; + createInventoryViewsServiceSetupMock, + createInventoryViewsServiceStartMock, +} from './services/inventory_views/inventory_views_service.mock'; +import { + createMetricsExplorerViewsServiceSetupMock, + createMetricsExplorerViewsServiceStartMock, +} from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; import { InfraPluginSetup, InfraPluginStart } from './types'; const createInfraSetupMock = () => { const infraSetupMock: jest.Mocked = { defineInternalSourceConfiguration: jest.fn(), - logViews: createLogViewsServiceSetupMock(), + inventoryViews: createInventoryViewsServiceSetupMock(), + metricsExplorerViews: createMetricsExplorerViewsServiceSetupMock(), }; return infraSetupMock; @@ -26,7 +29,6 @@ const createInfraStartMock = () => { const infraStartMock: jest.Mocked = { getMetricIndices: jest.fn(), inventoryViews: createInventoryViewsServiceStartMock(), - logViews: createLogViewsServiceStartMock(), metricsExplorerViews: createMetricsExplorerViewsServiceStartMock(), }; return infraStartMock; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index 04fea926a20834..2449293dfa3aa0 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -24,7 +24,6 @@ import { LOGS_FEATURE_ID, METRICS_FEATURE_ID, } from '../common/constants'; -import { defaultLogViewsStaticConfig } from '../common/log_views'; import { publicConfigKeys } from '../common/plugin_config_types'; import { configDeprecations, getInfraDeprecationsFactory } from './deprecations'; import { LOGS_FEATURE, METRICS_FEATURE } from './features'; @@ -32,7 +31,6 @@ import { initInfraServer } from './infra_server'; import { FrameworkFieldsAdapter } from './lib/adapters/fields/framework_fields_adapter'; import { InfraServerPluginSetupDeps, InfraServerPluginStartDeps } from './lib/adapters/framework'; import { KibanaFramework } from './lib/adapters/framework/kibana_framework_adapter'; -import { InfraKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter'; import { KibanaMetricsAdapter } from './lib/adapters/metrics/kibana_metrics_adapter'; import { InfraElasticsearchSourceStatusAdapter } from './lib/adapters/source_status'; import { registerRuleTypes } from './lib/alerting'; @@ -41,20 +39,13 @@ import { METRICS_RULES_ALERT_CONTEXT, } from './lib/alerting/register_rule_types'; import { InfraFieldsDomain } from './lib/domains/fields_domain'; -import { InfraLogEntriesDomain } from './lib/domains/log_entries_domain'; import { InfraMetricsDomain } from './lib/domains/metrics_domain'; import { InfraBackendLibs, InfraDomainLibs } from './lib/infra_types'; import { makeGetMetricIndices } from './lib/metrics/make_get_metric_indices'; import { infraSourceConfigurationSavedObjectType, InfraSources } from './lib/sources'; import { InfraSourceStatus } from './lib/source_status'; -import { - inventoryViewSavedObjectType, - logViewSavedObjectType, - metricsExplorerViewSavedObjectType, -} from './saved_objects'; +import { inventoryViewSavedObjectType, metricsExplorerViewSavedObjectType } from './saved_objects'; import { InventoryViewsService } from './services/inventory_views'; -import { LogEntriesService } from './services/log_entries'; -import { LogViewsService } from './services/log_views'; import { MetricsExplorerViewsService } from './services/metrics_explorer_views'; import { RulesService } from './services/rules'; import { @@ -65,6 +56,7 @@ import { InfraPluginStart, } from './types'; import { UsageCollector } from './usage/usage_collector'; +import { mapSourceToLogView } from './utils/map_source_to_log_view'; export const config: PluginConfigDescriptor = { schema: schema.object({ @@ -138,7 +130,6 @@ export class InfraServerPlugin private logsRules: RulesService; private metricsRules: RulesService; private inventoryViews: InventoryViewsService; - private logViews: LogViewsService; private metricsExplorerViews: MetricsExplorerViewsService; constructor(context: PluginInitializerContext) { @@ -157,7 +148,6 @@ export class InfraServerPlugin ); this.inventoryViews = new InventoryViewsService(this.logger.get('inventoryViews')); - this.logViews = new LogViewsService(this.logger.get('logViews')); this.metricsExplorerViews = new MetricsExplorerViewsService( this.logger.get('metricsExplorerViews') ); @@ -170,18 +160,16 @@ export class InfraServerPlugin }); const sourceStatus = new InfraSourceStatus( new InfraElasticsearchSourceStatusAdapter(framework), - { - sources, - } + { sources } ); + + // Setup infra services const inventoryViews = this.inventoryViews.setup(); - const logViews = this.logViews.setup(); const metricsExplorerViews = this.metricsExplorerViews.setup(); - // register saved object types + // Register saved object types core.savedObjects.registerType(infraSourceConfigurationSavedObjectType); core.savedObjects.registerType(inventoryViewSavedObjectType); - core.savedObjects.registerType(logViewSavedObjectType); core.savedObjects.registerType(metricsExplorerViewSavedObjectType); // TODO: separate these out individually and do away with "domains" as a temporary group @@ -191,10 +179,7 @@ export class InfraServerPlugin fields: new InfraFieldsDomain(new FrameworkFieldsAdapter(framework), { sources, }), - logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { - framework, - getStartServices: () => core.getStartServices(), - }), + logEntries: plugins.logsShared.logEntries, metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), }; @@ -216,6 +201,19 @@ export class InfraServerPlugin plugins.features.registerKibanaFeature(METRICS_FEATURE); plugins.features.registerKibanaFeature(LOGS_FEATURE); + // Register an handler to retrieve the fallback logView starting from a source configuration + plugins.logsShared.logViews.registerLogViewFallbackHandler(async (sourceId, { soClient }) => { + const sourceConfiguration = await sources.getSourceConfiguration(soClient, sourceId); + return mapSourceToLogView(sourceConfiguration); + }); + plugins.logsShared.logViews.setLogViewsStaticConfig({ + messageFields: this.config.sources?.default?.fields?.message, + }); + + plugins.logsShared.registerUsageCollectorActions({ + countLogs: () => UsageCollector.countLogs(), + }); + plugins.home.sampleData.addAppLinksToSampleDataset('logs', [ { sampleObject: null, // indicates that there is no sample object associated with this app link's path @@ -247,9 +245,6 @@ export class InfraServerPlugin // Telemetry UsageCollector.registerUsageCollector(plugins.usageCollection); - const logEntriesService = new LogEntriesService(); - logEntriesService.setup(core, plugins); - // register deprecated source configuration fields core.deprecations.registerDeprecations({ getDeprecations: getInfraDeprecationsFactory(sources), @@ -258,29 +253,16 @@ export class InfraServerPlugin return { defineInternalSourceConfiguration: sources.defineInternalSourceConfiguration.bind(sources), inventoryViews, - logViews, metricsExplorerViews, } as InfraPluginSetup; } - start(core: CoreStart, plugins: InfraServerPluginStartDeps) { + start(core: CoreStart) { const inventoryViews = this.inventoryViews.start({ infraSources: this.libs.sources, savedObjects: core.savedObjects, }); - const logViews = this.logViews.start({ - infraSources: this.libs.sources, - savedObjects: core.savedObjects, - dataViews: plugins.dataViews, - elasticsearch: core.elasticsearch, - config: { - messageFields: - this.config.sources?.default?.fields?.message ?? - defaultLogViewsStaticConfig.messageFields, - }, - }); - const metricsExplorerViews = this.metricsExplorerViews.start({ infraSources: this.libs.sources, savedObjects: core.savedObjects, @@ -288,7 +270,6 @@ export class InfraServerPlugin return { inventoryViews, - logViews, metricsExplorerViews, getMetricIndices: makeGetMetricIndices(this.libs.sources), }; diff --git a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts index 9a963c3f84e722..1c6be6bf56c28f 100644 --- a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts +++ b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts @@ -38,8 +38,10 @@ export const initGetLogAlertsChartPreviewDataRoute = ({ data: { logView, buckets, alertParams, executionTimeRange }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const { series } = await getChartPreviewData( diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts index b17a50d23974d1..5e9a57768828c4 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts @@ -45,8 +45,10 @@ export const initGetLogEntryCategoryExamplesRoute = ({ }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts index 2b413dce7f2940..8b3b2f0449c58c 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts @@ -46,8 +46,10 @@ export const initGetLogEntryExamplesRoute = ({ }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 0c893171b5b677..085be4584e2a7e 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -40,8 +40,8 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { const soClient = (await requestContext.core).savedObjects.client; const source = await libs.sources.getSourceConfiguration(soClient, snapshotRequest.sourceId); const compositeSize = libs.configuration.inventory.compositeSize; - const [, , { logViews }] = await libs.getStartServices(); - const logQueryFields: LogQueryFields | undefined = await logViews + const [, { logsShared }] = await libs.getStartServices(); + const logQueryFields: LogQueryFields | undefined = await logsShared.logViews .getScopedClient(request) .getResolvedLogView({ type: 'log-view-reference', diff --git a/x-pack/plugins/infra/server/saved_objects/index.ts b/x-pack/plugins/infra/server/saved_objects/index.ts index cf6906fc733f73..c64f4b46808c46 100644 --- a/x-pack/plugins/infra/server/saved_objects/index.ts +++ b/x-pack/plugins/infra/server/saved_objects/index.ts @@ -6,5 +6,4 @@ */ export * from './inventory_view'; -export * from './log_view'; export * from './metrics_explorer_view'; diff --git a/x-pack/plugins/infra/server/types.ts b/x-pack/plugins/infra/server/types.ts index 49dbca9b276b26..0a4ad94c09d43e 100644 --- a/x-pack/plugins/infra/server/types.ts +++ b/x-pack/plugins/infra/server/types.ts @@ -14,9 +14,11 @@ import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import type { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration'; import { InfraServerPluginStartDeps } from './lib/adapters/framework'; -import { InventoryViewsServiceStart } from './services/inventory_views'; -import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views/types'; -import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views'; +import { InventoryViewsServiceSetup, InventoryViewsServiceStart } from './services/inventory_views'; +import { + MetricsExplorerViewsServiceSetup, + MetricsExplorerViewsServiceStart, +} from './services/metrics_explorer_views'; export type { InfraConfig } from '../common/plugin_config_types'; @@ -28,12 +30,12 @@ export interface InfraPluginSetup { sourceId: string, sourceProperties: InfraStaticSourceConfiguration ) => void; - logViews: LogViewsServiceSetup; + inventoryViews: InventoryViewsServiceSetup; + metricsExplorerViews: MetricsExplorerViewsServiceSetup; } export interface InfraPluginStart { inventoryViews: InventoryViewsServiceStart; - logViews: LogViewsServiceStart; metricsExplorerViews: MetricsExplorerViewsServiceStart; getMetricIndices: ( savedObjectsClient: SavedObjectsClientContract, diff --git a/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts b/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts index e2dbf02ae2d06f..20f0aeb2e2f0a4 100644 --- a/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts +++ b/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts @@ -17,8 +17,6 @@ export const shardFailureRT = rt.partial({ shard: rt.number, }); -export type ShardFailure = rt.TypeOf; - export const commonSearchSuccessResponseFieldsRT = rt.type({ _shards: rt.intersection([ rt.type({ @@ -34,8 +32,3 @@ export const commonSearchSuccessResponseFieldsRT = rt.type({ timed_out: rt.boolean, took: rt.number, }); - -export const commonHitFieldsRT = rt.type({ - _index: rt.string, - _id: rt.string, -}); diff --git a/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts b/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts new file mode 100644 index 00000000000000..38db985a28280b --- /dev/null +++ b/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { InfraSource } from '../lib/sources'; +import { getAttributesFromSourceConfiguration } from './map_source_to_log_view'; + +describe('getAttributesFromSourceConfiguration function', () => { + it('converts the index_pattern log indices type to data_view', () => { + const logViewAttributes = getAttributesFromSourceConfiguration(basicTestSourceConfiguration); + + expect(logViewAttributes.logIndices).toEqual({ + type: 'data_view', + dataViewId: 'INDEX_PATTERN_ID', + }); + }); + + it('preserves the index_name log indices type', () => { + const logViewAttributes = getAttributesFromSourceConfiguration({ + ...basicTestSourceConfiguration, + configuration: { + ...basicTestSourceConfiguration.configuration, + logIndices: { + type: 'index_name', + indexName: 'INDEX_NAME', + }, + }, + }); + + expect(logViewAttributes.logIndices).toEqual({ + type: 'index_name', + indexName: 'INDEX_NAME', + }); + }); +}); + +const basicTestSourceConfiguration: InfraSource = { + id: 'ID', + origin: 'stored', + configuration: { + name: 'NAME', + description: 'DESCRIPTION', + logIndices: { + type: 'index_pattern', + indexPatternId: 'INDEX_PATTERN_ID', + }, + logColumns: [], + fields: { + message: [], + }, + metricAlias: 'METRIC_ALIAS', + inventoryDefaultView: 'INVENTORY_DEFAULT_VIEW', + metricsExplorerDefaultView: 'METRICS_EXPLORER_DEFAULT_VIEW', + anomalyThreshold: 0, + }, +}; diff --git a/x-pack/plugins/infra/server/utils/map_source_to_log_view.ts b/x-pack/plugins/infra/server/utils/map_source_to_log_view.ts new file mode 100644 index 00000000000000..5dd5d021ccd6a2 --- /dev/null +++ b/x-pack/plugins/infra/server/utils/map_source_to_log_view.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 { LogIndexReference, LogView, LogViewAttributes } from '@kbn/logs-shared-plugin/common'; +import { LogIndexReference as SourceConfigurationLogIndexReference } from '../../common/source_configuration/source_configuration'; +import { InfraSource } from '../lib/sources'; + +export const mapSourceToLogView = (sourceConfiguration: InfraSource): LogView => { + return { + id: sourceConfiguration.id, + version: sourceConfiguration.version, + updatedAt: sourceConfiguration.updatedAt, + origin: `infra-source-${sourceConfiguration.origin}`, + attributes: getAttributesFromSourceConfiguration(sourceConfiguration), + }; +}; + +export const getAttributesFromSourceConfiguration = ({ + configuration: { name, description, logIndices, logColumns }, +}: InfraSource): LogViewAttributes => ({ + name, + description, + logIndices: getLogIndicesFromSourceConfigurationLogIndices(logIndices), + logColumns, +}); + +const getLogIndicesFromSourceConfigurationLogIndices = ( + logIndices: SourceConfigurationLogIndexReference +): LogIndexReference => + logIndices.type === 'index_pattern' + ? { + type: 'data_view', + dataViewId: logIndices.indexPatternId, + } + : logIndices; diff --git a/x-pack/plugins/infra/tsconfig.json b/x-pack/plugins/infra/tsconfig.json index 997fbf24ea9c9d..3f1ece70501de6 100644 --- a/x-pack/plugins/infra/tsconfig.json +++ b/x-pack/plugins/infra/tsconfig.json @@ -38,7 +38,6 @@ "@kbn/shared-ux-page-kibana-template", "@kbn/safer-lodash-set", "@kbn/test-jest-helpers", - "@kbn/test-subj-selector", "@kbn/controls-plugin", "@kbn/securitysolution-io-ts-types", "@kbn/config-schema", @@ -67,6 +66,7 @@ "@kbn/aiops-plugin", "@kbn/field-formats-plugin", "@kbn/core-http-server", + "@kbn/logs-shared-plugin", "@kbn/licensing-plugin", ], "exclude": ["target/**/*"] diff --git a/x-pack/plugins/logs_shared/README.md b/x-pack/plugins/logs_shared/README.md new file mode 100755 index 00000000000000..16483a988ec4a5 --- /dev/null +++ b/x-pack/plugins/logs_shared/README.md @@ -0,0 +1,3 @@ +# Logs Shared + +Exposes the shared components and APIs to access and visualize logs. diff --git a/x-pack/plugins/logs_shared/common/constants.ts b/x-pack/plugins/logs_shared/common/constants.ts new file mode 100644 index 00000000000000..7e49b14458a9ea --- /dev/null +++ b/x-pack/plugins/logs_shared/common/constants.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const TIMESTAMP_FIELD = '@timestamp'; +export const MESSAGE_FIELD = 'message'; +export const TIEBREAKER_FIELD = '_doc'; diff --git a/x-pack/plugins/logs_shared/common/dynamic.tsx b/x-pack/plugins/logs_shared/common/dynamic.tsx new file mode 100644 index 00000000000000..a66dbaa10b5aaa --- /dev/null +++ b/x-pack/plugins/logs_shared/common/dynamic.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { lazy, Suspense } from 'react'; + +type LoadableComponent = () => any; + +interface DynamicOptions { + fallback?: React.ReactNode; +} + +/** + * Lazy load and wrap with Suspense any component. + * + * @example + * const Header = dynamic(() => import('./components/header')) + */ +export function dynamic(loader: LoadableComponent, options: DynamicOptions = {}) { + const Component = lazy(loader); + + return (props: any) => ( + + + + ); +} diff --git a/x-pack/plugins/logs_shared/common/formatters/datetime.ts b/x-pack/plugins/logs_shared/common/formatters/datetime.ts new file mode 100644 index 00000000000000..270dd7aa738082 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/formatters/datetime.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. + */ + +import { i18n } from '@kbn/i18n'; + +export function localizedDate(dateTime: number | Date, locale: string = i18n.getLocale()) { + const formatter = new Intl.DateTimeFormat(locale, { + year: 'numeric', + month: 'short', + day: 'numeric', + }); + + return formatter.format(dateTime); +} diff --git a/x-pack/plugins/logs_shared/common/http_api/index.ts b/x-pack/plugins/logs_shared/common/http_api/index.ts new file mode 100644 index 00000000000000..939f72786183b6 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/http_api/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Exporting versioned APIs types + */ +export * from './latest'; +export * as logEntriesV1 from './log_entries/v1'; +export * as logViewsV1 from './log_views/v1'; diff --git a/x-pack/plugins/logs_shared/common/http_api/latest.ts b/x-pack/plugins/logs_shared/common/http_api/latest.ts new file mode 100644 index 00000000000000..63f58bf4f92c0c --- /dev/null +++ b/x-pack/plugins/logs_shared/common/http_api/latest.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './log_entries/v1'; +export * from './log_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/highlights.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/highlights.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/highlights.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/highlights.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/summary.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/summary.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/summary_highlights.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary_highlights.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/summary_highlights.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary_highlights.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/common.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/common.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/common.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/common.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/get_log_view.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/get_log_view.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/get_log_view.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/get_log_view.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/put_log_view.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/put_log_view.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/put_log_view.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/put_log_view.ts diff --git a/x-pack/plugins/logs_shared/common/index.ts b/x-pack/plugins/logs_shared/common/index.ts new file mode 100644 index 00000000000000..07f029868b22a4 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/index.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. + */ + +// LogView runtime +export { + defaultFilterStateKey, + defaultPositionStateKey, + DEFAULT_LOG_VIEW, + DEFAULT_REFRESH_INTERVAL, + logDataViewReferenceRT, + logIndexNameReferenceRT, + logViewColumnConfigurationRT, + logViewReferenceRT, + persistedLogViewReferenceRT, + defaultLogViewAttributes, +} from './log_views'; + +// LogView types +export type { + LogDataViewReference, + LogIndexNameReference, + LogIndexReference, + LogView, + LogViewAttributes, + LogViewColumnConfiguration, + LogViewReference, + LogViewStatus, + PersistedLogViewReference, + ResolvedLogView, + ResolvedLogViewField, +} from './log_views'; + +// LogView errors +export { + FetchLogViewError, + FetchLogViewStatusError, + ResolveLogViewError, +} from './log_views/errors'; + +// eslint-disable-next-line @kbn/eslint/no_export_all +export * from './log_entry'; + +// Http types +export type { LogEntriesSummaryBucket, LogEntriesSummaryHighlightsBucket } from './http_api'; + +// Http runtime +export { + LOG_ENTRIES_HIGHLIGHTS_PATH, + LOG_ENTRIES_SUMMARY_PATH, + logEntriesHighlightsRequestRT, + logEntriesHighlightsResponseRT, + logEntriesSummaryRequestRT, + logEntriesSummaryResponseRT, +} from './http_api'; diff --git a/x-pack/plugins/infra/common/log_entry/index.ts b/x-pack/plugins/logs_shared/common/log_entry/index.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/index.ts rename to x-pack/plugins/logs_shared/common/log_entry/index.ts diff --git a/x-pack/plugins/infra/common/log_entry/log_entry.ts b/x-pack/plugins/logs_shared/common/log_entry/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/log_entry.ts rename to x-pack/plugins/logs_shared/common/log_entry/log_entry.ts diff --git a/x-pack/plugins/infra/common/log_entry/log_entry_cursor.ts b/x-pack/plugins/logs_shared/common/log_entry/log_entry_cursor.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/log_entry_cursor.ts rename to x-pack/plugins/logs_shared/common/log_entry/log_entry_cursor.ts diff --git a/x-pack/plugins/logs_shared/common/log_text_scale/index.ts b/x-pack/plugins/logs_shared/common/log_text_scale/index.ts new file mode 100644 index 00000000000000..11ae6d0adc7ff6 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/log_text_scale/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 * from './log_text_scale'; diff --git a/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts b/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts new file mode 100644 index 00000000000000..7fc774c4b59e0c --- /dev/null +++ b/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts @@ -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. + */ + +export type TextScale = 'small' | 'medium' | 'large'; + +export function isTextScale(maybeTextScale: string): maybeTextScale is TextScale { + return ['small', 'medium', 'large'].includes(maybeTextScale); +} diff --git a/x-pack/plugins/infra/common/log_views/defaults.ts b/x-pack/plugins/logs_shared/common/log_views/defaults.ts similarity index 82% rename from x-pack/plugins/infra/common/log_views/defaults.ts rename to x-pack/plugins/logs_shared/common/log_views/defaults.ts index 155ce6465b2fae..2d7f26c6d94077 100644 --- a/x-pack/plugins/infra/common/log_views/defaults.ts +++ b/x-pack/plugins/logs_shared/common/log_views/defaults.ts @@ -5,8 +5,7 @@ * 2.0. */ -import { defaultSourceConfiguration } from '../source_configuration/defaults'; -import { LogViewAttributes, LogViewsStaticConfig } from './types'; +import { DefaultLogViewsStaticConfig, LogViewAttributes } from './types'; export const defaultLogViewId = 'default'; export const defaultFilterStateKey = 'logFilter'; @@ -41,8 +40,8 @@ export const defaultLogViewAttributes: LogViewAttributes = { ], }; -export const defaultLogViewsStaticConfig: LogViewsStaticConfig = { - messageFields: defaultSourceConfiguration.fields.message, +export const defaultLogViewsStaticConfig: DefaultLogViewsStaticConfig = { + messageFields: ['message', '@message'], }; export const DEFAULT_LOG_VIEW = { diff --git a/x-pack/plugins/infra/common/log_views/errors.ts b/x-pack/plugins/logs_shared/common/log_views/errors.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/errors.ts rename to x-pack/plugins/logs_shared/common/log_views/errors.ts diff --git a/x-pack/plugins/infra/common/log_views/index.ts b/x-pack/plugins/logs_shared/common/log_views/index.ts similarity index 89% rename from x-pack/plugins/infra/common/log_views/index.ts rename to x-pack/plugins/logs_shared/common/log_views/index.ts index 22176058622c0d..dd0cdaece43163 100644 --- a/x-pack/plugins/infra/common/log_views/index.ts +++ b/x-pack/plugins/logs_shared/common/log_views/index.ts @@ -9,4 +9,3 @@ export * from './defaults'; export * from './errors'; export * from './resolved_log_view'; export * from './types'; -export * from './url_state_storage_service'; diff --git a/x-pack/plugins/infra/common/log_views/log_view.mock.ts b/x-pack/plugins/logs_shared/common/log_views/log_view.mock.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/log_view.mock.ts rename to x-pack/plugins/logs_shared/common/log_views/log_view.mock.ts diff --git a/x-pack/plugins/infra/common/log_views/resolved_log_view.mock.ts b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.mock.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/resolved_log_view.mock.ts rename to x-pack/plugins/logs_shared/common/log_views/resolved_log_view.mock.ts diff --git a/x-pack/plugins/infra/common/log_views/resolved_log_view.ts b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts similarity index 91% rename from x-pack/plugins/infra/common/log_views/resolved_log_view.ts rename to x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts index 391c6be18fb9d8..b9419fbd51f22e 100644 --- a/x-pack/plugins/infra/common/log_views/resolved_log_view.ts +++ b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts @@ -8,6 +8,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { DataView, DataViewsContract, FieldSpec } from '@kbn/data-views-plugin/common'; import { TIEBREAKER_FIELD, TIMESTAMP_FIELD } from '../constants'; +import { defaultLogViewsStaticConfig } from './defaults'; import { ResolveLogViewError } from './errors'; import { LogViewAttributes, LogViewColumnConfiguration, LogViewsStaticConfig } from './types'; @@ -26,16 +27,16 @@ export interface ResolvedLogView { dataViewReference: DataView; } -export const resolveLogView = async ( +export const resolveLogView = ( logViewId: string, logViewAttributes: LogViewAttributes, dataViewsService: DataViewsContract, config: LogViewsStaticConfig ): Promise => { if (logViewAttributes.logIndices.type === 'index_name') { - return await resolveLegacyReference(logViewId, logViewAttributes, dataViewsService, config); + return resolveLegacyReference(logViewId, logViewAttributes, dataViewsService, config); } else { - return await resolveDataViewReference(logViewAttributes, dataViewsService); + return resolveDataViewReference(logViewAttributes, dataViewsService); } }; @@ -71,7 +72,7 @@ const resolveLegacyReference = async ( indices, timestampField: TIMESTAMP_FIELD, tiebreakerField: TIEBREAKER_FIELD, - messageField: config.messageFields, + messageField: config.messageFields ?? defaultLogViewsStaticConfig.messageFields, fields: dataViewReference.fields, runtimeMappings: {}, columns: logViewAttributes.logColumns, diff --git a/x-pack/plugins/infra/common/log_views/types.ts b/x-pack/plugins/logs_shared/common/log_views/types.ts similarity index 96% rename from x-pack/plugins/infra/common/log_views/types.ts rename to x-pack/plugins/logs_shared/common/log_views/types.ts index ca6dd95330f8c6..f94601f9e0f848 100644 --- a/x-pack/plugins/infra/common/log_views/types.ts +++ b/x-pack/plugins/logs_shared/common/log_views/types.ts @@ -7,10 +7,12 @@ import * as rt from 'io-ts'; -export interface LogViewsStaticConfig { +export interface DefaultLogViewsStaticConfig { messageFields: string[]; } +export type LogViewsStaticConfig = Partial; + export const logViewOriginRT = rt.keyof({ stored: null, internal: null, diff --git a/x-pack/plugins/logs_shared/common/mocks.ts b/x-pack/plugins/logs_shared/common/mocks.ts new file mode 100644 index 00000000000000..06ff3df3eb00df --- /dev/null +++ b/x-pack/plugins/logs_shared/common/mocks.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 { createResolvedLogViewMock } from './log_views/resolved_log_view.mock'; diff --git a/x-pack/plugins/logs_shared/common/runtime_types.ts b/x-pack/plugins/logs_shared/common/runtime_types.ts new file mode 100644 index 00000000000000..89a6b4323b89a7 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/runtime_types.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 { RouteValidationFunction } from '@kbn/core/server'; +import { fold } from 'fp-ts/lib/Either'; +import { identity } from 'fp-ts/lib/function'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { Context, Errors, IntersectionType, Type, UnionType, ValidationError } from 'io-ts'; + +type ErrorFactory = (message: string) => Error; + +const getErrorPath = ([first, ...rest]: Context): string[] => { + if (typeof first === 'undefined') { + return []; + } else if (first.type instanceof IntersectionType) { + const [, ...next] = rest; + return getErrorPath(next); + } else if (first.type instanceof UnionType) { + const [, ...next] = rest; + return [first.key, ...getErrorPath(next)]; + } + + return [first.key, ...getErrorPath(rest)]; +}; + +const getErrorType = ({ context }: ValidationError) => + context[context.length - 1]?.type?.name ?? 'unknown'; + +const formatError = (error: ValidationError) => + error.message ?? + `in ${getErrorPath(error.context).join('/')}: ${JSON.stringify( + error.value + )} does not match expected type ${getErrorType(error)}`; + +export const formatErrors = (errors: ValidationError[]) => + `Failed to validate: \n${errors.map((error) => ` ${formatError(error)}`).join('\n')}`; + +export const createPlainError = (message: string) => new Error(message); + +export const throwErrors = (createError: ErrorFactory) => (errors: Errors) => { + throw createError(formatErrors(errors)); +}; + +export const decodeOrThrow = + ( + runtimeType: Type, + createError: ErrorFactory = createPlainError + ) => + (inputValue: InputValue) => + pipe(runtimeType.decode(inputValue), fold(throwErrors(createError), identity)); + +type ValdidationResult = ReturnType>; + +export const createValidationFunction = + ( + runtimeType: Type + ): RouteValidationFunction => + (inputValue, { badRequest, ok }) => + pipe( + runtimeType.decode(inputValue), + fold>( + (errors: Errors) => badRequest(formatErrors(errors)), + (result: DecodedValue) => ok(result) + ) + ); diff --git a/x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts b/x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts new file mode 100644 index 00000000000000..4114af07619dc9 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +const abortedRequestSearchStrategyErrorRT = rt.type({ + type: rt.literal('aborted'), +}); + +export type AbortedRequestSearchStrategyError = rt.TypeOf< + typeof abortedRequestSearchStrategyErrorRT +>; + +const genericSearchStrategyErrorRT = rt.type({ + type: rt.literal('generic'), + message: rt.string, +}); + +export type GenericSearchStrategyError = rt.TypeOf; + +const shardFailureSearchStrategyErrorRT = rt.type({ + type: rt.literal('shardFailure'), + shardInfo: rt.type({ + shard: rt.union([rt.number, rt.null]), + index: rt.union([rt.string, rt.null]), + node: rt.union([rt.string, rt.null]), + }), + message: rt.union([rt.string, rt.null]), +}); + +export type ShardFailureSearchStrategyError = rt.TypeOf; + +export const searchStrategyErrorRT = rt.union([ + abortedRequestSearchStrategyErrorRT, + genericSearchStrategyErrorRT, + shardFailureSearchStrategyErrorRT, +]); + +export type SearchStrategyError = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts new file mode 100644 index 00000000000000..f8daaa1b9227b3 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts @@ -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 type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import * as rt from 'io-ts'; +import { + logEntryAfterCursorRT, + logEntryBeforeCursorRT, + logEntryCursorRT, + logEntryRT, +} from '../../log_entry'; +import { logViewColumnConfigurationRT, logViewReferenceRT } from '../../log_views'; +import { jsonObjectRT } from '../../typed_json'; +import { searchStrategyErrorRT } from '../common/errors'; + +export const LOG_ENTRIES_SEARCH_STRATEGY = 'infra-log-entries'; + +const logEntriesBaseSearchRequestParamsRT = rt.intersection([ + rt.type({ + logView: logViewReferenceRT, + startTimestamp: rt.number, + endTimestamp: rt.number, + size: rt.number, + }), + rt.partial({ + query: jsonObjectRT, + columns: rt.array(logViewColumnConfigurationRT), + highlightPhrase: rt.string, + }), +]); + +export const logEntriesBeforeSearchRequestParamsRT = rt.intersection([ + logEntriesBaseSearchRequestParamsRT, + logEntryBeforeCursorRT, +]); + +export const logEntriesAfterSearchRequestParamsRT = rt.intersection([ + logEntriesBaseSearchRequestParamsRT, + logEntryAfterCursorRT, +]); + +export const logEntriesSearchRequestParamsRT = rt.union([ + logEntriesBaseSearchRequestParamsRT, + logEntriesBeforeSearchRequestParamsRT, + logEntriesAfterSearchRequestParamsRT, +]); + +export type LogEntriesSearchRequestParams = rt.TypeOf; + +export type LogEntriesSearchRequestQuery = estypes.QueryDslQueryContainer; + +export const logEntriesSearchResponsePayloadRT = rt.intersection([ + rt.type({ + data: rt.intersection([ + rt.type({ + entries: rt.array(logEntryRT), + topCursor: rt.union([logEntryCursorRT, rt.null]), + bottomCursor: rt.union([logEntryCursorRT, rt.null]), + }), + rt.partial({ + hasMoreBefore: rt.boolean, + hasMoreAfter: rt.boolean, + }), + ]), + }), + rt.partial({ + errors: rt.array(searchStrategyErrorRT), + }), +]); + +export type LogEntriesSearchResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts new file mode 100644 index 00000000000000..6d2a7891264d19 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { logEntryCursorRT, logEntryFieldRT } from '../../log_entry'; +import { logViewReferenceRT } from '../../log_views'; +import { searchStrategyErrorRT } from '../common/errors'; + +export const LOG_ENTRY_SEARCH_STRATEGY = 'infra-log-entry'; + +export const logEntrySearchRequestParamsRT = rt.type({ + logView: logViewReferenceRT, + logEntryId: rt.string, +}); + +export type LogEntrySearchRequestParams = rt.TypeOf; + +export const logEntryRT = rt.type({ + id: rt.string, + index: rt.string, + fields: rt.array(logEntryFieldRT), + cursor: logEntryCursorRT, +}); + +export type LogEntry = rt.TypeOf; + +export const logEntrySearchResponsePayloadRT = rt.intersection([ + rt.type({ + data: rt.union([logEntryRT, rt.null]), + }), + rt.partial({ + errors: rt.array(searchStrategyErrorRT), + }), +]); + +export type LogEntrySearchResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/time/index.ts b/x-pack/plugins/logs_shared/common/time/index.ts new file mode 100644 index 00000000000000..c6a68995c024a9 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/time/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 * from './time_key'; diff --git a/x-pack/plugins/logs_shared/common/time/time_key.ts b/x-pack/plugins/logs_shared/common/time/time_key.ts new file mode 100644 index 00000000000000..4c78158dd5bf64 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/time/time_key.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ascending, bisector } from 'd3-array'; +import * as rt from 'io-ts'; + +export const minimalTimeKeyRT = rt.type({ + time: rt.number, + tiebreaker: rt.number, +}); + +export const timeKeyRT = rt.intersection([ + minimalTimeKeyRT, + rt.partial({ + gid: rt.string, + fromAutoReload: rt.boolean, + }), +]); +export type TimeKey = rt.TypeOf; + +export interface UniqueTimeKey extends TimeKey { + gid: string; +} + +export type Comparator = (firstValue: any, secondValue: any) => number; + +export function compareTimeKeys( + firstKey: TimeKey, + secondKey: TimeKey, + compareValues: Comparator = ascending +): number { + const timeComparison = compareValues(firstKey.time, secondKey.time); + + if (timeComparison === 0) { + const tiebreakerComparison = compareValues(firstKey.tiebreaker, secondKey.tiebreaker); + + if ( + tiebreakerComparison === 0 && + typeof firstKey.gid !== 'undefined' && + typeof secondKey.gid !== 'undefined' + ) { + return compareValues(firstKey.gid, secondKey.gid); + } + + return tiebreakerComparison; + } + + return timeComparison; +} + +export const compareToTimeKey = + (keyAccessor: (value: Value) => TimeKey, compareValues?: Comparator) => + (value: Value, key: TimeKey) => + compareTimeKeys(keyAccessor(value), key, compareValues); + +export const getIndexAtTimeKey = ( + keyAccessor: (value: Value) => TimeKey, + compareValues?: Comparator +) => { + const comparator = compareToTimeKey(keyAccessor, compareValues); + const collectionBisector = bisector(comparator); + + return (collection: Value[], key: TimeKey): number | null => { + const index = collectionBisector.left(collection, key); + + if (index >= collection.length) { + return null; + } + + if (comparator(collection[index], key) !== 0) { + return null; + } + + return index; + }; +}; diff --git a/x-pack/plugins/logs_shared/common/typed_json.ts b/x-pack/plugins/logs_shared/common/typed_json.ts new file mode 100644 index 00000000000000..95d5d4274c3b63 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/typed_json.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 * as rt from 'io-ts'; +import { JsonArray, JsonObject, JsonValue } from '@kbn/utility-types'; + +export type { JsonArray, JsonObject, JsonValue }; + +export const jsonScalarRT = rt.union([rt.null, rt.boolean, rt.number, rt.string]); +export type JsonScalar = rt.TypeOf; + +export const jsonValueRT: rt.Type = rt.recursion('JsonValue', () => + rt.union([jsonScalarRT, jsonArrayRT, jsonObjectRT]) +); + +export const jsonArrayRT: rt.Type = rt.recursion('JsonArray', () => + rt.array(jsonValueRT) +); + +export const jsonObjectRT: rt.Type = rt.recursion('JsonObject', () => + rt.record(rt.string, jsonValueRT) +); diff --git a/x-pack/plugins/logs_shared/jest.config.js b/x-pack/plugins/logs_shared/jest.config.js new file mode 100644 index 00000000000000..4d4168f2dbda47 --- /dev/null +++ b/x-pack/plugins/logs_shared/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/x-pack/plugins/logs_shared'], + coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/logs_shared', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/logs_shared/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/x-pack/plugins/logs_shared/kibana.jsonc b/x-pack/plugins/logs_shared/kibana.jsonc new file mode 100644 index 00000000000000..fea2ccc878485f --- /dev/null +++ b/x-pack/plugins/logs_shared/kibana.jsonc @@ -0,0 +1,22 @@ +{ + "type": "plugin", + "id": "@kbn/logs-shared-plugin", + "owner": "@elastic/infra-monitoring-ui", + "description": "Exposes the shared components and APIs to access and visualize logs.", + "plugin": { + "id": "logsShared", + "server": true, + "browser": true, + "configPath": ["xpack", "logs_shared"], + "requiredPlugins": ["data", "dataViews", "usageCollection", "observabilityShared"], + "optionalPlugins": ["observability"], + "requiredBundles": [ + "observability", + "kibanaUtils", + "kibanaReact", + ], + "extraPublicDirs": [ + "common", + ] + } +} diff --git a/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx b/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx new file mode 100644 index 00000000000000..a983502fa85b7e --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx @@ -0,0 +1,188 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { isEqual } from 'lodash'; +import React from 'react'; + +interface Measurement { + width?: number; + height?: number; +} + +interface Measurements { + bounds: Measurement; + content: Measurement; +} + +interface AutoSizerProps { + detectAnyWindowResize?: boolean | 'height' | 'width'; + bounds?: boolean; + content?: boolean; + onResize?: (size: Measurements) => void; + children: ( + args: { measureRef: (instance: HTMLElement | null) => any } & Measurements + ) => React.ReactNode; +} + +interface AutoSizerState { + boundsMeasurement: Measurement; + contentMeasurement: Measurement; +} + +export class AutoSizer extends React.PureComponent { + public element: HTMLElement | null = null; + public resizeObserver: ResizeObserver | null = null; + public windowWidth: number = -1; + public windowHeight: number = -1; + + public readonly state = { + boundsMeasurement: { + height: void 0, + width: void 0, + }, + contentMeasurement: { + height: void 0, + width: void 0, + }, + }; + + constructor(props: AutoSizerProps) { + super(props); + if (this.props.detectAnyWindowResize) { + window.addEventListener('resize', this.updateMeasurement); + } + this.resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => { + entries.forEach((entry) => { + if (entry.target === this.element) { + this.measure(entry); + } + }); + }); + } + + public componentWillUnmount() { + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + this.resizeObserver = null; + } + if (this.props.detectAnyWindowResize) { + window.removeEventListener('resize', this.updateMeasurement); + } + } + + public measure = (entry: ResizeObserverEntry | null) => { + if (!this.element) { + return; + } + + const { content = true, bounds = false } = this.props; + const { + boundsMeasurement: previousBoundsMeasurement, + contentMeasurement: previousContentMeasurement, + } = this.state; + + const boundsRect = bounds ? this.element.getBoundingClientRect() : null; + const boundsMeasurement = boundsRect + ? { + height: boundsRect.height, + width: boundsRect.width, + } + : previousBoundsMeasurement; + + if (this.props.detectAnyWindowResize && boundsMeasurement) { + if ( + boundsMeasurement.width && + this.windowWidth !== -1 && + this.windowWidth > window.innerWidth + ) { + const gap = this.windowWidth - window.innerWidth; + boundsMeasurement.width = boundsMeasurement.width - gap; + } + if ( + boundsMeasurement.height && + this.windowHeight !== -1 && + this.windowHeight > window.innerHeight + ) { + const gap = this.windowHeight - window.innerHeight; + boundsMeasurement.height = boundsMeasurement.height - gap; + } + } + this.windowWidth = window.innerWidth; + this.windowHeight = window.innerHeight; + const contentRect = content && entry ? entry.contentRect : null; + const contentMeasurement = + contentRect && entry + ? { + height: entry.contentRect.height, + width: entry.contentRect.width, + } + : previousContentMeasurement; + if ( + isEqual(boundsMeasurement, previousBoundsMeasurement) && + isEqual(contentMeasurement, previousContentMeasurement) + ) { + return; + } + + requestAnimationFrame(() => { + if (!this.resizeObserver) { + return; + } + + this.setState({ boundsMeasurement, contentMeasurement }); + + if (this.props.onResize) { + this.props.onResize({ + bounds: boundsMeasurement, + content: contentMeasurement, + }); + } + }); + }; + + public render() { + const { children } = this.props; + const { boundsMeasurement, contentMeasurement } = this.state; + return children({ + bounds: boundsMeasurement, + content: contentMeasurement, + measureRef: this.storeRef, + }); + } + + private updateMeasurement = () => + requestAnimationFrame(() => { + const { detectAnyWindowResize } = this.props; + if (!detectAnyWindowResize) return; + switch (detectAnyWindowResize) { + case 'height': + if (this.windowHeight !== window.innerHeight) { + this.measure(null); + } + break; + case 'width': + if (this.windowWidth !== window.innerWidth) { + this.measure(null); + } + break; + default: + this.measure(null); + } + }); + + private storeRef = (element: HTMLElement | null) => { + if (this.element && this.resizeObserver) { + this.resizeObserver.unobserve(this.element); + } + + if (element && this.resizeObserver) { + this.resizeObserver.observe(element); + } + + this.element = element; + }; +} diff --git a/x-pack/plugins/infra/public/components/centered_flyout_body.tsx b/x-pack/plugins/logs_shared/public/components/centered_flyout_body.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/centered_flyout_body.tsx rename to x-pack/plugins/logs_shared/public/components/centered_flyout_body.tsx diff --git a/x-pack/plugins/infra/public/components/data_search_error_callout.stories.tsx b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.stories.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/data_search_error_callout.stories.tsx rename to x-pack/plugins/logs_shared/public/components/data_search_error_callout.stories.tsx diff --git a/x-pack/plugins/infra/public/components/data_search_error_callout.tsx b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/data_search_error_callout.tsx rename to x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx index dd63b22db683dd..52e36002de73f4 100644 --- a/x-pack/plugins/infra/public/components/data_search_error_callout.tsx +++ b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx @@ -35,7 +35,7 @@ export const DataSearchErrorCallout: React.FC<{ onClick={onRetry} > @@ -59,7 +59,7 @@ const AbortedRequestErrorMessage: React.FC<{ }> = ({}) => ( ); @@ -73,7 +73,7 @@ const ShardFailureErrorMessage: React.FC<{ error: ShardFailureSearchStrategyErro }) => ( void; + testString?: string; +} + +export const NoData: React.FC = ({ + titleText, + bodyText, + refetchText, + onRefetch, + testString, +}) => ( + {titleText}} + titleSize="m" + body={

{bodyText}

} + actions={ + + {refetchText} + + } + data-test-subj={testString} + /> +); + +const CenteredEmptyPrompt = euiStyled(EuiEmptyPrompt)` + align-self: center; +`; diff --git a/x-pack/plugins/infra/public/components/formatted_time.tsx b/x-pack/plugins/logs_shared/public/components/formatted_time.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/formatted_time.tsx rename to x-pack/plugins/logs_shared/public/components/formatted_time.tsx diff --git a/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx b/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx new file mode 100644 index 00000000000000..879d8a2328ebc7 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { Meta, Story } from '@storybook/react/types-6-0'; +import React from 'react'; +import { LogsSharedLoadingPanel } from '..'; +import { decorateWithGlobalStorybookThemeProviders } from '../../../test_utils/use_global_storybook_theme'; + +export default { + title: 'logs_shared/LogsSharedLoadingPanel', + decorators: [ + (wrappedStory) =>
{wrappedStory()}
, + decorateWithGlobalStorybookThemeProviders, + ], +} as Meta; + +export const LoadingPanel: Story = () => ( + +); diff --git a/x-pack/plugins/logs_shared/public/components/loading/index.tsx b/x-pack/plugins/logs_shared/public/components/loading/index.tsx new file mode 100644 index 00000000000000..ca032885a89581 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/loading/index.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 { EuiLoadingChart, EuiPanel, EuiText } from '@elastic/eui'; +import * as React from 'react'; + +import { euiStyled } from '@kbn/kibana-react-plugin/common'; + +interface LogsSharedLoadingProps { + text: string | JSX.Element; + height: number | string; + width: number | string; +} + +export class LogsSharedLoadingPanel extends React.PureComponent { + public render() { + const { height, text, width } = this.props; + return ( + + + + + +

{text}

+
+
+
+
+ ); + } +} + +export const LogsSharedLoadingStaticPanel = euiStyled.div` + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; + justify-content: center; +`; + +export const LogsSharedLoadingStaticContentPanel = euiStyled.div` + flex: 0 0 auto; + align-self: center; + text-align: center; +`; diff --git a/x-pack/plugins/infra/public/components/log_stream/index.ts b/x-pack/plugins/logs_shared/public/components/log_stream/index.ts similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/index.ts rename to x-pack/plugins/logs_shared/public/components/log_stream/index.ts diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx similarity index 91% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx index b6e1d5f7fe0d8f..36bddaf0a11d25 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx +++ b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx @@ -1,15 +1,15 @@ import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks'; - + # Embeddable `` component The purpose of this component is to allow you, the developer, to have your very own Log Stream in your plugin. -The component is exposed through `infra/public`. Since Kibana uses relative paths, it is up to you to find how to import it (sorry). +The component is exposed through `logs_shared/public`. Since Kibana uses relative paths, it is up to you to find how to import it (sorry). ```tsx -import { LogStream } from '../../../../../../infra/public'; +import { LogStream } from '../../../../../../logs_shared/public'; // ^^ Modify appropriately ``` @@ -17,7 +17,7 @@ import { LogStream } from '../../../../../../infra/public'; To use the component your plugin needs to follow certain criteria: -- Ensure `"infra"` and `"data"` are specified as a `requiredPlugins` in your plugin's `kibana.json`. +- Ensure `"logsShared"` and `"data"` are specified as a `requiredPlugins` in your plugin's `kibana.json`. - Ensure the `` component is mounted inside the hierachy of a [`kibana-react` provider](https://github.com/elastic/kibana/blob/b2d0aa7b7fae1c89c8f9e8854ae73e71be64e765/src/plugins/kibana_react/README.md#L45). At a minimum, the kibana-react provider must pass `http` (from core start services) and `data` (from core plugin start dependencies). - Ensure the `` component is mounted inside the hierachy of a [`KibanaThemeProvider`](https://github.com/elastic/kibana/blob/31d2db035c905fb5819fa6dc2354f3be795a34cf/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx#L27). - Ensure the `` component is mounted inside the hierachy of a [`EuiThemeProvider`](https://github.com/elastic/kibana/blob/main/src/plugins/kibana_react/common/eui_styled_components.tsx). This is not the same as the provider exported by EUI. It bridges the gap between EUI and styled components and predates the css-in-js support in EUI. @@ -35,7 +35,7 @@ const startTimestamp = endTimestamp - 15 * 60 * 1000; // 15 minutes This will show a list of log entries between the specified timestamps. - + ## Query log entries @@ -80,7 +80,7 @@ The component also has a `filters` prop that accepts valid es-query `filters`. T ## Center the view on a specific entry -By default the component will load at the bottom of the list, showing the newest entries. You can change the rendering point with the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/infra/common/http_api/log_entries/common.ts#L9-L13). +By default the component will load at the bottom of the list, showing the newest entries. You can change the rendering point with the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/logs_shared/common/http_api/log_entries/common.ts#L9-L13). ```tsx ``` - + ## Highlight a specific entry @@ -100,7 +100,7 @@ The component can highlight a specific line via the `highlight` prop. It takes t ``` - + ## Column configuration @@ -131,7 +131,7 @@ The easiest way is to specify what columns you want with the `columns` prop. /> ``` - + The rendering of the column headers and the cell contents can also be customized with the following properties: @@ -206,7 +206,7 @@ The rendering of the column headers and the cell contents can also be customized /> ``` - + ### With a static log view configuration @@ -262,4 +262,4 @@ The component can render a button on the row that opens a flyout, via the `showF showFlyoutAction /> ``` - + diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.stories.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.story_decorators.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.story_decorators.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.story_decorators.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.story_decorators.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx index c2e025dcd5e755..cf60b902e3b330 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx +++ b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx @@ -33,7 +33,7 @@ const LogStreamErrorContent: React.FC<{ @@ -46,7 +46,7 @@ const LogStreamErrorContent: React.FC<{ diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/index.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/index.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/index.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/index.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx index e06149dd90d5ca..e99304a61b4534 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx @@ -8,7 +8,6 @@ import { EuiButton, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; -import { getApmTraceUrl } from '@kbn/observability-plugin/public'; import { useLinkProps, LinkDescriptor } from '@kbn/observability-shared-plugin/public'; import { useVisibilityState } from '../../../utils/use_visibility_state'; import { LogEntry } from '../../../../common/search_strategies/log_entries/log_entry'; @@ -45,7 +44,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { {...uptimeLinkProps} > , @@ -57,7 +56,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { {...apmLinkProps} > , @@ -78,7 +77,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { onClick={toggle} > @@ -142,3 +141,15 @@ const getAPMLink = (logEntry: LogEntry): LinkDescriptor | undefined => { pathname: getApmTraceUrl({ traceId, rangeFrom, rangeTo }), }; }; + +function getApmTraceUrl({ + traceId, + rangeFrom, + rangeTo, +}: { + traceId: string; + rangeFrom: string; + rangeTo: string; +}) { + return `/link-to/trace/${traceId}?` + new URLSearchParams({ rangeFrom, rangeTo }).toString(); +} diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx index a503c05011246f..09b83818593547 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx @@ -47,7 +47,7 @@ export const LogEntryFieldsTable: React.FC<{ () => [ { field: 'field', - name: i18n.translate('xpack.infra.logFlyout.fieldColumnLabel', { + name: i18n.translate('xpack.logsShared.logFlyout.fieldColumnLabel', { defaultMessage: 'Field', }), sortable: true, @@ -66,7 +66,7 @@ export const LogEntryFieldsTable: React.FC<{ }, { field: 'value', - name: i18n.translate('xpack.infra.logFlyout.valueColumnLabel', { + name: i18n.translate('xpack.logsShared.logFlyout.valueColumnLabel', { defaultMessage: 'Value', }), render: (_name: string, item: LogEntryField) => ( @@ -107,11 +107,11 @@ const searchOptions = { }, }; -const setFilterButtonLabel = i18n.translate('xpack.infra.logFlyout.filterAriaLabel', { +const setFilterButtonLabel = i18n.translate('xpack.logsShared.logFlyout.filterAriaLabel', { defaultMessage: 'Filter', }); -const setFilterButtonDescription = i18n.translate('xpack.infra.logFlyout.setFilterTooltip', { +const setFilterButtonDescription = i18n.translate('xpack.logsShared.logFlyout.setFilterTooltip', { defaultMessage: 'View event with filter', }); diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx similarity index 91% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx index 8237a36f5557dd..e06064c676a636 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx @@ -146,7 +146,7 @@ export const LogEntryFlyout = ({

{logEntryId} : '', }} @@ -158,7 +158,7 @@ export const LogEntryFlyout = ({ {logEntry.index}, @@ -237,18 +237,24 @@ export const LogEntryFlyout = ({ ); }; -const explainLogMessageTitle = i18n.translate('xpack.infra.logFlyout.explainLogMessageTitle', { +const explainLogMessageTitle = i18n.translate('xpack.logsShared.logFlyout.explainLogMessageTitle', { defaultMessage: "What's this message?", }); -const similarLogMessagesTitle = i18n.translate('xpack.infra.logFlyout.similarLogMessagesTitle', { - defaultMessage: 'How do I find similar log messages?', -}); +const similarLogMessagesTitle = i18n.translate( + 'xpack.logsShared.logFlyout.similarLogMessagesTitle', + { + defaultMessage: 'How do I find similar log messages?', + } +); -const loadingProgressMessage = i18n.translate('xpack.infra.logFlyout.loadingMessage', { +const loadingProgressMessage = i18n.translate('xpack.logsShared.logFlyout.loadingMessage', { defaultMessage: 'Searching log entry in shards', }); -const loadingErrorCalloutTitle = i18n.translate('xpack.infra.logFlyout.loadingErrorCalloutTitle', { - defaultMessage: 'Error while searching the log entry', -}); +const loadingErrorCalloutTitle = i18n.translate( + 'xpack.logsShared.logFlyout.loadingErrorCalloutTitle', + { + defaultMessage: 'Error while searching the log entry', + } +); diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx index 30355ea1a9a232..9e1d9330f7b87e 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx @@ -43,7 +43,7 @@ export const LogColumnHeaders: React.FunctionComponent<{ } else { columnHeader = firstVisiblePosition ? localizedDate(firstVisiblePosition.time) - : i18n.translate('xpack.infra.logs.stream.timestampColumnTitle', { + : i18n.translate('xpack.logsShared.logs.stream.timestampColumnTitle', { defaultMessage: 'Timestamp', }); } @@ -64,7 +64,7 @@ export const LogColumnHeaders: React.FunctionComponent<{ } else if (typeof columnConfiguration.messageColumn.header === 'string') { columnHeader = columnConfiguration.messageColumn.header; } else { - columnHeader = i18n.translate('xpack.infra.logs.stream.messageColumnTitle', { + columnHeader = i18n.translate('xpack.logsShared.logs.stream.messageColumnTitle', { defaultMessage: 'Message', }); } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/field_value.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/field_value.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/highlighting.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/highlighting.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/highlighting.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/highlighting.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts similarity index 79% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts index dbd5bd49d02407..dfccaae6dd8c9b 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts @@ -5,11 +5,14 @@ * 2.0. */ +export type { LogEntryStreamItem } from './item'; export type { LogEntryColumnWidths } from './log_entry_column'; -export { LogEntryColumn, useColumnWidths, iconColumnId } from './log_entry_column'; + +export { LogColumnHeader, LogColumnHeadersWrapper } from './column_headers'; +export { iconColumnId, LogEntryColumn, useColumnWidths } from './log_entry_column'; +export { LogEntryContextMenu } from './log_entry_context_menu'; export { LogEntryFieldColumn } from './log_entry_field_column'; export { LogEntryMessageColumn } from './log_entry_message_column'; export { LogEntryRowWrapper } from './log_entry_row'; export { LogEntryTimestampColumn } from './log_entry_timestamp_column'; export { ScrollableLogTextStreamView } from './scrollable_log_text_stream_view'; -export { LogEntryContextMenu } from './log_entry_context_menu'; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item.ts b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/item.ts similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/item.ts rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/item.ts diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx index 81bb3f299db57f..1f3f35d0d1a17e 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx @@ -24,7 +24,7 @@ export class LogTextStreamJumpToTail extends React.PureComponent @@ -36,7 +36,7 @@ export class LogTextStreamJumpToTail extends React.PureComponent diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx similarity index 89% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx index f0b0fc4236bfc1..9cd7c912505288 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx @@ -118,19 +118,19 @@ const ProgressMessage: React.FC = ({ timestamp, position, const message = position === 'start' ? ( ) : isStreaming ? ( ) : ( @@ -152,12 +152,12 @@ const ProgressSpinner: React.FC<{ kind: 'streaming' | 'loading' }> = ({ kind }) {kind === 'streaming' ? ( ) : ( )} @@ -182,7 +182,7 @@ const ProgressCta: React.FC = ({ if (rangeEdge === 'now' && position === 'end') { return ( - + ); } @@ -217,7 +217,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'ms': return ( @@ -225,7 +225,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 's': return ( @@ -233,7 +233,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'm': return ( @@ -241,7 +241,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'h': return ( @@ -249,7 +249,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'd': return ( @@ -257,7 +257,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'w': return ( @@ -265,7 +265,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'M': return ( @@ -273,7 +273,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'y': return ( diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_date_row.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_date_row.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_date_row.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_date_row.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx index ba87fa8c09bc41..17c7fb9dd7e9f0 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx @@ -35,7 +35,7 @@ interface LogEntryContextMenuProps { } const DEFAULT_MENU_LABEL = i18n.translate( - 'xpack.infra.logEntryItemView.logEntryActionsMenuToolTip', + 'xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip', { defaultMessage: 'View actions for line', } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx index 4a137ca361a406..2963a3e1aac144 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx @@ -32,16 +32,16 @@ import { LogEntryMessageColumn } from './log_entry_message_column'; import { LogEntryTimestampColumn } from './log_entry_timestamp_column'; import { highlightedContentStyle, hoveredContentStyle, monospaceTextStyle } from './text_styles'; -const MENU_LABEL = i18n.translate('xpack.infra.logEntryItemView.logEntryActionsMenuToolTip', { +const MENU_LABEL = i18n.translate('xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip', { defaultMessage: 'View actions for line', }); -const LOG_DETAILS_LABEL = i18n.translate('xpack.infra.logs.logEntryActionsDetailsButton', { +const LOG_DETAILS_LABEL = i18n.translate('xpack.logsShared.logs.logEntryActionsDetailsButton', { defaultMessage: 'View details', }); const LOG_VIEW_IN_CONTEXT_LABEL = i18n.translate( - 'xpack.infra.lobs.logEntryActionsViewInContextButton', + 'xpack.logsShared.lobs.logEntryActionsViewInContextButton', { defaultMessage: 'View in context', } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_text_separator.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_text_separator.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/measurable_item_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/measurable_item_view.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/measurable_item_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/measurable_item_view.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx index 4c11bd21daa193..8a0a120a3a7d5d 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx @@ -16,7 +16,7 @@ import { TimeKey, UniqueTimeKey } from '../../../../common/time'; import { callWithoutRepeats } from '../../../utils/handlers'; import { AutoSizer } from '../../auto_sizer'; import { NoData } from '../../empty_states'; -import { InfraLoadingPanel } from '../../loading'; +import { LogsSharedLoadingPanel } from '../../loading'; import { getStreamItemBeforeTimeKey, getStreamItemId, parseStreamItemId, StreamItem } from './item'; import { LogColumnHeaders } from './column_headers'; import { LogTextStreamLoadingItemView } from './loading_item_view'; @@ -160,27 +160,30 @@ export class ScrollableLogTextStreamView extends React.PureComponent< return ( {isReloading && (!isStreaming || !hasItems) ? ( - } /> ) : !hasItems ? ( @@ -368,6 +371,9 @@ export class ScrollableLogTextStreamView extends React.PureComponent< }; } +// eslint-disable-next-line import/no-default-export +export default ScrollableLogTextStreamView; + /** * If the above component wasn't a class component, this wouldn't be necessary * since the `useColumnWidths` hook could have been used directly. diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/text_styles.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/text_styles.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/vertical_scroll_panel.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/vertical_scroll_panel.tsx diff --git a/x-pack/plugins/infra/public/components/resettable_error_boundary.tsx b/x-pack/plugins/logs_shared/public/components/resettable_error_boundary.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/resettable_error_boundary.tsx rename to x-pack/plugins/logs_shared/public/components/resettable_error_boundary.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_entry.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_entry.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_entry.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx similarity index 98% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx index ea0e1fa326c78e..6e13ff542add6d 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx @@ -6,7 +6,7 @@ */ import { useEffect, useMemo, useState } from 'react'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { LogEntriesHighlightsResponse } from '../../../../common/http_api'; import { LogEntry } from '../../../../common/log_entry'; import { TimeKey } from '../../../../common/time'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx similarity index 96% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx index 0a6710731bcb18..aa963925d7ac92 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx @@ -8,12 +8,13 @@ import createContainer from 'constate'; import { useState } from 'react'; import useThrottle from 'react-use/lib/useThrottle'; -import { LogViewReference } from '../../../../common/log_views'; + +import { LogViewReference } from '../../../../common'; import { useLogEntryHighlights } from './log_entry_highlights'; import { useLogSummaryHighlights } from './log_summary_highlights'; import { useNextAndPrevious } from './next_and_previous'; -import { useLogPositionStateContext } from '../log_position'; import { TimeKey } from '../../../../common/time'; +import { useLogPositionStateContext } from '../log_position'; const FETCH_THROTTLE_INTERVAL = 3000; @@ -25,7 +26,7 @@ interface UseLogHighlightsStateProps { filterQuery: string | null; } -export const useLogHighlightsState = ({ +const useLogHighlightsState = ({ logViewReference, sourceVersion, centerCursor, diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts similarity index 97% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts index 8c5f7fb7ae778c..61a1a02618e7a4 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts @@ -8,7 +8,7 @@ import { useEffect, useMemo, useState } from 'react'; import { debounce } from 'lodash'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogSummaryHighlights } from './api/fetch_log_summary_highlights'; import { LogEntriesSummaryHighlightsResponse } from '../../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/next_and_previous.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/next_and_previous.tsx similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/next_and_previous.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/next_and_previous.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_position/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_position/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_position/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts similarity index 80% rename from x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts index 2471acf6e92834..236e59093d450f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts @@ -5,15 +5,28 @@ * 2.0. */ +import { TimeRange } from '@kbn/es-query'; import createContainer from 'constate'; import { useMemo } from 'react'; -import { VisiblePositions } from '../../../observability_logs/log_stream_position_state/src/types'; -import { - LogStreamPageActorRef, - LogStreamPageCallbacks, -} from '../../../observability_logs/log_stream_page/state'; -import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; +import { ActorRefWithDeprecatedState } from 'xstate'; import { TimeKey } from '../../../../common/time'; +import { + MatchedStateFromActor, + OmitDeprecatedState, +} from '../../../observability_logs/xstate_helpers'; + +type LogStreamPageState = MatchedStateFromActor< + OmitDeprecatedState>, + { hasLogViewIndices: 'initialized' } +>; + +interface VisiblePositions { + startKey: TimeKey | null; + middleKey: TimeKey | null; + endKey: TimeKey | null; + pagesAfterEnd: number; + pagesBeforeStart: number; +} type TimeKeyOrNull = TimeKey | null; @@ -46,6 +59,15 @@ export interface LogPositionCallbacks { updateDateRange: UpdateDateRangeFn; } +export interface LogStreamPageCallbacks { + updateTimeRange: (timeRange: Partial) => void; + jumpToTargetPosition: (targetPosition: TimeKey | null) => void; + jumpToTargetPositionTime: (time: number) => void; + reportVisiblePositions: (visiblePositions: VisiblePositions) => void; + startLiveStreaming: () => void; + stopLiveStreaming: () => void; +} + type UpdateDateRangeFn = ( newDateRange: Partial> ) => void; @@ -54,7 +76,7 @@ export const useLogPositionState = ({ logStreamPageState, logStreamPageCallbacks, }: { - logStreamPageState: InitializedLogStreamPageState; + logStreamPageState: LogStreamPageState; logStreamPageCallbacks: LogStreamPageCallbacks; }): LogPositionStateParams & LogPositionCallbacks => { const dateRange = useMemo(() => getLegacyDateRange(logStreamPageState), [logStreamPageState]); @@ -119,7 +141,7 @@ export const useLogPositionState = ({ export const [LogPositionStateProvider, useLogPositionStateContext] = createContainer(useLogPositionState); -const getLegacyDateRange = (logStreamPageState: InitializedLogStreamPageState): DateRange => { +const getLegacyDateRange = (logStreamPageState: LogStreamPageState): DateRange => { return { startDateExpression: logStreamPageState.context.timeRange.from, endDateExpression: logStreamPageState.context.timeRange.to, @@ -130,8 +152,3 @@ const getLegacyDateRange = (logStreamPageState: InitializedLogStreamPageState): timestampsLastUpdate: logStreamPageState.context.timestamps.lastChangedTimestamp, }; }; - -type InitializedLogStreamPageState = MatchedStateFromActor< - LogStreamPageActorRef, - { hasLogViewIndices: 'initialized' } ->; diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_after.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_after.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_around.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_around.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_before.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_before.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/api/fetch_log_summary.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/api/fetch_log_summary.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/bucket_size.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/bucket_size.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/bucket_size.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/bucket_size.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.test.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx similarity index 97% rename from x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx index c2792300c5f34c..0360d6d381adab 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx @@ -8,7 +8,7 @@ import { useEffect } from 'react'; import { exhaustMap, map, Observable } from 'rxjs'; import { HttpHandler } from '@kbn/core-http-browser'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { useObservableState, useReplaySubject } from '../../../utils/use_observable'; import { fetchLogSummary } from './api/fetch_log_summary'; import { LogEntriesSummaryRequest, LogEntriesSummaryResponse } from '../../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts similarity index 66% rename from x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts index 1dc5c7021d253e..5d18926cca294a 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts @@ -5,32 +5,24 @@ * 2.0. */ -import { useSelector } from '@xstate/react'; -import stringify from 'json-stable-stringify'; import useThrottle from 'react-use/lib/useThrottle'; -import { useLogViewContext } from '../../../hooks/use_log_view'; -import { useLogStreamPageStateContext } from '../../../observability_logs/log_stream_page/state'; +import { useLogPositionStateContext, useLogViewContext } from '../../..'; import { RendererFunction } from '../../../utils/typed_react'; -import { useLogPositionStateContext } from '../log_position'; import { LogSummaryBuckets, useLogSummary } from './log_summary'; const FETCH_THROTTLE_INTERVAL = 3000; -export const WithSummary = ({ - children, -}: { +export interface WithSummaryProps { + serializedParsedQuery: string | null; children: RendererFunction<{ buckets: LogSummaryBuckets; start: number | null; end: number | null; }>; -}) => { +} + +export const WithSummary = ({ serializedParsedQuery, children }: WithSummaryProps) => { const { logViewReference } = useLogViewContext(); - const serializedParsedQuery = useSelector(useLogStreamPageStateContext(), (logStreamPageState) => - logStreamPageState.matches({ hasLogViewIndices: 'initialized' }) - ? stringify(logStreamPageState.context.parsedQuery) - : null - ); const { startTimestamp, endTimestamp } = useLogPositionStateContext(); // Keep it reasonably updated for the `now` case, but don't reload all the time when the user scrolls diff --git a/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx b/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx new file mode 100644 index 00000000000000..09032b4b644a2a --- /dev/null +++ b/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PropsOf } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { CoreStart } from '@kbn/core/public'; +import { + createKibanaReactContext, + KibanaReactContextValue, + useKibana, +} from '@kbn/kibana-react-plugin/public'; +import { + LogsSharedClientCoreSetup, + LogsSharedClientStartDeps, + LogsSharedClientStartExports, +} from '../types'; + +export type PluginKibanaContextValue = CoreStart & + LogsSharedClientStartDeps & + LogsSharedClientStartExports; + +export const createKibanaContextForPlugin = ( + core: CoreStart, + plugins: LogsSharedClientStartDeps, + pluginStart: LogsSharedClientStartExports +) => + createKibanaReactContext({ + ...core, + ...plugins, + ...pluginStart, + }); + +export const useKibanaContextForPlugin = + useKibana as () => KibanaReactContextValue; + +export const useKibanaContextForPluginProvider = ( + core: CoreStart, + plugins: LogsSharedClientStartDeps, + pluginStart: LogsSharedClientStartExports +) => { + const { Provider } = useMemo( + () => createKibanaContextForPlugin(core, plugins, pluginStart), + [core, pluginStart, plugins] + ); + + return Provider; +}; + +export const createLazyComponentWithKibanaContext = >( + coreSetup: LogsSharedClientCoreSetup, + lazyComponentFactory: () => Promise<{ default: T }> +) => + React.lazy(() => + Promise.all([lazyComponentFactory(), coreSetup.getStartServices()]).then( + ([{ default: LazilyLoadedComponent }, [core, plugins, pluginStart]]) => { + const { Provider } = createKibanaContextForPlugin(core, plugins, pluginStart); + + return { + default: (props: PropsOf) => ( + + + + ), + }; + } + ) + ); diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/logs_shared/public/hooks/use_log_view.ts similarity index 100% rename from x-pack/plugins/infra/public/hooks/use_log_view.ts rename to x-pack/plugins/logs_shared/public/hooks/use_log_view.ts diff --git a/x-pack/plugins/logs_shared/public/index.ts b/x-pack/plugins/logs_shared/public/index.ts new file mode 100644 index 00000000000000..63692bbdeae54e --- /dev/null +++ b/x-pack/plugins/logs_shared/public/index.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { dynamic } from '../common/dynamic'; +import { LogsSharedPlugin } from './plugin'; + +export type { + LogsSharedClientSetupExports, + LogsSharedClientStartExports, + LogsSharedClientSetupDeps, + LogsSharedClientStartDeps, +} from './types'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new LogsSharedPlugin(); +} + +// Containers & Hook +export { LogViewProvider, useLogViewContext, useLogView } from './hooks/use_log_view'; +export { LogStreamProvider, useLogStreamContext } from './containers/logs/log_stream'; +export { + LogPositionStateProvider, + useLogPositionStateContext, +} from './containers/logs/log_position'; +export { + LogHighlightsStateProvider, + useLogHighlightsStateContext, +} from './containers/logs/log_highlights'; +export type { LogSummaryBuckets, WithSummaryProps } from './containers/logs/log_summary'; +export { useLogSummary, WithSummary } from './containers/logs/log_summary'; +export { useLogEntryFlyout } from './components/logging/log_entry_flyout'; + +// Shared components +export type { + LogEntryStreamItem, + LogEntryColumnWidths, +} from './components/logging/log_text_stream'; +export { + iconColumnId, + useColumnWidths, +} from './components/logging/log_text_stream/log_entry_column'; +export { LogEntryFlyout } from './components/logging/log_entry_flyout'; +export type { LogStreamProps } from './components/log_stream/log_stream'; + +export const LogStream = dynamic(() => import('./components/log_stream/log_stream')); +export const LogColumnHeader = dynamic( + () => import('./components/logging/log_text_stream/column_headers') +); +export const LogColumnHeadersWrapper = dynamic( + () => import('./components/logging/log_text_stream/column_headers') +); +export const LogEntryColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_column') +); +export const LogEntryContextMenu = dynamic( + () => import('./components/logging/log_text_stream/log_entry_context_menu') +); +export const LogEntryFieldColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_field_column') +); +export const LogEntryMessageColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_message_column') +); +export const LogEntryRowWrapper = dynamic( + () => import('./components/logging/log_text_stream/log_entry_row') +); +export const LogEntryTimestampColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_timestamp_column') +); +export const ScrollableLogTextStreamView = dynamic( + () => import('./components/logging/log_text_stream/scrollable_log_text_stream_view') +); + +// State machine utils +export { + getLogViewReferenceFromUrl, + initializeFromUrl, + listenForUrlChanges, + updateContextInUrl, +} from './observability_logs/log_view_state'; +export type { + LogViewContextWithError, + LogViewContextWithResolvedLogView, + LogViewNotificationChannel, + LogViewNotificationEvent, +} from './observability_logs/log_view_state'; diff --git a/x-pack/plugins/logs_shared/public/mocks.tsx b/x-pack/plugins/logs_shared/public/mocks.tsx new file mode 100644 index 00000000000000..963480d8fd90fb --- /dev/null +++ b/x-pack/plugins/logs_shared/public/mocks.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 { createLogViewsServiceStartMock } from './services/log_views/log_views_service.mock'; +import { LogsSharedClientStartExports } from './types'; + +export const createLogsSharedPluginStartMock = (): jest.Mocked => ({ + logViews: createLogViewsServiceStartMock(), +}); + +export const _ensureTypeCompatibility = (): LogsSharedClientStartExports => + createLogsSharedPluginStartMock(); diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/README.md b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/README.md similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/README.md rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/README.md diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/index.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/index.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/index.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/index.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/index.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/notifications.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/notifications.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/state_machine.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/state_machine.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/types.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/types.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/url_state_storage_service.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/url_state_storage_service.ts diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md new file mode 100644 index 00000000000000..337f65add42264 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md @@ -0,0 +1,3 @@ +# @kbn/observability-logs-xstate-helpers + +Helpers to design well-typed state machines with XState diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts new file mode 100644 index 00000000000000..3b2a320ae181f5 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/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 * from './src'; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts new file mode 100644 index 00000000000000..340087bb31fc83 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './notification_channel'; +export * from './types'; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts new file mode 100644 index 00000000000000..0108ab0225176c --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ReplaySubject } from 'rxjs'; +import { ActionFunction, EventObject, Expr, Subscribable } from 'xstate'; + +export interface NotificationChannel { + createService: () => Subscribable; + notify: ( + eventExpr: Expr + ) => ActionFunction; +} + +export const createNotificationChannel = < + TContext, + TEvent extends EventObject, + TSentEvent +>(): NotificationChannel => { + const eventsSubject = new ReplaySubject(1); + + const createService = () => eventsSubject.asObservable(); + + const notify = + (eventExpr: Expr) => + (context: TContext, event: TEvent) => { + const eventToSend = eventExpr(context, event); + + if (eventToSend != null) { + eventsSubject.next(eventToSend); + } + }; + + return { + createService, + notify, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts new file mode 100644 index 00000000000000..05e75c5fe6e459 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ActorRef, ActorRefWithDeprecatedState, EmittedFrom, State, StateValue } from 'xstate'; + +export type OmitDeprecatedState> = Omit< + T, + 'state' +>; + +export type MatchedState< + TState extends State, + TStateValue extends StateValue +> = TState extends State< + any, + infer TEvent, + infer TStateSchema, + infer TTypestate, + infer TResolvedTypesMeta +> + ? State< + (TTypestate extends any + ? { value: TStateValue; context: any } extends TTypestate + ? TTypestate + : never + : never)['context'], + TEvent, + TStateSchema, + TTypestate, + TResolvedTypesMeta + > & { + value: TStateValue; + } + : never; + +export type MatchedStateFromActor< + TActorRef extends ActorRef, + TStateValue extends StateValue +> = MatchedState, TStateValue>; diff --git a/x-pack/plugins/logs_shared/public/plugin.ts b/x-pack/plugins/logs_shared/public/plugin.ts new file mode 100644 index 00000000000000..47ded2e3df8352 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/plugin.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 { CoreStart } from '@kbn/core/public'; +import { LogViewsService } from './services/log_views'; +import { LogsSharedClientPluginClass, LogsSharedClientStartDeps } from './types'; + +export class LogsSharedPlugin implements LogsSharedClientPluginClass { + private logViews: LogViewsService; + + constructor() { + this.logViews = new LogViewsService(); + } + + public setup() { + const logViews = this.logViews.setup(); + + return { logViews }; + } + + public start(core: CoreStart, plugins: LogsSharedClientStartDeps) { + const logViews = this.logViews.start({ + http: core.http, + dataViews: plugins.dataViews, + search: plugins.data.search, + }); + + return { + logViews, + }; + } + + public stop() {} +} diff --git a/x-pack/plugins/infra/public/services/log_views/index.ts b/x-pack/plugins/logs_shared/public/services/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/index.ts rename to x-pack/plugins/logs_shared/public/services/log_views/index.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.mock.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_client.mock.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_client.mock.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_client.mock.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_client.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_client.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_client.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_service.mock.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.mock.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_service.mock.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_service.mock.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_service.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts similarity index 61% rename from x-pack/plugins/infra/public/services/log_views/log_views_service.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts index 9e081a8df50285..712196c95205ca 100644 --- a/x-pack/plugins/infra/public/services/log_views/log_views_service.ts +++ b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts @@ -5,17 +5,23 @@ * 2.0. */ -import { LogViewsStaticConfig } from '../../../common/log_views'; +import { defaultLogViewsStaticConfig, LogViewsStaticConfig } from '../../../common/log_views'; import { LogViewsClient } from './log_views_client'; import { LogViewsServiceStartDeps, LogViewsServiceSetup, LogViewsServiceStart } from './types'; export class LogViewsService { - constructor(private readonly config: LogViewsStaticConfig) {} + private logViewsStaticConfig: LogViewsStaticConfig = defaultLogViewsStaticConfig; - public setup(): LogViewsServiceSetup {} + public setup(): LogViewsServiceSetup { + return { + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => { + this.logViewsStaticConfig = config; + }, + }; + } public start({ dataViews, http, search }: LogViewsServiceStartDeps): LogViewsServiceStart { - const client = new LogViewsClient(dataViews, http, search.search, this.config); + const client = new LogViewsClient(dataViews, http, search.search, this.logViewsStaticConfig); return { client, diff --git a/x-pack/plugins/infra/public/services/log_views/types.ts b/x-pack/plugins/logs_shared/public/services/log_views/types.ts similarity index 90% rename from x-pack/plugins/infra/public/services/log_views/types.ts rename to x-pack/plugins/logs_shared/public/services/log_views/types.ts index 6fd7a4d208b3cd..58a504be789bc2 100644 --- a/x-pack/plugins/infra/public/services/log_views/types.ts +++ b/x-pack/plugins/logs_shared/public/services/log_views/types.ts @@ -12,11 +12,14 @@ import { LogView, LogViewAttributes, LogViewReference, + LogViewsStaticConfig, LogViewStatus, ResolvedLogView, } from '../../../common/log_views'; -export type LogViewsServiceSetup = void; +export interface LogViewsServiceSetup { + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => void; +} export interface LogViewsServiceStart { client: ILogViewsClient; diff --git a/x-pack/plugins/logs_shared/public/test_utils/entries.ts b/x-pack/plugins/logs_shared/public/test_utils/entries.ts new file mode 100644 index 00000000000000..4dc3732fd49d5d --- /dev/null +++ b/x-pack/plugins/logs_shared/public/test_utils/entries.ts @@ -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 faker from 'faker'; +import { LogEntry } from '../../common/log_entry'; +import { LogViewColumnConfiguration } from '../../common/log_views'; + +export const ENTRIES_EMPTY = { + data: { + entries: [], + topCursor: null, + bottomCursor: null, + }, +}; + +export function generateFakeEntries( + count: number, + startTimestamp: number, + endTimestamp: number, + columns: LogViewColumnConfiguration[] +): LogEntry[] { + const entries: LogEntry[] = []; + const timestampStep = Math.floor((endTimestamp - startTimestamp) / count); + for (let i = 0; i < count; i++) { + const timestamp = i === count - 1 ? endTimestamp : startTimestamp + timestampStep * i; + entries.push({ + id: `entry-${i}`, + index: 'logs-fake', + context: {}, + cursor: { time: timestamp, tiebreaker: i }, + columns: columns.map((column) => { + if ('timestampColumn' in column) { + return { columnId: column.timestampColumn.id, timestamp }; + } else if ('messageColumn' in column) { + return { + columnId: column.messageColumn.id, + message: [{ field: 'message', value: [fakeColumnValue('message')], highlights: [] }], + }; + } else { + return { + columnId: column.fieldColumn.id, + field: column.fieldColumn.field, + value: [fakeColumnValue(column.fieldColumn.field)], + highlights: [], + }; + } + }), + }); + } + + return entries; +} + +function fakeColumnValue(field: string): string { + switch (field) { + case 'message': + return faker.fake( + '{{internet.ip}} - [{{date.past}}] "GET {{internet.url}} HTTP/1.1" 200 {{random.number}} "-" "{{internet.userAgent}}"' + ); + case 'event.dataset': + return faker.fake('{{hacker.noun}}.{{hacker.noun}}'); + case 'log.file.path': + return faker.system.filePath(); + case 'log.level': + return faker.random.arrayElement(['debug', 'info', 'warn', 'error']); + case 'host.name': + return faker.hacker.noun(); + default: + return faker.lorem.sentence(); + } +} diff --git a/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx new file mode 100644 index 00000000000000..4d1feb4617dcf3 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DecoratorFn } from '@storybook/react'; +import React, { useEffect, useMemo, useState } from 'react'; +import { BehaviorSubject } from 'rxjs'; +import type { CoreTheme } from '@kbn/core/public'; +import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; + +type StoryContext = Parameters[1]; + +export const useGlobalStorybookTheme = ({ globals: { euiTheme } }: StoryContext) => { + const theme = useMemo(() => euiThemeFromId(euiTheme), [euiTheme]); + const [theme$] = useState(() => new BehaviorSubject(theme)); + + useEffect(() => { + theme$.next(theme); + }, [theme$, theme]); + + return { + theme, + theme$, + }; +}; + +export const GlobalStorybookThemeProviders: React.FC<{ storyContext: StoryContext }> = ({ + children, + storyContext, +}) => { + const { theme, theme$ } = useGlobalStorybookTheme(storyContext); + return ( + + {children} + + ); +}; + +export const decorateWithGlobalStorybookThemeProviders: DecoratorFn = ( + wrappedStory, + storyContext +) => ( + + {wrappedStory()} + +); + +const euiThemeFromId = (themeId: string): CoreTheme => { + switch (themeId) { + case 'v8.dark': + return { darkMode: true }; + default: + return { darkMode: false }; + } +}; diff --git a/x-pack/plugins/logs_shared/public/types.ts b/x-pack/plugins/logs_shared/public/types.ts new file mode 100644 index 00000000000000..f2563ccb3433fe --- /dev/null +++ b/x-pack/plugins/logs_shared/public/types.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. + */ + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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, CoreStart, Plugin as PluginClass } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +// import type { OsqueryPluginStart } from '../../osquery/public'; +import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views'; + +// Our own setup and start contract values +export interface LogsSharedClientSetupExports { + logViews: LogViewsServiceSetup; +} + +export interface LogsSharedClientStartExports { + logViews: LogViewsServiceStart; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface LogsSharedClientSetupDeps {} + +export interface LogsSharedClientStartDeps { + data: DataPublicPluginStart; + dataViews: DataViewsPublicPluginStart; + uiActions: UiActionsStart; +} + +export type LogsSharedClientCoreSetup = CoreSetup< + LogsSharedClientStartDeps, + LogsSharedClientStartExports +>; +export type LogsSharedClientCoreStart = CoreStart; +export type LogsSharedClientPluginClass = PluginClass< + LogsSharedClientSetupExports, + LogsSharedClientStartExports, + LogsSharedClientSetupDeps, + LogsSharedClientStartDeps +>; + +export type UnwrapPromise> = T extends Promise ? Value : never; + +export type LogsSharedClientStartServicesAccessor = LogsSharedClientCoreSetup['getStartServices']; +export type LogsSharedClientStartServices = UnwrapPromise< + ReturnType +>; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx b/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx new file mode 100644 index 00000000000000..a8854692caa36c --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx @@ -0,0 +1,152 @@ +import { Canvas, Meta, Story } from '@storybook/addon-docs/blocks'; + + + +# The `data` plugin and `SearchStrategies` + +The search functionality abstraction provided by the `search` service of the +`data` plugin is pretty powerful: + +- The execution of the request is delegated to a search strategy, which is + executed on the Kibana server side. +- Any plugin can register custom search strategies with custom parameters and + response shapes. +- Search requests can be cancelled via an `AbortSignal`. +- Search requests are decoupled from the transport layer. The service will poll + for new results transparently. +- Partial responses can be returned as they become available if the search + takes longer. + +# Working with `data.search.search()` in the Browser + +The following chapters describe a set of React components and hooks that aim to +make it easy to take advantage of these characteristics from client-side React +code. They implement a producer/consumer pattern that decouples the craeation +of search requests from the consumption of the responses. This keeps each +code-path small and encourages the use of reactive processing, which in turn +reduces the risk of race conditions and incorrect assumptions about the +response timing. + +## Issuing new requests + +The main API to issue new requests is the `data.search.search()` function. It +returns an `Observable` representing the stream of partial and final results +without the consumer having to know the underlying transport mechanisms. +Besides receiving a search-strategy-specific parameter object, it supports +selection of the search strategy as well an `AbortSignal` used for request +cancellation. + +The hook `useDataSearch()` is designed to ease the integration between the +`Observable` world and the React world. It uses the function it is given to +derive the parameters to use for the next search request. The request can then +be issued by calling the returned `search()` function. For each new request the +hook emits an object describing the request and its state in the `requests$` +`Observable`. + +Since the specific response shape depends on the data strategy used, the hook +takes a projection function, that is responsible for decoding the response in +an appropriate way. Because most response projections follow a similar pattern +there's a helper `normalizeDataSearchResponses(initialResponse, +parseRawResponse)`, which generates an RxJS operator, that... + +- emits an initial response containing the given `initialResponse` value +- applies `parseRawResponse` to the `rawResponse` property of each emitted response +- transforms transport layer errors as well as parsing errors into + `SearchStrategyError`s + +```typescript +const parseMyCustomSearchResponse = normalizeDataSearchResponses( + 'initial value', + decodeOrThrow(myCustomSearchResponsePayloadRT) +); + +const { search, requests$ } = useDataSearch({ + getRequest: useCallback((searchTerm: string) => ({ + request: { + params: { + searchTerm + }, + options: { + strategy: 'my-custom-search-strategy', + }, + }, + }), []), + parseResponses: parseMyCustomSearchResponse, +}); +``` + +## Executing requests and consuming the responses + +The response `Observable`s emitted by `data.search.search()` is "cold", so it +won't be executed unless a subscriber subscribes to it. And in order to cleanly +cancel and garbage collect the subscription it should be integrated with the +React component life-cycle. + +The `useLatestPartialDataSearchResponse()` does that in such a way that the +newest response observable is subscribed to and that any previous response +observables are unsubscribed from for proper cancellation if a new request has +been created. This uses RxJS's `switchMap()` operator under the hood. The hook +also makes sure that all observables are unsubscribed from on unmount. + +A request can fail due to various reasons that include servers-side errors, +Elasticsearch shard failures and network failures. The intention is to map all +of them to a common `SearchStrategyError` interface. While the +`useLatestPartialDataSearchResponse()` hook does that for errors emitted +natively by the response `Observable`, it's the responsibility of the +projection function to handle errors that are encoded in the response body, +which includes most server-side errors. Note that errors and partial results in +a response are not mutually exclusive. + +The request status (running, partial, etc), the response +and the errors are turned in to React component state so they can be used in +the usual rendering cycle: + +```typescript +const { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, +} = useLatestPartialDataSearchResponse(requests$); +``` + +## Representing the request state to the user + +After the values have been made available to the React rendering process using +the `useLatestPartialDataSearchResponse()` hook, normal component hierarchies +can be used to make the request state and result available to the user. The +following utility components can make that even easier. + +### Undetermined progress + +If `total` and `loaded` are not (yet) known, we can show an undetermined +progress bar. + + + + + +### Known progress + +If `total` and `loaded` are returned by the search strategy, they can be used +to show a progress bar with the option to cancel the request if it takes too +long. + + + + + +### Failed requests + +Assuming the errors are represented as an array of `SearchStrategyError`s in +the `latestResponseErrors` return value, they can be rendered as appropriate +for the respective part of the UI. For many cases a `EuiCallout` is suitable, +so the `DataSearchErrorCallout` can serve as a starting point: + + + + + diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts b/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts new file mode 100644 index 00000000000000..52f08f39bc2d4f --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { map } from 'rxjs/operators'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { ParsedDataSearchRequestDescriptor } from './types'; + +export const flattenDataSearchResponseDescriptor = < + Request extends IKibanaSearchRequest, + Response +>({ + abortController, + options, + request, + response$, +}: ParsedDataSearchRequestDescriptor) => + response$.pipe( + map((response) => { + return { + abortController, + options, + request, + response, + }; + }) + ); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/index.ts b/x-pack/plugins/logs_shared/public/utils/data_search/index.ts new file mode 100644 index 00000000000000..bd1881a6935e93 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './flatten_data_search_response'; +export * from './normalize_data_search_responses'; +export * from './types'; +export * from './use_data_search_request'; +export * from './use_data_search_response_state'; +export * from './use_latest_partial_data_search_response'; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts b/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts new file mode 100644 index 00000000000000..0056b7466759af --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { Observable, of } from 'rxjs'; +import { catchError, map, startWith } from 'rxjs/operators'; +import { IKibanaSearchResponse } from '@kbn/data-plugin/public'; +import { AbortError } from '@kbn/kibana-utils-plugin/public'; +import { SearchStrategyError } from '../../../common/search_strategies/common/errors'; +import { ParsedKibanaSearchResponse } from './types'; + +export type RawResponseParser = (rawResponse: RawResponse) => { + data: Response; + errors?: SearchStrategyError[]; +}; + +/** + * An operator factory that normalizes each {@link IKibanaSearchResponse} by + * parsing it into a {@link ParsedKibanaSearchResponse} and adding initial + * responses and error handling. + * + * @param initialResponse - The initial value to emit when a new request is + * handled. + * @param projectResponse - The projection function to apply to each response + * payload. It should validate that the response payload is of the type {@link + * RawResponse} and decode it to a {@link Response}. + * + * @return An operator that adds parsing and error handling transformations to + * each response payload using the arguments given above. + */ +export const normalizeDataSearchResponses = + ( + initialResponse: InitialResponse, + parseRawResponse: RawResponseParser + ) => + ( + response$: Observable> + ): Observable> => + response$.pipe( + map((response) => { + const { data, errors = [] } = parseRawResponse(response.rawResponse); + return { + data, + errors, + isPartial: response.isPartial ?? false, + isRunning: response.isRunning ?? false, + loaded: response.loaded, + total: response.total, + }; + }), + startWith({ + data: initialResponse, + errors: [], + isPartial: true, + isRunning: true, + loaded: 0, + total: undefined, + }), + catchError((error) => + of({ + data: initialResponse, + errors: [ + error instanceof AbortError + ? { + type: 'aborted' as const, + } + : { + type: 'generic' as const, + message: `${error.message ?? error}`, + }, + ], + isPartial: true, + isRunning: false, + loaded: 0, + total: undefined, + }) + ) + ); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/types.ts b/x-pack/plugins/logs_shared/public/utils/data_search/types.ts new file mode 100644 index 00000000000000..3e2c6a15487b81 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/types.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { Observable } from 'rxjs'; +import { + IKibanaSearchRequest, + IKibanaSearchResponse, + ISearchOptions, +} from '@kbn/data-plugin/public'; +import { SearchStrategyError } from '../../../common/search_strategies/common/errors'; + +export interface DataSearchRequestDescriptor { + request: Request; + options: ISearchOptions; + response$: Observable>; + abortController: AbortController; +} + +export interface ParsedDataSearchRequestDescriptor< + Request extends IKibanaSearchRequest, + ResponseData +> { + request: Request; + options: ISearchOptions; + response$: Observable>; + abortController: AbortController; +} + +export interface ParsedKibanaSearchResponse { + total?: number; + loaded?: number; + isRunning: boolean; + isPartial: boolean; + data: ResponseData; + errors: SearchStrategyError[]; +} + +export interface ParsedDataSearchResponseDescriptor< + Request extends IKibanaSearchRequest, + Response +> { + request: Request; + options: ISearchOptions; + response: ParsedKibanaSearchResponse; + abortController: AbortController; +} diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx new file mode 100644 index 00000000000000..06f8ca1b82eb7d --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx @@ -0,0 +1,198 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, renderHook } from '@testing-library/react-hooks'; +import React from 'react'; +import { firstValueFrom, Observable, of, Subject } from 'rxjs'; +import { + DataPublicPluginStart, + IKibanaSearchResponse, + ISearchGeneric, + ISearchStart, +} from '@kbn/data-plugin/public'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; +import { PluginKibanaContextValue } from '../../hooks/use_kibana'; +import { normalizeDataSearchResponses } from './normalize_data_search_responses'; +import { useDataSearch } from './use_data_search_request'; + +describe('useDataSearch hook', () => { + it('forwards the search function arguments to the getRequest function', async () => { + const dataMock = createDataPluginMock(); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((_firstArgument: string, _secondArgument: string) => null); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + act(() => { + result.current.search('first', 'second'); + }); + + expect(getRequest).toHaveBeenLastCalledWith('first', 'second'); + expect(dataMock.search.search).not.toHaveBeenCalled(); + }); + + it('creates search requests with the given params and options and parses the responses', async () => { + const dataMock = createDataPluginMock(); + const searchResponseMock$ = of({ + rawResponse: { + firstKey: 'firstValue', + }, + }); + dataMock.search.search.mockReturnValue(searchResponseMock$); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((firstArgument: string, secondArgument: string) => ({ + request: { + params: { + firstArgument, + secondArgument, + }, + }, + options: { + strategy: 'test-search-strategy', + }, + })); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + // the request execution is lazy + expect(dataMock.search.search).not.toHaveBeenCalled(); + + // execute requests$ observable + const firstRequestPromise = firstValueFrom(result.current.requests$); + + act(() => { + result.current.search('first', 'second'); + }); + + const firstRequest = await firstRequestPromise; + + expect(dataMock.search.search).toHaveBeenLastCalledWith( + { + params: { firstArgument: 'first', secondArgument: 'second' }, + }, + { + abortSignal: expect.any(Object), + strategy: 'test-search-strategy', + } + ); + expect(firstRequest).toHaveProperty('abortController', expect.any(Object)); + expect(firstRequest).toHaveProperty('request.params', { + firstArgument: 'first', + secondArgument: 'second', + }); + expect(firstRequest).toHaveProperty('options.strategy', 'test-search-strategy'); + expect(firstRequest).toHaveProperty('response$', expect.any(Observable)); + await expect(firstRequest.response$.toPromise()).resolves.toMatchObject({ + data: { + firstKey: 'firstValue', // because this specific response parser just copies the raw response + }, + errors: [], + }); + }); + + it('aborts the request when the response observable looses the last subscriber', async () => { + const dataMock = createDataPluginMock(); + const searchResponseMock$ = new Subject(); + dataMock.search.search.mockReturnValue(searchResponseMock$); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((firstArgument: string, secondArgument: string) => ({ + request: { + params: { + firstArgument, + secondArgument, + }, + }, + options: { + strategy: 'test-search-strategy', + }, + })); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + // the request execution is lazy + expect(dataMock.search.search).not.toHaveBeenCalled(); + + // execute requests$ observable + const firstRequestPromise = firstValueFrom(result.current.requests$); + + act(() => { + result.current.search('first', 'second'); + }); + + const firstRequest = await firstRequestPromise; + + // execute requests$ observable + const firstResponseSubscription = firstRequest.response$.subscribe({ + next: jest.fn(), + }); + + // get the abort signal + const [, firstRequestOptions] = dataMock.search.search.mock.calls[0]; + + expect(firstRequestOptions?.abortSignal?.aborted).toBe(false); + + // unsubscribe + firstResponseSubscription.unsubscribe(); + + expect(firstRequestOptions?.abortSignal?.aborted).toBe(true); + }); +}); + +const createDataPluginMock = () => { + const dataMock = dataPluginMock.createStartContract() as DataPublicPluginStart & { + search: ISearchStart & { search: jest.MockedFunction }; + }; + return dataMock; +}; + +const noopParseResponse = normalizeDataSearchResponses( + null, + (response: Response) => ({ data: response }) +); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts new file mode 100644 index 00000000000000..230c2d87e06541 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { OperatorFunction, ReplaySubject } from 'rxjs'; +import { share, tap } from 'rxjs/operators'; +import { + IKibanaSearchRequest, + IKibanaSearchResponse, + ISearchOptions, +} from '@kbn/data-plugin/public'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; +import { tapUnsubscribe, useObservable } from '../use_observable'; +import { ParsedDataSearchRequestDescriptor, ParsedKibanaSearchResponse } from './types'; + +export type DataSearchRequestFactory = ( + ...args: Args +) => + | { + request: Request; + options: ISearchOptions; + } + | null + | undefined; + +type ParseResponsesOperator = OperatorFunction< + IKibanaSearchResponse, + ParsedKibanaSearchResponse +>; + +export const useDataSearch = < + RequestFactoryArgs extends any[], + RequestParams, + Request extends IKibanaSearchRequest, + RawResponse, + Response +>({ + getRequest, + parseResponses, +}: { + getRequest: DataSearchRequestFactory; + parseResponses: ParseResponsesOperator; +}) => { + const { services } = useKibanaContextForPlugin(); + const requests$ = useObservable( + () => new ReplaySubject>(1), + [] + ); + + const search = useCallback( + (...args: RequestFactoryArgs) => { + const requestArgs = getRequest(...args); + + if (requestArgs == null) { + return; + } + + const abortController = new AbortController(); + let isAbortable = true; + + const newRequestDescriptor = { + ...requestArgs, + abortController, + response$: services.data.search + .search>(requestArgs.request, { + abortSignal: abortController.signal, + ...requestArgs.options, + }) + .pipe( + // avoid aborting failed or completed requests + tap({ + error: () => { + isAbortable = false; + }, + complete: () => { + isAbortable = false; + }, + }), + tapUnsubscribe(() => { + if (isAbortable) { + abortController.abort(); + } + }), + parseResponses, + share() + ), + }; + + requests$.next(newRequestDescriptor); + + return newRequestDescriptor; + }, + [getRequest, services.data.search, parseResponses, requests$] + ); + + return { + requests$, + search, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts new file mode 100644 index 00000000000000..c8ec672beb8429 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { Observable } from 'rxjs'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { useObservableState } from '../use_observable'; +import { ParsedDataSearchResponseDescriptor } from './types'; + +export const useDataSearchResponseState = < + Request extends IKibanaSearchRequest, + Response, + InitialResponse +>( + response$: Observable> +) => { + const { latestValue } = useObservableState(response$, undefined); + + const cancelRequest = useCallback(() => { + latestValue?.abortController.abort(); + }, [latestValue]); + + return { + cancelRequest, + isRequestRunning: latestValue?.response.isRunning ?? false, + isResponsePartial: latestValue?.response.isPartial ?? false, + latestResponseData: latestValue?.response.data, + latestResponseErrors: latestValue?.response.errors, + loaded: latestValue?.response.loaded, + total: latestValue?.response.total, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx new file mode 100644 index 00000000000000..a48cf2c7ccdc46 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, renderHook } from '@testing-library/react-hooks'; +import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { ParsedDataSearchRequestDescriptor, ParsedKibanaSearchResponse } from './types'; +import { useLatestPartialDataSearchResponse } from './use_latest_partial_data_search_response'; + +describe('useLatestPartialDataSearchResponse hook', () => { + it("subscribes to the latest request's response observable", () => { + const firstRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'firstRequestParam' }, + response$: new BehaviorSubject>({ + data: 'initial', + isRunning: true, + isPartial: true, + errors: [], + }), + }; + + const secondRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'secondRequestParam' }, + response$: new BehaviorSubject>({ + data: 'initial', + isRunning: true, + isPartial: true, + errors: [], + }), + }; + + const requests$ = new Subject< + ParsedDataSearchRequestDescriptor, string> + >(); + + const { result } = renderHook(() => useLatestPartialDataSearchResponse(requests$)); + + expect(result).toHaveProperty('current.isRequestRunning', false); + expect(result).toHaveProperty('current.latestResponseData', undefined); + + // first request is started + act(() => { + requests$.next(firstRequest); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'initial'); + + // first response of the first request arrives + act(() => { + firstRequest.response$.next({ + data: 'request-1-response-1', + isRunning: true, + isPartial: true, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'request-1-response-1'); + + // second request is started before the second response of the first request arrives + act(() => { + requests$.next(secondRequest); + secondRequest.response$.next({ + data: 'request-2-response-1', + isRunning: true, + isPartial: true, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'request-2-response-1'); + + // second response of the second request arrives + act(() => { + secondRequest.response$.next({ + data: 'request-2-response-2', + isRunning: false, + isPartial: false, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', false); + expect(result).toHaveProperty('current.latestResponseData', 'request-2-response-2'); + }); + + it("unsubscribes from the latest request's response observable on unmount", () => { + const onUnsubscribe = jest.fn(); + + const firstRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'firstRequestParam' }, + response$: new Observable>(() => { + return onUnsubscribe; + }), + }; + + const requests$ = + of, string>>(firstRequest); + + const { unmount } = renderHook(() => useLatestPartialDataSearchResponse(requests$)); + + expect(onUnsubscribe).not.toHaveBeenCalled(); + + unmount(); + + expect(onUnsubscribe).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts new file mode 100644 index 00000000000000..48ff61eb676b93 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Observable } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { useOperator } from '../use_observable'; +import { flattenDataSearchResponseDescriptor } from './flatten_data_search_response'; +import { ParsedDataSearchRequestDescriptor, ParsedDataSearchResponseDescriptor } from './types'; +import { useDataSearchResponseState } from './use_data_search_response_state'; + +export const useLatestPartialDataSearchResponse = ( + requests$: Observable> +) => { + const latestResponse$: Observable> = + useOperator(requests$, flattenLatestDataSearchResponse); + + const { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, + } = useDataSearchResponseState(latestResponse$); + + return { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, + }; +}; + +const flattenLatestDataSearchResponse = switchMap(flattenDataSearchResponseDescriptor); diff --git a/x-pack/plugins/logs_shared/public/utils/datemath.ts b/x-pack/plugins/logs_shared/public/utils/datemath.ts new file mode 100644 index 00000000000000..ab07ace52d05da --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/datemath.ts @@ -0,0 +1,293 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 dateMath, { Unit } from '@kbn/datemath'; + +const JS_MAX_DATE = 8640000000000000; + +export function isValidDatemath(value: string): boolean { + const parsedValue = dateMath.parse(value); + return !!(parsedValue && parsedValue.isValid()); +} + +export function datemathToEpochMillis( + value: string, + round: 'down' | 'up' = 'down', + forceNow?: Date +): number | null { + const parsedValue = dateMath.parse(value, { roundUp: round === 'up', forceNow }); + if (!parsedValue || !parsedValue.isValid()) { + return null; + } + return parsedValue.valueOf(); +} + +type DatemathExtension = + | { + value: string; + diffUnit: Unit; + diffAmount: number; + } + | { value: 'now' }; + +const datemathNowExpression = /(\+|\-)(\d+)(ms|s|m|h|d|w|M|y)$/; + +/** + * Extend a datemath value + * @param value The value to extend + * @param {'before' | 'after'} direction Should the value move before or after in time + * @param oppositeEdge For absolute values, the value of the other edge of the range + */ +export function extendDatemath( + value: string, + direction: 'before' | 'after' = 'before', + oppositeEdge?: string +): DatemathExtension | undefined { + if (!isValidDatemath(value)) { + return undefined; + } + + // `now` cannot be extended + if (value === 'now') { + return { value: 'now' }; + } + + // The unit is relative + if (value.startsWith('now')) { + return extendRelativeDatemath(value, direction); + } else if (oppositeEdge && isValidDatemath(oppositeEdge)) { + return extendAbsoluteDatemath(value, direction, oppositeEdge); + } + + return undefined; +} + +function extendRelativeDatemath( + value: string, + direction: 'before' | 'after' +): DatemathExtension | undefined { + const [, operator, amount, unit] = datemathNowExpression.exec(value) || []; + if (!operator || !amount || !unit) { + return undefined; + } + + const mustIncreaseAmount = + (operator === '-' && direction === 'before') || (operator === '+' && direction === 'after'); + const parsedAmount = parseInt(amount, 10); + let newUnit: Unit = unit as Unit; + let newAmount: number; + + // Extend the amount + switch (unit) { + // For small units, always double or halve the amount + case 'ms': + case 's': + newAmount = mustIncreaseAmount ? parsedAmount * 2 : Math.floor(parsedAmount / 2); + break; + // For minutes, increase or decrease in doubles or halves, depending on + // the amount of minutes + case 'm': + let ratio; + const MINUTES_LARGE = 10; + if (mustIncreaseAmount) { + ratio = parsedAmount >= MINUTES_LARGE ? 0.5 : 1; + newAmount = parsedAmount + Math.floor(parsedAmount * ratio); + } else { + newAmount = + parsedAmount >= MINUTES_LARGE + ? Math.floor(parsedAmount / 1.5) + : parsedAmount - Math.floor(parsedAmount * 0.5); + } + break; + + // For hours, increase or decrease half an hour for 1 hour. Otherwise + // increase full hours + case 'h': + if (parsedAmount === 1) { + newAmount = mustIncreaseAmount ? 90 : 30; + newUnit = 'm'; + } else { + newAmount = mustIncreaseAmount ? parsedAmount + 1 : parsedAmount - 1; + } + break; + + // For the rest of units, increase or decrease one smaller unit for + // amounts of 1. Otherwise increase or decrease the unit + case 'd': + case 'w': + case 'M': + case 'y': + if (parsedAmount === 1) { + newUnit = dateMath.unitsDesc[dateMath.unitsDesc.indexOf(unit) + 1]; + newAmount = mustIncreaseAmount + ? convertDate(1, unit, newUnit) + 1 + : convertDate(1, unit, newUnit) - 1; + } else { + newAmount = mustIncreaseAmount ? parsedAmount + 1 : parsedAmount - 1; + } + break; + + default: + throw new TypeError('Unhandled datemath unit'); + } + + // normalize amount and unit (i.e. 120s -> 2m) + const { unit: normalizedUnit, amount: normalizedAmount } = normalizeDate(newAmount, newUnit); + + // How much have we changed the time? + const diffAmount = Math.abs(normalizedAmount - convertDate(parsedAmount, unit, normalizedUnit)); + // if `diffAmount` is not an integer after normalization, express the difference in the original unit + const shouldKeepDiffUnit = diffAmount % 1 !== 0; + + const nextValue = `now${operator}${normalizedAmount}${normalizedUnit}`; + + if (isDateInRange(nextValue)) { + return { + value: nextValue, + diffUnit: shouldKeepDiffUnit ? unit : newUnit, + diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount, + }; + } else { + return undefined; + } +} + +function extendAbsoluteDatemath( + value: string, + direction: 'before' | 'after', + oppositeEdge: string +): DatemathExtension | undefined { + const valueTimestamp = datemathToEpochMillis(value)!; + const oppositeEdgeTimestamp = datemathToEpochMillis(oppositeEdge)!; + const actualTimestampDiff = Math.abs(valueTimestamp - oppositeEdgeTimestamp); + const normalizedDiff = normalizeDate(actualTimestampDiff, 'ms'); + const normalizedTimestampDiff = convertDate(normalizedDiff.amount, normalizedDiff.unit, 'ms'); + + const newValue = + direction === 'before' + ? valueTimestamp - normalizedTimestampDiff + : valueTimestamp + normalizedTimestampDiff; + + if (isDateInRange(newValue)) { + return { + value: new Date(newValue).toISOString(), + diffUnit: normalizedDiff.unit, + diffAmount: normalizedDiff.amount, + }; + } else { + return undefined; + } +} + +const CONVERSION_RATIOS: Record> = { + wy: [ + ['w', 52], // 1 year = 52 weeks + ['y', 1], + ], + w: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 7], // 1 week = 7 days + ['w', 4], // 1 month = 4 weeks = 28 days + ['M', 12], // 1 year = 12 months = 52 weeks = 364 days + ['y', 1], + ], + M: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 30], // 1 month = 30 days + ['M', 12], // 1 year = 12 months = 360 days + ['y', 1], + ], + default: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 365], // 1 year = 365 days + ['y', 1], + ], +}; + +function getRatioScale(from: Unit, to?: Unit) { + if ((from === 'y' && to === 'w') || (from === 'w' && to === 'y')) { + return CONVERSION_RATIOS.wy; + } else if (from === 'w' || to === 'w') { + return CONVERSION_RATIOS.w; + } else if (from === 'M' || to === 'M') { + return CONVERSION_RATIOS.M; + } else { + return CONVERSION_RATIOS.default; + } +} + +export function convertDate(value: number, from: Unit, to: Unit): number { + if (from === to) { + return value; + } + + const ratioScale = getRatioScale(from, to); + const fromIdx = ratioScale.findIndex((ratio) => ratio[0] === from); + const toIdx = ratioScale.findIndex((ratio) => ratio[0] === to); + + let convertedValue = value; + + if (fromIdx > toIdx) { + // `from` is the bigger unit. Multiply the value + for (let i = toIdx; i < fromIdx; i++) { + convertedValue *= ratioScale[i][1]; + } + } else { + // `from` is the smaller unit. Divide the value + for (let i = fromIdx; i < toIdx; i++) { + convertedValue /= ratioScale[i][1]; + } + } + + return convertedValue; +} + +export function normalizeDate(amount: number, unit: Unit): { amount: number; unit: Unit } { + // There is nothing after years + if (unit === 'y') { + return { amount, unit }; + } + + const nextUnit = dateMath.unitsAsc[dateMath.unitsAsc.indexOf(unit) + 1]; + const ratioScale = getRatioScale(unit, nextUnit); + const ratio = ratioScale.find((r) => r[0] === unit)![1]; + + const newAmount = amount / ratio; + + // Exact conversion + if (newAmount === 1) { + return { amount: newAmount, unit: nextUnit }; + } + + // Might be able to go one unit more, so try again, rounding the value + // 7200s => 120m => 2h + // 7249s ~> 120m ~> 2h + if (newAmount >= 2) { + return normalizeDate(Math.round(newAmount), nextUnit); + } + + // Cannot go one one unit above. Return as it is + return { amount, unit }; +} + +function isDateInRange(date: string | number): boolean { + try { + const epoch = typeof date === 'string' ? datemathToEpochMillis(date) ?? -1 : date; + return epoch >= 0 && epoch <= JS_MAX_DATE; + } catch { + return false; + } +} diff --git a/x-pack/plugins/logs_shared/public/utils/dev_mode.ts b/x-pack/plugins/logs_shared/public/utils/dev_mode.ts new file mode 100644 index 00000000000000..60571501b41934 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/dev_mode.ts @@ -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. + */ + +export const getReduxDevtools = () => (window as any).__REDUX_DEVTOOLS_EXTENSION__; + +export const hasReduxDevtools = () => getReduxDevtools() != null; + +export const isDevMode = () => process.env.NODE_ENV !== 'production'; diff --git a/x-pack/plugins/logs_shared/public/utils/handlers.ts b/x-pack/plugins/logs_shared/public/utils/handlers.ts new file mode 100644 index 00000000000000..f79e2fa4766a2e --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/handlers.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 { isEqual } from 'lodash'; + +export function callWithoutRepeats( + func: (...args: any[]) => T, + isArgsEqual: (firstArgs: any, secondArgs: any) => boolean = isEqual +) { + let previousArgs: any[]; + let previousResult: T; + + return (...args: any[]) => { + if (!isArgsEqual(args, previousArgs)) { + previousArgs = args; + previousResult = func(...args); + } + + return previousResult; + }; +} diff --git a/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx b/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx new file mode 100644 index 00000000000000..ff4a24f1498a6a --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ReactNode } from 'react'; +import { JsonValue } from '@kbn/utility-types'; + +/** + * Interface for common configuration properties, regardless of the column type. + */ +interface CommonRenderConfiguration { + id: string; + width?: number | string; + header?: boolean | string; +} + +interface TimestampColumnRenderConfiguration { + timestampColumn: CommonRenderConfiguration & { + render?: (timestamp: number) => ReactNode; + }; +} + +interface MessageColumnRenderConfiguration { + messageColumn: CommonRenderConfiguration & { + render?: (message: string) => ReactNode; + }; +} + +interface FieldColumnRenderConfiguration { + fieldColumn: CommonRenderConfiguration & { + field: string; + render?: (value: JsonValue) => ReactNode; + }; +} + +export type LogColumnRenderConfiguration = + | TimestampColumnRenderConfiguration + | MessageColumnRenderConfiguration + | FieldColumnRenderConfiguration; + +export function isTimestampColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is TimestampColumnRenderConfiguration { + return 'timestampColumn' in column; +} + +export function isMessageColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is MessageColumnRenderConfiguration { + return 'messageColumn' in column; +} + +export function isFieldColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is FieldColumnRenderConfiguration { + return 'fieldColumn' in column; +} + +export function columnWidthToCSS(width: number | string) { + return typeof width === 'number' ? `${width}px` : width; +} diff --git a/x-pack/plugins/infra/public/utils/log_entry/index.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/index.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/index.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/index.ts diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/log_entry.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/log_entry.ts diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry_highlight.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/log_entry_highlight.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/log_entry_highlight.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/log_entry_highlight.ts diff --git a/x-pack/plugins/infra/public/utils/styles.ts b/x-pack/plugins/logs_shared/public/utils/styles.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/styles.ts rename to x-pack/plugins/logs_shared/public/utils/styles.ts diff --git a/x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx b/x-pack/plugins/logs_shared/public/utils/typed_react.tsx similarity index 50% rename from x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx rename to x-pack/plugins/logs_shared/public/utils/typed_react.tsx index 064e944378cab9..664894e1bf05ca 100644 --- a/x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx +++ b/x-pack/plugins/logs_shared/public/utils/typed_react.tsx @@ -6,12 +6,6 @@ */ import React from 'react'; -import type { LogStreamProps } from './log_stream'; -const LazyLogStream = React.lazy(() => import('./log_stream')); - -export const LazyLogStreamWrapper = (props: LogStreamProps) => ( - }> - - -); +export type RendererResult = React.ReactElement | null; +export type RendererFunction = (args: RenderArgs) => Result; diff --git a/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts b/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts new file mode 100644 index 00000000000000..521cd0142303be --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EsQueryConfig } from '@kbn/es-query'; +import { SerializableRecord } from '@kbn/utility-types'; +import { useMemo } from 'react'; +import { UI_SETTINGS } from '@kbn/data-plugin/public'; +import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; + +export const useKibanaQuerySettings = (): EsQueryConfig => { + const [allowLeadingWildcards] = useUiSetting$(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS); + const [queryStringOptions] = useUiSetting$(UI_SETTINGS.QUERY_STRING_OPTIONS); + const [dateFormatTZ] = useUiSetting$(UI_SETTINGS.DATEFORMAT_TZ); + const [ignoreFilterIfFieldNotInIndex] = useUiSetting$( + UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX + ); + + return useMemo( + () => ({ + allowLeadingWildcards, + queryStringOptions, + dateFormatTZ, + ignoreFilterIfFieldNotInIndex, + }), + [allowLeadingWildcards, dateFormatTZ, ignoreFilterIfFieldNotInIndex, queryStringOptions] + ); +}; diff --git a/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts b/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts new file mode 100644 index 00000000000000..e53e2b28cbdd40 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.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 { useMemo } from 'react'; +import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; + +/** + * This hook behaves like a `useState` hook in that it provides a requested + * setting value (with an optional default) from the Kibana UI settings (also + * known as "advanced settings") and a setter to change that setting: + * + * ``` + * const [quickRanges, setQuickRanges] = useKibanaUiSetting('timepicker:quickRanges'); + * ``` + * + * This is not just a static consumption of the value, but will reactively + * update when the underlying setting subscription of the `UiSettingsClient` + * notifies of a change. + * + * Unlike the `useState`, it doesn't give type guarantees for the value, + * because the underlying `UiSettingsClient` doesn't support that. + */ + +export interface TimePickerQuickRange { + from: string; + to: string; + display: string; +} + +export function useKibanaUiSetting( + key: 'timepicker:quickRanges', + defaultValue?: TimePickerQuickRange[] +): [ + TimePickerQuickRange[], + (key: 'timepicker:quickRanges', value: TimePickerQuickRange[]) => Promise +]; + +export function useKibanaUiSetting( + key: string, + defaultValue?: any +): [any, (key: string, value: any) => Promise]; + +export function useKibanaUiSetting(key: string, defaultValue?: any) { + const [uiSetting, setUiSetting] = useUiSetting$(key); + const uiSettingValue = useMemo(() => { + return uiSetting ? uiSetting : defaultValue; + }, [uiSetting, defaultValue]); + return [uiSettingValue, setUiSetting]; +} diff --git a/x-pack/plugins/logs_shared/public/utils/use_observable.ts b/x-pack/plugins/logs_shared/public/utils/use_observable.ts new file mode 100644 index 00000000000000..00efc4900b82f0 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_observable.ts @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useRef, useState } from 'react'; +import { + BehaviorSubject, + Observable, + OperatorFunction, + PartialObserver, + ReplaySubject, + Subscription, +} from 'rxjs'; +import { switchMap } from 'rxjs/operators'; + +export const useLatest = (value: Value) => { + const valueRef = useRef(value); + valueRef.current = value; + return valueRef; +}; + +export const useObservable = < + OutputValue, + OutputObservable extends Observable, + InputValues extends Readonly +>( + createObservableOnce: (inputValues: Observable) => OutputObservable, + inputValues: InputValues +) => { + const [output$, next] = useBehaviorSubject(createObservableOnce, () => inputValues); + + useEffect(() => { + next(inputValues); + // `inputValues` can't be statically analyzed + // eslint-disable-next-line react-hooks/exhaustive-deps + }, inputValues); + + return output$; +}; + +export const useBehaviorSubject = < + InputValue, + OutputValue, + OutputObservable extends Observable +>( + deriveObservableOnce: (input$: Observable) => OutputObservable, + createInitialValue: () => InputValue +) => { + const [[subject$, next], _] = useState(() => { + const newSubject$ = new BehaviorSubject(createInitialValue()); + const newNext = newSubject$.next.bind(newSubject$); + return [newSubject$, newNext] as const; + }); + const [output$] = useState(() => deriveObservableOnce(subject$)); + return [output$, next] as const; +}; + +export const useReplaySubject = < + InputValue, + OutputValue, + OutputObservable extends Observable +>( + deriveObservableOnce: (input$: Observable) => OutputObservable +) => { + const [[subject$, next], _] = useState(() => { + const newSubject$ = new ReplaySubject(); + const newNext = newSubject$.next.bind(newSubject$); + return [newSubject$, newNext] as const; + }); + const [output$] = useState(() => deriveObservableOnce(subject$)); + return [output$, next] as const; +}; + +export const useObservableState = ( + state$: Observable, + initialState: InitialState | (() => InitialState) +) => { + const [latestValue, setLatestValue] = useState(initialState); + const [latestError, setLatestError] = useState(); + + useSubscription(state$, { + next: setLatestValue, + error: setLatestError, + }); + + return { latestValue, latestError }; +}; + +export const useSubscription = ( + input$: Observable, + { next, error, complete, unsubscribe }: PartialObserver & { unsubscribe?: () => void } +) => { + const latestSubscription = useRef(); + const latestNext = useLatest(next); + const latestError = useLatest(error); + const latestComplete = useLatest(complete); + const latestUnsubscribe = useLatest(unsubscribe); + + useEffect(() => { + const fixedUnsubscribe = latestUnsubscribe.current; + + const subscription = input$.subscribe({ + next: (value) => { + return latestNext.current?.(value); + }, + error: (value) => latestError.current?.(value), + complete: () => latestComplete.current?.(), + }); + + latestSubscription.current = subscription; + + return () => { + subscription.unsubscribe(); + fixedUnsubscribe?.(); + }; + }, [input$, latestNext, latestError, latestComplete, latestUnsubscribe]); + + return latestSubscription.current; +}; + +export const useOperator = ( + input$: Observable, + operator: OperatorFunction +) => { + const latestOperator = useLatest(operator); + + return useObservable( + (inputs$) => + inputs$.pipe(switchMap(([currentInput$]) => latestOperator.current(currentInput$))), + [input$] as const + ); +}; + +export const tapUnsubscribe = + (onUnsubscribe: () => void) => + (source$: Observable) => { + return new Observable((subscriber) => { + const subscription = source$.subscribe({ + next: (value) => subscriber.next(value), + error: (error) => subscriber.error(error), + complete: () => subscriber.complete(), + }); + + return () => { + onUnsubscribe(); + subscription.unsubscribe(); + }; + }); + }; diff --git a/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts b/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts new file mode 100644 index 00000000000000..d12749ea69fdc9 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts @@ -0,0 +1,299 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { DependencyList, useEffect, useMemo, useRef, useState, useCallback } from 'react'; +import useMountedState from 'react-use/lib/useMountedState'; + +interface UseTrackedPromiseArgs { + createPromise: (...args: Arguments) => Promise; + onResolve?: (result: Result) => void; + onReject?: (value: unknown) => void; + cancelPreviousOn?: 'creation' | 'settlement' | 'resolution' | 'rejection' | 'never'; + triggerOrThrow?: 'always' | 'whenMounted'; +} + +/** + * This hook manages a Promise factory and can create new Promises from it. The + * state of these Promises is tracked and they can be canceled when superseded + * to avoid race conditions. + * + * ``` + * const [requestState, performRequest] = useTrackedPromise( + * { + * cancelPreviousOn: 'resolution', + * createPromise: async (url: string) => { + * return await fetchSomething(url) + * }, + * onResolve: response => { + * setSomeState(response.data); + * }, + * onReject: response => { + * setSomeError(response); + * }, + * }, + * [fetchSomething] + * ); + * ``` + * + * The `onResolve` and `onReject` handlers are registered separately, because + * the hook will inject a rejection when in case of a canellation. The + * `cancelPreviousOn` attribute can be used to indicate when the preceding + * pending promises should be canceled: + * + * 'never': No preceding promises will be canceled. + * + * 'creation': Any preceding promises will be canceled as soon as a new one is + * created. + * + * 'settlement': Any preceding promise will be canceled when a newer promise is + * resolved or rejected. + * + * 'resolution': Any preceding promise will be canceled when a newer promise is + * resolved. + * + * 'rejection': Any preceding promise will be canceled when a newer promise is + * rejected. + * + * Any pending promises will be canceled when the component using the hook is + * unmounted, but their status will not be tracked to avoid React warnings + * about memory leaks. + * + * The last argument is a normal React hook dependency list that indicates + * under which conditions a new reference to the configuration object should be + * used. + * + * The `onResolve`, `onReject` and possible uncatched errors are only triggered + * if the underlying component is mounted. To ensure they always trigger (i.e. + * if the promise is called in a `useLayoutEffect`) use the `triggerOrThrow` + * attribute: + * + * 'whenMounted': (default) they are called only if the component is mounted. + * + * 'always': they always call. The consumer is then responsible of ensuring no + * side effects happen if the underlying component is not mounted. + */ +export const useTrackedPromise = ( + { + createPromise, + onResolve = noOp, + onReject = noOp, + cancelPreviousOn = 'never', + triggerOrThrow = 'whenMounted', + }: UseTrackedPromiseArgs, + dependencies: DependencyList +) => { + const isComponentMounted = useMountedState(); + const shouldTriggerOrThrow = useCallback(() => { + switch (triggerOrThrow) { + case 'always': + return true; + case 'whenMounted': + return isComponentMounted(); + } + }, [isComponentMounted, triggerOrThrow]); + + /** + * If a promise is currently pending, this holds a reference to it and its + * cancellation function. + */ + const pendingPromises = useRef>>([]); + + /** + * The state of the promise most recently created by the `createPromise` + * factory. It could be uninitialized, pending, resolved or rejected. + */ + const [promiseState, setPromiseState] = useState>({ + state: 'uninitialized', + }); + + const reset = useCallback(() => { + setPromiseState({ + state: 'uninitialized', + }); + }, []); + + const execute = useMemo( + () => + (...args: Arguments) => { + let rejectCancellationPromise!: (value: any) => void; + const cancellationPromise = new Promise((_, reject) => { + rejectCancellationPromise = reject; + }); + + // remember the list of prior pending promises for cancellation + const previousPendingPromises = pendingPromises.current; + + const cancelPreviousPendingPromises = () => { + previousPendingPromises.forEach((promise) => promise.cancel()); + }; + + const newPromise = createPromise(...args); + const newCancelablePromise = Promise.race([newPromise, cancellationPromise]); + + // track this new state + setPromiseState({ + state: 'pending', + promise: newCancelablePromise, + }); + + if (cancelPreviousOn === 'creation') { + cancelPreviousPendingPromises(); + } + + const newPendingPromise: CancelablePromise = { + cancel: () => { + rejectCancellationPromise(new CanceledPromiseError()); + }, + cancelSilently: () => { + rejectCancellationPromise(new SilentCanceledPromiseError()); + }, + promise: newCancelablePromise.then( + (value) => { + if (['settlement', 'resolution'].includes(cancelPreviousOn)) { + cancelPreviousPendingPromises(); + } + + // remove itself from the list of pending promises + pendingPromises.current = pendingPromises.current.filter( + (pendingPromise) => pendingPromise.promise !== newPendingPromise.promise + ); + + if (onResolve && shouldTriggerOrThrow()) { + onResolve(value); + } + + setPromiseState((previousPromiseState) => + previousPromiseState.state === 'pending' && + previousPromiseState.promise === newCancelablePromise + ? { + state: 'resolved', + promise: newPendingPromise.promise, + value, + } + : previousPromiseState + ); + + return value; + }, + (value) => { + if (!(value instanceof SilentCanceledPromiseError)) { + if (['settlement', 'rejection'].includes(cancelPreviousOn)) { + cancelPreviousPendingPromises(); + } + + // remove itself from the list of pending promises + pendingPromises.current = pendingPromises.current.filter( + (pendingPromise) => pendingPromise.promise !== newPendingPromise.promise + ); + + if (shouldTriggerOrThrow()) { + if (onReject) { + onReject(value); + } else { + throw value; + } + } + + setPromiseState((previousPromiseState) => + previousPromiseState.state === 'pending' && + previousPromiseState.promise === newCancelablePromise + ? { + state: 'rejected', + promise: newCancelablePromise, + value, + } + : previousPromiseState + ); + } + } + ), + }; + + // add the new promise to the list of pending promises + pendingPromises.current = [...pendingPromises.current, newPendingPromise]; + + // silence "unhandled rejection" warnings + newPendingPromise.promise.catch(noOp); + + return newPendingPromise.promise; + }, + // the dependencies are managed by the caller + // eslint-disable-next-line react-hooks/exhaustive-deps + dependencies + ); + + /** + * Cancel any pending promises silently to avoid memory leaks and race + * conditions. + */ + useEffect( + () => () => { + pendingPromises.current.forEach((promise) => promise.cancelSilently()); + }, + [] + ); + + return [promiseState, execute, reset] as [typeof promiseState, typeof execute, typeof reset]; +}; + +export interface UninitializedPromiseState { + state: 'uninitialized'; +} + +export interface PendingPromiseState { + state: 'pending'; + promise: Promise; +} + +export interface ResolvedPromiseState { + state: 'resolved'; + promise: Promise; + value: ResolvedValue; +} + +export interface RejectedPromiseState { + state: 'rejected'; + promise: Promise; + value: RejectedValue; +} + +export type SettledPromiseState = + | ResolvedPromiseState + | RejectedPromiseState; + +export type PromiseState = + | UninitializedPromiseState + | PendingPromiseState + | SettledPromiseState; + +export const isRejectedPromiseState = ( + promiseState: PromiseState +): promiseState is RejectedPromiseState => promiseState.state === 'rejected'; + +interface CancelablePromise { + // reject the promise prematurely with a CanceledPromiseError + cancel: () => void; + // reject the promise prematurely with a SilentCanceledPromiseError + cancelSilently: () => void; + // the tracked promise + promise: Promise; +} + +export class CanceledPromiseError extends Error { + public isCanceled = true; + + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} + +export class SilentCanceledPromiseError extends CanceledPromiseError {} + +const noOp = () => undefined; diff --git a/x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts b/x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts new file mode 100644 index 00000000000000..cff9a7190d2bb3 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_visibility_state.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 { useCallback, useMemo, useState } from 'react'; + +export const useVisibilityState = (initialState: boolean) => { + const [isVisible, setIsVisible] = useState(initialState); + + const hide = useCallback(() => setIsVisible(false), []); + const show = useCallback(() => setIsVisible(true), []); + const toggle = useCallback(() => setIsVisible((state) => !state), []); + + return useMemo( + () => ({ + hide, + isVisible, + show, + toggle, + }), + [hide, isVisible, show, toggle] + ); +}; diff --git a/x-pack/plugins/logs_shared/server/index.ts b/x-pack/plugins/logs_shared/server/index.ts new file mode 100644 index 00000000000000..95f6741bb54b88 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PluginInitializerContext } from '@kbn/core/server'; +import { LogsSharedPlugin } from './plugin'; + +export type { LogsSharedPluginSetup, LogsSharedPluginStart } from './types'; +export type { + LogsSharedLogEntriesDomain, + ILogsSharedLogEntriesDomain, +} from './lib/domains/log_entries_domain'; + +export { logViewSavedObjectName } from './saved_objects'; + +export function plugin(context: PluginInitializerContext) { + return new LogsSharedPlugin(context); +} diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts new file mode 100644 index 00000000000000..46e77f48d3f4bc --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.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 type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { JsonArray, JsonValue } from '@kbn/utility-types'; +import { RouteMethod } from '@kbn/core/server'; +import { VersionedRouteConfig } from '@kbn/core-http-server'; + +export interface CallWithRequestParams extends estypes.RequestBase { + max_concurrent_shard_requests?: number; + name?: string; + index?: string | string[]; + ignore_unavailable?: boolean; + allow_no_indices?: boolean; + size?: number; + terminate_after?: number; + fields?: estypes.Fields; + path?: string; + query?: string | object; + track_total_hits?: boolean | number; + body?: any; +} + +export interface LogsSharedDatabaseResponse { + took: number; + timeout: boolean; +} + +export interface LogsSharedDatabaseSearchResponse + extends LogsSharedDatabaseResponse { + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + timed_out: boolean; + aggregations?: Aggregations; + hits: { + total: { + value: number; + relation: string; + }; + hits: Hit[]; + }; +} + +export interface LogsSharedDatabaseMultiResponse + extends LogsSharedDatabaseResponse { + responses: Array>; +} + +export interface LogsSharedDatabaseGetIndicesAliasResponse { + [indexName: string]: { + aliases: { + [aliasName: string]: any; + }; + }; +} + +export interface LogsSharedDatabaseGetIndicesResponse { + [indexName: string]: { + aliases: { + [aliasName: string]: any; + }; + mappings: { + _meta: object; + dynamic_templates: any[]; + date_detection: boolean; + properties: { + [fieldName: string]: any; + }; + }; + settings: { index: object }; + }; +} + +export type SearchHit = estypes.SearchHit; + +export interface SortedSearchHit extends SearchHit { + sort: any[]; + _source: { + [field: string]: JsonValue; + }; + fields: { + [field: string]: JsonArray; + }; +} + +export type LogsSharedVersionedRouteConfig = { + method: RouteMethod; +} & VersionedRouteConfig; diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts new file mode 100644 index 00000000000000..5d7c09c54b8c14 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/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 * from './adapter_types'; diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts new file mode 100644 index 00000000000000..413ab3b333e826 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -0,0 +1,179 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { TransportRequestParams } from '@elastic/elasticsearch'; +import { CoreSetup, IRouter, RouteMethod } from '@kbn/core/server'; +import { UI_SETTINGS } from '@kbn/data-plugin/server'; +import type { + LogsSharedPluginRequestHandlerContext, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps, +} from '../../../types'; +import { + CallWithRequestParams, + LogsSharedDatabaseGetIndicesAliasResponse, + LogsSharedDatabaseGetIndicesResponse, + LogsSharedDatabaseMultiResponse, + LogsSharedDatabaseSearchResponse, + LogsSharedVersionedRouteConfig, +} from './adapter_types'; + +interface FrozenIndexParams { + ignore_throttled?: boolean; +} + +export class KibanaFramework { + public router: IRouter; + public plugins: LogsSharedServerPluginSetupDeps; + + constructor( + core: CoreSetup, + plugins: LogsSharedServerPluginSetupDeps + ) { + this.router = core.http.createRouter(); + this.plugins = plugins; + } + + public registerVersionedRoute( + config: LogsSharedVersionedRouteConfig + ) { + const defaultOptions = { + tags: ['access:infra'], + }; + const routeConfig = { + access: config.access, + path: config.path, + // Currently we have no use of custom options beyond tags, this can be extended + // beyond defaultOptions if it's needed. + options: defaultOptions, + }; + switch (config.method) { + case 'get': + return this.router.versioned.get(routeConfig); + case 'post': + return this.router.versioned.post(routeConfig); + case 'delete': + return this.router.versioned.delete(routeConfig); + case 'put': + return this.router.versioned.put(routeConfig); + case 'patch': + return this.router.versioned.patch(routeConfig); + default: + throw new RangeError( + `#registerVersionedRoute: "${config.method}" is not an accepted method` + ); + } + } + + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'search', + options?: CallWithRequestParams + ): Promise>; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'msearch', + options?: CallWithRequestParams + ): Promise>; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'indices.existsAlias', + options?: CallWithRequestParams + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'indices.getAlias', + options?: object + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'indices.get' | 'ml.getBuckets', + options?: object + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'transport.request', + options?: CallWithRequestParams + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: string, + options?: CallWithRequestParams + ): Promise; + public async callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: string, + params: CallWithRequestParams + ) { + const { elasticsearch, uiSettings } = await requestContext.core; + + const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); + if (endpoint === 'msearch') { + const maxConcurrentShardRequests = await uiSettings.client.get( + UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS + ); + if (maxConcurrentShardRequests > 0) { + params = { ...params, max_concurrent_shard_requests: maxConcurrentShardRequests }; + } + } + + // Only set the "ignore_throttled" value (to false) if the Kibana setting + // for "search:includeFrozen" is true (i.e. don't ignore throttled indices, a triple negative!) + // More information: + // - https://github.com/elastic/kibana/issues/113197 + // - https://github.com/elastic/elasticsearch/pull/77479 + // + // NOTE: these params only need to be spread onto the search and msearch calls below + const frozenIndicesParams: FrozenIndexParams = {}; + if (includeFrozen) { + frozenIndicesParams.ignore_throttled = false; + } + + let apiResult; + switch (endpoint) { + case 'search': + apiResult = elasticsearch.client.asCurrentUser.search({ + ...params, + ...frozenIndicesParams, + }); + break; + case 'msearch': + apiResult = elasticsearch.client.asCurrentUser.msearch({ + ...params, + ...frozenIndicesParams, + } as estypes.MsearchRequest); + break; + case 'indices.existsAlias': + apiResult = elasticsearch.client.asCurrentUser.indices.existsAlias({ + ...params, + } as estypes.IndicesExistsAliasRequest); + break; + case 'indices.getAlias': + apiResult = elasticsearch.client.asCurrentUser.indices.getAlias({ + ...params, + }); + break; + case 'indices.get': + apiResult = elasticsearch.client.asCurrentUser.indices.get({ + ...params, + } as estypes.IndicesGetRequest); + break; + case 'transport.request': + apiResult = elasticsearch.client.asCurrentUser.transport.request({ + ...params, + } as TransportRequestParams); + break; + case 'ml.getBuckets': + apiResult = elasticsearch.client.asCurrentUser.ml.getBuckets({ + ...params, + } as estypes.MlGetBucketsRequest); + break; + } + return apiResult ? await apiResult : undefined; + } +} diff --git a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts similarity index 96% rename from x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts rename to x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts index 97ef51ded269d3..66de5699cfb3e5 100644 --- a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ b/x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts @@ -12,7 +12,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import * as runtimeTypes from 'io-ts'; import { JsonArray } from '@kbn/utility-types'; import { compact } from 'lodash'; -import type { InfraPluginRequestHandlerContext } from '../../../types'; +import type { LogsSharedPluginRequestHandlerContext } from '../../../types'; import { LogEntriesAdapter, LogEntriesParams, @@ -28,11 +28,11 @@ import { TIMESTAMP_FIELD, TIEBREAKER_FIELD } from '../../../../common/constants' const TIMESTAMP_FORMAT = 'epoch_millis'; -export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { +export class LogsSharedKibanaLogEntriesAdapter implements LogEntriesAdapter { constructor(private readonly framework: KibanaFramework) {} public async getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, fields: string[], params: LogEntriesParams @@ -123,7 +123,7 @@ export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { } public async getContainedLogSummaryBuckets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, startTimestamp: number, endTimestamp: number, @@ -318,5 +318,3 @@ const LogSummaryResponseRuntimeType = runtimeTypes.type({ }), }), }); - -export type LogSummaryResponse = runtimeTypes.TypeOf; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/index.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/index.ts similarity index 100% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/index.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/index.ts diff --git a/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts new file mode 100644 index 00000000000000..74509f11ae4a7e --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ILogsSharedLogEntriesDomain } from './log_entries_domain'; + +export const createLogsSharedLogEntriesDomainMock = + (): jest.Mocked => { + return { + getLogEntriesAround: jest.fn(), + getLogEntries: jest.fn(), + getLogSummaryBucketsBetween: jest.fn(), + getLogSummaryHighlightBucketsBetween: jest.fn(), + getLogEntryDatasets: jest.fn(), + }; + }; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts similarity index 84% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts index fcda9b30b0dac1..92829c676b9358 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -26,8 +26,8 @@ import { Fields, Highlights, } from '../../../services/log_entries/message/message'; -import type { InfraPluginRequestHandlerContext } from '../../../types'; -import { InfraBackendLibs } from '../../infra_types'; +import type { LogsSharedPluginRequestHandlerContext } from '../../../types'; +import { LogsSharedBackendLibs } from '../../logs_shared_types'; import { CompositeDatasetKey, createLogEntryDatasetsQuery, @@ -59,14 +59,54 @@ const FIELDS_FROM_CONTEXT = ['log.file.path', 'host.name', 'container.id'] as co const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000; -export class InfraLogEntriesDomain { +export interface ILogsSharedLogEntriesDomain { + getLogEntriesAround( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + params: LogEntriesAroundParams, + columnOverrides?: LogViewColumnConfiguration[] + ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; + getLogEntries( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + params: LogEntriesParams, + columnOverrides?: LogViewColumnConfiguration[] + ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; + getLogSummaryBucketsBetween( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + start: number, + end: number, + bucketSize: number, + filterQuery?: LogEntryQuery + ): Promise; + getLogSummaryHighlightBucketsBetween( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + startTimestamp: number, + endTimestamp: number, + bucketSize: number, + highlightQueries: string[], + filterQuery?: LogEntryQuery + ): Promise; + getLogEntryDatasets( + requestContext: LogsSharedPluginRequestHandlerContext, + timestampField: string, + indexName: string, + startTime: number, + endTime: number, + runtimeMappings: estypes.MappingRuntimeFields + ): Promise; +} + +export class LogsSharedLogEntriesDomain implements ILogsSharedLogEntriesDomain { constructor( private readonly adapter: LogEntriesAdapter, - private readonly libs: Pick + private readonly libs: Pick ) {} public async getLogEntriesAround( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, params: LogEntriesAroundParams, columnOverrides?: LogViewColumnConfiguration[] @@ -126,7 +166,7 @@ export class InfraLogEntriesDomain { } public async getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, params: LogEntriesParams, columnOverrides?: LogViewColumnConfiguration[] @@ -184,7 +224,7 @@ export class InfraLogEntriesDomain { } public async getLogSummaryBucketsBetween( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, start: number, end: number, @@ -208,7 +248,7 @@ export class InfraLogEntriesDomain { } public async getLogSummaryHighlightBucketsBetween( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, startTimestamp: number, endTimestamp: number, @@ -255,7 +295,7 @@ export class InfraLogEntriesDomain { } public async getLogEntryDatasets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, timestampField: string, indexName: string, startTime: number, @@ -298,14 +338,14 @@ export class InfraLogEntriesDomain { export interface LogEntriesAdapter { getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, fields: string[], params: LogEntriesParams ): Promise<{ documents: LogEntryDocument[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; getContainedLogSummaryBuckets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, startTimestamp: number, endTimestamp: number, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts similarity index 96% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts index a658c7deb317c1..c2b966e86983f7 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts @@ -99,5 +99,3 @@ export const logEntryDatasetsResponseRT = rt.intersection([ }), }), ]); - -export type LogEntryDatasetsResponse = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts b/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts new file mode 100644 index 00000000000000..9d7ef50443c7f1 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/logging'; +import type { IBasePath } from '@kbn/core/server'; +import type { LogsSharedPluginStartServicesAccessor, UsageCollector } from '../types'; +import type { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; +import type { ILogsSharedLogEntriesDomain } from './domains/log_entries_domain'; + +export interface LogsSharedDomainLibs { + logEntries: ILogsSharedLogEntriesDomain; +} + +export interface LogsSharedBackendLibs extends LogsSharedDomainLibs { + basePath: IBasePath; + framework: KibanaFramework; + getStartServices: LogsSharedPluginStartServicesAccessor; + logger: Logger; + getUsageCollector: () => UsageCollector; +} diff --git a/x-pack/plugins/logs_shared/server/logs_shared_server.ts b/x-pack/plugins/logs_shared/server/logs_shared_server.ts new file mode 100644 index 00000000000000..60dc17be61d2df --- /dev/null +++ b/x-pack/plugins/logs_shared/server/logs_shared_server.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogsSharedBackendLibs } from './lib/logs_shared_types'; +import { + initLogEntriesHighlightsRoute, + initLogEntriesSummaryHighlightsRoute, + initLogEntriesSummaryRoute, +} from './routes/log_entries'; +import { initLogViewRoutes } from './routes/log_views'; + +export const initLogsSharedServer = (libs: LogsSharedBackendLibs) => { + initLogEntriesHighlightsRoute(libs); + initLogEntriesSummaryRoute(libs); + initLogEntriesSummaryHighlightsRoute(libs); + initLogViewRoutes(libs); +}; diff --git a/x-pack/plugins/logs_shared/server/mocks.ts b/x-pack/plugins/logs_shared/server/mocks.ts new file mode 100644 index 00000000000000..a8b16381d32f38 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/mocks.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createLogsSharedLogEntriesDomainMock } from './lib/domains/log_entries_domain/log_entries_domain.mock'; +import { + createLogViewsServiceSetupMock, + createLogViewsServiceStartMock, +} from './services/log_views/log_views_service.mock'; +import { LogsSharedPluginSetup, LogsSharedPluginStart } from './types'; + +const createLogsSharedSetupMock = () => { + const logsSharedSetupMock: jest.Mocked = { + logViews: createLogViewsServiceSetupMock(), + logEntries: createLogsSharedLogEntriesDomainMock(), + registerUsageCollectorActions: jest.fn(), + }; + + return logsSharedSetupMock; +}; + +const createLogsSharedStartMock = () => { + const logsSharedStartMock: jest.Mocked = { + logViews: createLogViewsServiceStartMock(), + }; + return logsSharedStartMock; +}; + +export const logsSharedPluginMock = { + createSetupContract: createLogsSharedSetupMock, + createStartContract: createLogsSharedStartMock, +}; diff --git a/x-pack/plugins/logs_shared/server/plugin.ts b/x-pack/plugins/logs_shared/server/plugin.ts new file mode 100644 index 00000000000000..6ccf743dba7f2f --- /dev/null +++ b/x-pack/plugins/logs_shared/server/plugin.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PluginInitializerContext, CoreStart, Plugin, Logger } from '@kbn/core/server'; + +import { + LogsSharedPluginCoreSetup, + LogsSharedPluginSetup, + LogsSharedPluginStart, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps, + UsageCollector, +} from './types'; +import { logViewSavedObjectType } from './saved_objects'; +import { initLogsSharedServer } from './logs_shared_server'; +import { LogViewsService } from './services/log_views'; +import { KibanaFramework } from './lib/adapters/framework/kibana_framework_adapter'; +import { LogsSharedBackendLibs, LogsSharedDomainLibs } from './lib/logs_shared_types'; +import { LogsSharedLogEntriesDomain } from './lib/domains/log_entries_domain'; +import { LogsSharedKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter'; +import { LogEntriesService } from './services/log_entries'; + +export class LogsSharedPlugin + implements + Plugin< + LogsSharedPluginSetup, + LogsSharedPluginStart, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps + > +{ + private readonly logger: Logger; + private libs!: LogsSharedBackendLibs; + private logViews: LogViewsService; + private usageCollector: UsageCollector; + + constructor(context: PluginInitializerContext) { + this.logger = context.logger.get(); + this.usageCollector = {}; + + this.logViews = new LogViewsService(this.logger.get('logViews')); + } + + public setup(core: LogsSharedPluginCoreSetup, plugins: LogsSharedServerPluginSetupDeps) { + const framework = new KibanaFramework(core, plugins); + + const logViews = this.logViews.setup(); + + // Register saved objects + core.savedObjects.registerType(logViewSavedObjectType); + + const domainLibs: LogsSharedDomainLibs = { + logEntries: new LogsSharedLogEntriesDomain(new LogsSharedKibanaLogEntriesAdapter(framework), { + framework, + getStartServices: () => core.getStartServices(), + }), + }; + + this.libs = { + ...domainLibs, + basePath: core.http.basePath, + framework, + getStartServices: () => core.getStartServices(), + logger: this.logger, + getUsageCollector: () => this.usageCollector, + }; + + // Register server side APIs + initLogsSharedServer(this.libs); + + const logEntriesService = new LogEntriesService(); + logEntriesService.setup(core, plugins); + + return { + ...domainLibs, + logViews, + registerUsageCollectorActions: (usageCollector: UsageCollector) => { + Object.assign(this.usageCollector, usageCollector); + }, + }; + } + + public start(core: CoreStart, plugins: LogsSharedServerPluginStartDeps) { + const logViews = this.logViews.start({ + savedObjects: core.savedObjects, + dataViews: plugins.dataViews, + elasticsearch: core.elasticsearch, + }); + + return { logViews }; + } + + public stop() {} +} diff --git a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts similarity index 96% rename from x-pack/plugins/infra/server/routes/log_entries/highlights.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts index 9d81e0d349f468..e8019c58d60006 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts @@ -15,14 +15,14 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; import { LogEntriesParams } from '../../lib/domains/log_entries_domain'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); -export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBackendLibs) => { +export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', diff --git a/x-pack/plugins/infra/server/routes/log_entries/index.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/index.ts similarity index 100% rename from x-pack/plugins/infra/server/routes/log_entries/index.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/index.ts diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts similarity index 83% rename from x-pack/plugins/infra/server/routes/log_entries/summary.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts index ee042f51d1dc8a..2ac889ab9ffdf3 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts @@ -15,14 +15,17 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; -import { UsageCollector } from '../../usage/usage_collector'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); -export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBackendLibs) => { +export const initLogEntriesSummaryRoute = ({ + framework, + logEntries, + getUsageCollector, +}: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', @@ -41,6 +44,8 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke ); const { logView, startTimestamp, endTimestamp, bucketSize, query } = payload; + const usageCollector = getUsageCollector(); + const buckets = await logEntries.getLogSummaryBucketsBetween( requestContext, logView, @@ -50,7 +55,9 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke parseFilterQuery(query) ); - UsageCollector.countLogs(); + if (typeof usageCollector.countLogs === 'function') { + usageCollector.countLogs(); + } return response.ok({ body: logEntriesV1.logEntriesSummaryResponseRT.encode({ diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts similarity index 95% rename from x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts index e831ec51c41451..b4093f1d6543b5 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts @@ -15,7 +15,7 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; @@ -24,7 +24,7 @@ const escapeHatch = schema.object({}, { unknowns: 'allow' }); export const initLogEntriesSummaryHighlightsRoute = ({ framework, logEntries, -}: InfraBackendLibs) => { +}: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', diff --git a/x-pack/plugins/infra/server/routes/log_views/get_log_view.ts b/x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts similarity index 92% rename from x-pack/plugins/infra/server/routes/log_views/get_log_view.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts index 0c3cb7cbac2af9..ef6e69f07d0efc 100644 --- a/x-pack/plugins/infra/server/routes/log_views/get_log_view.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts @@ -9,14 +9,14 @@ import { logViewsV1 } from '../../../common/http_api'; import { LOG_VIEW_URL } from '../../../common/http_api/log_views'; import { createValidationFunction } from '../../../common/runtime_types'; import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import type { InfraPluginStartServicesAccessor } from '../../types'; +import type { LogsSharedPluginStartServicesAccessor } from '../../types'; export const initGetLogViewRoute = ({ framework, getStartServices, }: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { framework .registerVersionedRoute({ diff --git a/x-pack/plugins/infra/server/routes/log_views/index.ts b/x-pack/plugins/logs_shared/server/routes/log_views/index.ts similarity index 82% rename from x-pack/plugins/infra/server/routes/log_views/index.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/index.ts index fa7e6f6e1b9d39..b2670cfa3e40ab 100644 --- a/x-pack/plugins/infra/server/routes/log_views/index.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/index.ts @@ -6,13 +6,13 @@ */ import { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraPluginStartServicesAccessor } from '../../types'; +import { LogsSharedPluginStartServicesAccessor } from '../../types'; import { initGetLogViewRoute } from './get_log_view'; import { initPutLogViewRoute } from './put_log_view'; export const initLogViewRoutes = (dependencies: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { initGetLogViewRoute(dependencies); initPutLogViewRoute(dependencies); diff --git a/x-pack/plugins/infra/server/routes/log_views/put_log_view.ts b/x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts similarity index 93% rename from x-pack/plugins/infra/server/routes/log_views/put_log_view.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts index 310960156abfc6..899200902aa1e1 100644 --- a/x-pack/plugins/infra/server/routes/log_views/put_log_view.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts @@ -9,14 +9,14 @@ import { logViewsV1 } from '../../../common/http_api'; import { LOG_VIEW_URL } from '../../../common/http_api/log_views'; import { createValidationFunction } from '../../../common/runtime_types'; import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import type { InfraPluginStartServicesAccessor } from '../../types'; +import type { LogsSharedPluginStartServicesAccessor } from '../../types'; export const initPutLogViewRoute = ({ framework, getStartServices, }: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { framework .registerVersionedRoute({ diff --git a/x-pack/plugins/logs_shared/server/saved_objects/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/index.ts new file mode 100644 index 00000000000000..bd7ecac5179a15 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/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 * from './log_view'; diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/index.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/index.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/index.ts diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts index 9202227867dca0..246c398ea5a65f 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts @@ -5,9 +5,9 @@ * 2.0. */ +import { SavedObject, SavedObjectsType } from '@kbn/core/server'; import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { SavedObject, SavedObjectsType } from '@kbn/core/server'; import { logViewSavedObjectRT } from './types'; export const logViewSavedObjectName = 'infrastructure-monitoring-log-view'; diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/references/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/index.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/references/index.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/references/index.ts diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts similarity index 85% rename from x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts index ea45be30bc0b77..660f01f47eb5e0 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts @@ -7,24 +7,24 @@ import { SavedObjectReference } from '@kbn/core/server'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; -import { LogViewAttributes } from '../../../../common/log_views'; import { SavedObjectAttributesWithReferences, SavedObjectReferenceResolutionError, } from '../../references'; +import { LogViewSavedObjectAttributes } from '../types'; export const logIndicesDataViewReferenceName = 'log-indices-data-view-0'; export const extractLogIndicesSavedObjectReferences = ( - unextractedAttributes: LogViewAttributes -): SavedObjectAttributesWithReferences => { + unextractedAttributes: LogViewSavedObjectAttributes +): SavedObjectAttributesWithReferences => { if (unextractedAttributes.logIndices.type === 'data_view') { const logDataViewReference: SavedObjectReference = { id: unextractedAttributes.logIndices.dataViewId, type: DATA_VIEW_SAVED_OBJECT_TYPE, name: logIndicesDataViewReferenceName, }; - const attributes: LogViewAttributes = { + const attributes: LogViewSavedObjectAttributes = { ...unextractedAttributes, logIndices: { ...unextractedAttributes.logIndices, @@ -44,9 +44,9 @@ export const extractLogIndicesSavedObjectReferences = ( }; export const resolveLogIndicesSavedObjectReferences = ( - attributes: LogViewAttributes, + attributes: LogViewSavedObjectAttributes, references: SavedObjectReference[] -): LogViewAttributes => { +): LogViewSavedObjectAttributes => { if (attributes.logIndices?.type === 'data_view') { const logDataViewReference = references.find( (reference) => reference.name === logIndicesDataViewReferenceName diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/types.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts similarity index 95% rename from x-pack/plugins/infra/server/saved_objects/log_view/types.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts index 34387b5e330856..fb8bf49781a2db 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/types.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts @@ -58,6 +58,8 @@ export const logViewSavedObjectAttributesRT = rt.strict({ logColumns: rt.array(logViewSavedObjectColumnConfigurationRT), }); +export type LogViewSavedObjectAttributes = rt.TypeOf; + export const logViewSavedObjectRT = rt.intersection([ rt.type({ id: rt.string, diff --git a/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts b/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts new file mode 100644 index 00000000000000..674aabbd9d0582 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectReference } from '@kbn/core/server'; +import { + extractSavedObjectReferences, + resolveSavedObjectReferences, + SavedObjectAttributesWithReferences, +} from './references'; + +it('extractSavedObjectReferences extracts references using the given extractors', () => { + const { attributes, references } = extractSavedObjectReferences([ + extractReferenceA, + extractReferenceB, + ])({ + a: 'id-a', + b: 'id-b', + c: 'something-else', + }); + + expect(references).toMatchObject([ + { id: 'id-a', name: REFERENCE_A_NAME, type: 'some-reference' }, + { id: 'id-b', name: REFERENCE_B_NAME, type: 'some-reference' }, + ]); + expect(attributes).toMatchObject({ + a: REFERENCE_A_NAME, + b: REFERENCE_B_NAME, + c: 'something-else', + }); +}); + +it('resolveSavedObjectReferences resolves references using the given resolvers', () => { + const attributes = resolveSavedObjectReferences([resolveReferenceA, resolveReferenceB])( + { + a: REFERENCE_A_NAME, + b: REFERENCE_B_NAME, + c: 'something-else', + }, + [ + { id: 'id-a', name: REFERENCE_A_NAME, type: 'some-reference' }, + { id: 'id-b', name: REFERENCE_B_NAME, type: 'some-reference' }, + ] + ); + + expect(attributes).toMatchObject({ + a: 'id-a', + b: 'id-b', + c: 'something-else', + }); +}); + +interface TestSavedObjectAttributes { + a: string; + b: string; + c: string; +} + +const REFERENCE_A_NAME = 'reference-a'; +const REFERENCE_B_NAME = 'reference-b'; + +const extractReferenceA = ( + attributes: TestSavedObjectAttributes +): SavedObjectAttributesWithReferences => ({ + attributes: { ...attributes, a: REFERENCE_A_NAME }, + references: [ + { + id: attributes.a, + name: REFERENCE_A_NAME, + type: 'some-reference', + }, + ], +}); + +const extractReferenceB = ( + attributes: TestSavedObjectAttributes +): SavedObjectAttributesWithReferences => ({ + attributes: { ...attributes, b: REFERENCE_B_NAME }, + references: [ + { + id: attributes.b, + name: REFERENCE_B_NAME, + type: 'some-reference', + }, + ], +}); + +const resolveReferenceA = ( + attributes: TestSavedObjectAttributes, + references: SavedObjectReference[] +): TestSavedObjectAttributes => { + const referenceA = references.find((reference) => reference.name === REFERENCE_A_NAME); + + if (referenceA != null) { + return { + ...attributes, + a: referenceA.id, + }; + } else { + return attributes; + } +}; + +const resolveReferenceB = ( + attributes: TestSavedObjectAttributes, + references: SavedObjectReference[] +): TestSavedObjectAttributes => { + const referenceB = references.find((reference) => reference.name === REFERENCE_B_NAME); + + if (referenceB != null) { + return { + ...attributes, + b: referenceB.id, + }; + } else { + return attributes; + } +}; diff --git a/x-pack/plugins/logs_shared/server/saved_objects/references.ts b/x-pack/plugins/logs_shared/server/saved_objects/references.ts new file mode 100644 index 00000000000000..13b64ab6e6e737 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/references.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 * as rt from 'io-ts'; +import { SavedObject, SavedObjectReference } from '@kbn/core/server'; + +export type SavedObjectAttributesWithReferences = Pick< + SavedObject, + 'attributes' | 'references' +>; + +export type SavedObjectReferenceExtractor = ( + savedObjectAttributes: SavedObjectAttributes +) => SavedObjectAttributesWithReferences; + +export type SavedObjectReferenceResolver = ( + savedObjectAttributes: SavedObjectAttributes, + references: SavedObjectReference[] +) => SavedObjectAttributes; + +export const savedObjectReferenceRT = rt.strict({ + name: rt.string, + type: rt.string, + id: rt.string, +}); + +/** + * Rewrites a saved object such that well-known saved object references + * are extracted in the `references` array and replaced by the appropriate + * name. This is the inverse operation to `resolveSavedObjectReferences`. + */ +export const extractSavedObjectReferences = + ( + referenceExtractors: Array> + ) => + ( + savedObjectAttributes: SavedObjectAttributes + ): SavedObjectAttributesWithReferences => + referenceExtractors.reduce>( + ({ attributes: accumulatedAttributes, references: accumulatedReferences }, extract) => { + const { attributes, references } = extract(accumulatedAttributes); + return { + attributes, + references: [...accumulatedReferences, ...references], + }; + }, + { + attributes: savedObjectAttributes, + references: [], + } + ); + +/** + * Rewrites a source configuration such that well-known saved object references + * are resolved from the `references` argument and replaced by the real saved + * object ids. This is the inverse operation to `extractSavedObjectReferences`. + */ +export const resolveSavedObjectReferences = + ( + referenceResolvers: Array> + ) => + (attributes: SavedObjectAttributes, references: SavedObjectReference[]): SavedObjectAttributes => + referenceResolvers.reduce( + (accumulatedAttributes, resolve) => resolve(accumulatedAttributes, references), + attributes + ); + +export class SavedObjectReferenceResolutionError extends Error { + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + this.name = 'SavedObjectReferenceResolutionError'; + } +} diff --git a/x-pack/plugins/infra/server/services/log_entries/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_service.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_service.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_service.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_service.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_redis.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_redis.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_redis.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_redis.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_system.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_system.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_system.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_system.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic_webserver.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic_webserver.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic_webserver.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic_webserver.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/helpers.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/helpers.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/helpers.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/helpers.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/message.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/message.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/message.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/message.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/rule_types.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/rule_types.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/common.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/common.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/common.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/common.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/log_entries.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entries.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/log_entries.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entries.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/log_entry.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/log_entry.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entry.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/types.ts b/x-pack/plugins/logs_shared/server/services/log_entries/types.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/types.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/types.ts diff --git a/x-pack/plugins/infra/server/services/log_views/errors.ts b/x-pack/plugins/logs_shared/server/services/log_views/errors.ts similarity index 65% rename from x-pack/plugins/infra/server/services/log_views/errors.ts rename to x-pack/plugins/logs_shared/server/services/log_views/errors.ts index fb0dc3b0315111..088dd6244bba6b 100644 --- a/x-pack/plugins/infra/server/services/log_views/errors.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/errors.ts @@ -5,9 +5,18 @@ * 2.0. */ +/* eslint-disable max-classes-per-file */ + export class NotFoundError extends Error { constructor(message?: string) { super(message); Object.setPrototypeOf(this, new.target.prototype); } } + +export class LogViewFallbackUnregisteredError extends Error { + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/x-pack/plugins/infra/server/services/log_views/index.ts b/x-pack/plugins/logs_shared/server/services/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_views/index.ts rename to x-pack/plugins/logs_shared/server/services/log_views/index.ts diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.mock.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.mock.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.mock.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.mock.ts diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts similarity index 88% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts index e517ae8aef7f0c..5efdf9e125deb0 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts @@ -17,42 +17,11 @@ import { LogViewsStaticConfig, } from '../../../common/log_views'; import { createLogViewMock } from '../../../common/log_views/log_view.mock'; -import { InfraSource } from '../../lib/sources'; -import { createInfraSourcesMock } from '../../lib/sources/mocks'; import { extractLogViewSavedObjectReferences, logViewSavedObjectName, } from '../../saved_objects/log_view'; -import { getAttributesFromSourceConfiguration, LogViewsClient } from './log_views_client'; - -describe('getAttributesFromSourceConfiguration function', () => { - it('converts the index_pattern log indices type to data_view', () => { - const logViewAttributes = getAttributesFromSourceConfiguration(basicTestSourceConfiguration); - - expect(logViewAttributes.logIndices).toEqual({ - type: 'data_view', - dataViewId: 'INDEX_PATTERN_ID', - }); - }); - - it('preserves the index_name log indices type', () => { - const logViewAttributes = getAttributesFromSourceConfiguration({ - ...basicTestSourceConfiguration, - configuration: { - ...basicTestSourceConfiguration.configuration, - logIndices: { - type: 'index_name', - indexName: 'INDEX_NAME', - }, - }, - }); - - expect(logViewAttributes.logIndices).toEqual({ - type: 'index_name', - indexName: 'INDEX_NAME', - }); - }); -}); +import { LogViewsClient } from './log_views_client'; describe('LogViewsClient class', () => { it('getLogView resolves the default id to a real saved object id if it exists', async () => { @@ -116,9 +85,9 @@ describe('LogViewsClient class', () => { }); it('getLogView preserves the default id for fallback lookups', async () => { - const { infraSources, logViewsClient, savedObjectsClient } = createLogViewsClient(); + const { logViewFallbackHandler, logViewsClient, savedObjectsClient } = createLogViewsClient(); - infraSources.getSourceConfiguration.mockResolvedValue(basicTestSourceConfiguration); + logViewFallbackHandler.mockResolvedValue(basicTestSourceConfiguration); savedObjectsClient.find.mockResolvedValue({ total: 0, @@ -129,10 +98,9 @@ describe('LogViewsClient class', () => { await logViewsClient.getLogView(defaultLogViewId); - expect(infraSources.getSourceConfiguration).toHaveBeenCalledWith( - savedObjectsClient, - defaultLogViewId - ); + expect(logViewFallbackHandler).toHaveBeenCalledWith(defaultLogViewId, { + soClient: savedObjectsClient, + }); }); it('putLogView resolves the default id to a real saved object id if one exists', async () => { @@ -364,7 +332,7 @@ const createLogViewsClient = () => { const logger = loggerMock.create(); const dataViews = dataViewsServiceMock; const savedObjectsClient = savedObjectsClientMock.create(); - const infraSources = createInfraSourcesMock(); + const logViewFallbackHandler = jest.fn(); const internalLogViews = new Map(); const logViewStaticConfig: LogViewsStaticConfig = { messageFields: ['message'], @@ -374,14 +342,14 @@ const createLogViewsClient = () => { logger, Promise.resolve(dataViews), savedObjectsClient, - infraSources, + logViewFallbackHandler, internalLogViews, logViewStaticConfig ); return { dataViews, - infraSources, + logViewFallbackHandler, internalLogViews, logViewStaticConfig, logViewsClient, @@ -389,7 +357,7 @@ const createLogViewsClient = () => { }; }; -const basicTestSourceConfiguration: InfraSource = { +const basicTestSourceConfiguration = { id: 'ID', origin: 'stored', configuration: { diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts similarity index 77% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts index 3f832c67707170..452bc1b3b969ec 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts @@ -16,7 +16,6 @@ import { import { defaultLogViewAttributes, defaultLogViewId, - LogIndexReference, LogView, LogViewAttributes, LogViewReference, @@ -26,16 +25,14 @@ import { resolveLogView, } from '../../../common/log_views'; import { decodeOrThrow } from '../../../common/runtime_types'; -import { LogIndexReference as SourceConfigurationLogIndexReference } from '../../../common/source_configuration/source_configuration'; -import type { IInfraSources, InfraSource } from '../../lib/sources'; import { extractLogViewSavedObjectReferences, logViewSavedObjectName, resolveLogViewSavedObjectReferences, } from '../../saved_objects/log_view'; import { logViewSavedObjectRT } from '../../saved_objects/log_view/types'; -import { NotFoundError } from './errors'; -import { ILogViewsClient } from './types'; +import { LogViewFallbackUnregisteredError, NotFoundError } from './errors'; +import { ILogViewsClient, LogViewFallbackHandler } from './types'; type DataViewsService = ReturnType; @@ -48,7 +45,7 @@ export class LogViewsClient implements ILogViewsClient { private readonly logger: Logger, private readonly dataViews: DataViewsService, private readonly savedObjectsClient: SavedObjectsClientContract, - private readonly infraSources: IInfraSources, + private readonly logViewFallbackHandler: LogViewFallbackHandler, private readonly internalLogViews: Map, private readonly config: LogViewsStaticConfig ) {} @@ -62,7 +59,7 @@ export class LogViewsClient implements ILogViewsClient { ) .catch((err) => err instanceof NotFoundError - ? this.getLogViewFromInfraSourceConfiguration(logViewId) + ? this.getLogViewFromLogsSharedSourceConfiguration(logViewId) : Promise.reject(err) ); } @@ -142,21 +139,16 @@ export class LogViewsClient implements ILogViewsClient { return internalLogView; } - private async getLogViewFromInfraSourceConfiguration(sourceId: string): Promise { - this.logger.debug(`Trying to load log view from source configuration "${sourceId}"...`); + private async getLogViewFromLogsSharedSourceConfiguration(sourceId: string): Promise { + this.logger.debug(`Trying to load log view from fallback configuration "${sourceId}"...`); - const sourceConfiguration = await this.infraSources.getSourceConfiguration( - this.savedObjectsClient, - sourceId - ); + if (this.logViewFallbackHandler === null) { + throw new LogViewFallbackUnregisteredError( + 'A fallback LogView handler is not registered. Register one in the setup method of your server plugin.' + ); + } - return { - id: sourceConfiguration.id, - version: sourceConfiguration.version, - updatedAt: sourceConfiguration.updatedAt, - origin: `infra-source-${sourceConfiguration.origin}`, - attributes: getAttributesFromSourceConfiguration(sourceConfiguration), - }; + return this.logViewFallbackHandler(sourceId, { soClient: this.savedObjectsClient }); } private async resolveLogViewId(logViewId: string): Promise { @@ -197,22 +189,3 @@ const getLogViewFromSavedObject = (savedObject: SavedObject): LogView = ), }; }; - -export const getAttributesFromSourceConfiguration = ({ - configuration: { name, description, logIndices, logColumns }, -}: InfraSource): LogViewAttributes => ({ - name, - description, - logIndices: getLogIndicesFromSourceConfigurationLogIndices(logIndices), - logColumns, -}); - -const getLogIndicesFromSourceConfigurationLogIndices = ( - logIndices: SourceConfigurationLogIndexReference -): LogIndexReference => - logIndices.type === 'index_pattern' - ? { - type: 'data_view', - dataViewId: logIndices.indexPatternId, - } - : logIndices; diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts similarity index 90% rename from x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts index e472e30fae2b4f..295b1fd77452f7 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts @@ -10,6 +10,8 @@ import { LogViewsServiceSetup, LogViewsServiceStart } from './types'; export const createLogViewsServiceSetupMock = (): jest.Mocked => ({ defineInternalLogView: jest.fn(), + registerLogViewFallbackHandler: jest.fn(), + setLogViewsStaticConfig: jest.fn(), }); export const createLogViewsServiceStartMock = (): jest.Mocked => ({ diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_service.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts similarity index 65% rename from x-pack/plugins/infra/server/services/log_views/log_views_service.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts index cf1c7595ae5cb1..5479c16dff411a 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_service.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts @@ -11,12 +11,25 @@ import { Logger, SavedObjectsClientContract, } from '@kbn/core/server'; -import { defaultLogViewAttributes, LogView, LogViewAttributes } from '../../../common/log_views'; +import { + defaultLogViewAttributes, + defaultLogViewsStaticConfig, + LogView, + LogViewAttributes, + LogViewsStaticConfig, +} from '../../../common/log_views'; import { LogViewsClient } from './log_views_client'; -import { LogViewsServiceSetup, LogViewsServiceStart, LogViewsServiceStartDeps } from './types'; +import { + LogViewFallbackHandler, + LogViewsServiceSetup, + LogViewsServiceStart, + LogViewsServiceStartDeps, +} from './types'; export class LogViewsService { private internalLogViews: Map = new Map(); + private logViewFallbackHandler: LogViewFallbackHandler | null = null; + private logViewsStaticConfig: LogViewsStaticConfig = defaultLogViewsStaticConfig; constructor(private readonly logger: Logger) {} @@ -24,7 +37,7 @@ export class LogViewsService { const { internalLogViews } = this; return { - defineInternalLogView(logViewId: string, logViewAttributes: Partial) { + defineInternalLogView: (logViewId: string, logViewAttributes: Partial) => { internalLogViews.set(logViewId, { id: logViewId, origin: 'internal', @@ -32,17 +45,21 @@ export class LogViewsService { updatedAt: Date.now(), }); }, + registerLogViewFallbackHandler: (handler) => { + this.logViewFallbackHandler = handler; + }, + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => { + this.logViewsStaticConfig = config; + }, }; } public start({ - config, dataViews, elasticsearch, - infraSources, savedObjects, }: LogViewsServiceStartDeps): LogViewsServiceStart { - const { internalLogViews, logger } = this; + const { internalLogViews, logger, logViewFallbackHandler, logViewsStaticConfig } = this; return { getClient( @@ -54,9 +71,9 @@ export class LogViewsService { logger, dataViews.dataViewsServiceFactory(savedObjectsClient, elasticsearchClient, request), savedObjectsClient, - infraSources, + logViewFallbackHandler, internalLogViews, - config + logViewsStaticConfig ); }, getScopedClient(request: KibanaRequest) { diff --git a/x-pack/plugins/infra/server/services/log_views/types.ts b/x-pack/plugins/logs_shared/server/services/log_views/types.ts similarity index 81% rename from x-pack/plugins/infra/server/services/log_views/types.ts rename to x-pack/plugins/logs_shared/server/services/log_views/types.ts index b5f91cb3587b4d..db1410207c11aa 100644 --- a/x-pack/plugins/infra/server/services/log_views/types.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/types.ts @@ -20,18 +20,25 @@ import { LogViewsStaticConfig, ResolvedLogView, } from '../../../common/log_views'; -import { InfraSources } from '../../lib/sources'; export interface LogViewsServiceStartDeps { - config: LogViewsStaticConfig; dataViews: DataViewsServerPluginStart; elasticsearch: ElasticsearchServiceStart; - infraSources: InfraSources; savedObjects: SavedObjectsServiceStart; } +export interface LogViewFallbackHandlerOptions { + soClient: SavedObjectsClientContract; +} + +export type LogViewFallbackHandler = + | ((sourceId: string, options: LogViewFallbackHandlerOptions) => Promise) + | null; + export interface LogViewsServiceSetup { defineInternalLogView(logViewId: string, logViewAttributes: Partial): void; + registerLogViewFallbackHandler: (handler: LogViewFallbackHandler) => void; + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => void; } export interface LogViewsServiceStart { diff --git a/x-pack/plugins/logs_shared/server/types.ts b/x-pack/plugins/logs_shared/server/types.ts new file mode 100644 index 00000000000000..2e922eceeb183a --- /dev/null +++ b/x-pack/plugins/logs_shared/server/types.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 type { CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import { + PluginSetup as DataPluginSetup, + PluginStart as DataPluginStart, +} from '@kbn/data-plugin/server'; +import { PluginStart as DataViewsPluginStart } from '@kbn/data-views-plugin/server'; +import { LogsSharedDomainLibs } from './lib/logs_shared_types'; +import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views/types'; + +export type LogsSharedPluginCoreSetup = CoreSetup< + LogsSharedServerPluginStartDeps, + LogsSharedPluginStart +>; +export type LogsSharedPluginStartServicesAccessor = LogsSharedPluginCoreSetup['getStartServices']; + +export interface LogsSharedPluginSetup extends LogsSharedDomainLibs { + logViews: LogViewsServiceSetup; + registerUsageCollectorActions: (usageCollector: UsageCollector) => void; +} + +export interface LogsSharedPluginStart { + logViews: LogViewsServiceStart; +} + +export interface LogsSharedServerPluginSetupDeps { + data: DataPluginSetup; +} + +export interface LogsSharedServerPluginStartDeps { + data: DataPluginStart; + dataViews: DataViewsPluginStart; +} + +export interface UsageCollector { + countLogs?: () => void; +} + +/** + * @internal + */ +export type LogsSharedPluginRequestHandlerContext = RequestHandlerContext; diff --git a/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts b/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts new file mode 100644 index 00000000000000..e2dbf02ae2d06f --- /dev/null +++ b/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const shardFailureRT = rt.partial({ + index: rt.union([rt.string, rt.null]), + node: rt.union([rt.string, rt.null]), + reason: rt.partial({ + reason: rt.union([rt.string, rt.null]), + type: rt.union([rt.string, rt.null]), + }), + shard: rt.number, +}); + +export type ShardFailure = rt.TypeOf; + +export const commonSearchSuccessResponseFieldsRT = rt.type({ + _shards: rt.intersection([ + rt.type({ + total: rt.number, + successful: rt.number, + skipped: rt.number, + failed: rt.number, + }), + rt.partial({ + failures: rt.array(shardFailureRT), + }), + ]), + timed_out: rt.boolean, + took: rt.number, +}); + +export const commonHitFieldsRT = rt.type({ + _index: rt.string, + _id: rt.string, +}); diff --git a/x-pack/plugins/logs_shared/server/utils/serialized_query.ts b/x-pack/plugins/logs_shared/server/utils/serialized_query.ts new file mode 100644 index 00000000000000..b3b2569528aeae --- /dev/null +++ b/x-pack/plugins/logs_shared/server/utils/serialized_query.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { JsonObject } from '@kbn/utility-types'; + +export const parseFilterQuery = ( + filterQuery: string | null | undefined +): JsonObject | undefined => { + try { + if (filterQuery) { + const parsedFilterQuery = JSON.parse(filterQuery); + if ( + !parsedFilterQuery || + ['string', 'number', 'boolean'].includes(typeof parsedFilterQuery) || + Array.isArray(parsedFilterQuery) + ) { + throw new Error('expected value to be an object'); + } + return parsedFilterQuery; + } else { + return undefined; + } + } catch (err) { + throw new Error(`Failed to parse query: ${err}`); + } +}; diff --git a/x-pack/plugins/infra/server/utils/typed_search_strategy.ts b/x-pack/plugins/logs_shared/server/utils/typed_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/utils/typed_search_strategy.ts rename to x-pack/plugins/logs_shared/server/utils/typed_search_strategy.ts diff --git a/x-pack/plugins/logs_shared/tsconfig.json b/x-pack/plugins/logs_shared/tsconfig.json new file mode 100644 index 00000000000000..31c44666159740 --- /dev/null +++ b/x-pack/plugins/logs_shared/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types" + }, + "include": ["../../../typings/**/*", "common/**/*", "public/**/*", "server/**/*", "types/**/*"], + "exclude": ["target/**/*"], + "kbn_references": [ + "@kbn/core", + "@kbn/i18n", + "@kbn/i18n-react", + "@kbn/data-views-plugin", + "@kbn/io-ts-utils", + "@kbn/data-plugin", + "@kbn/kibana-utils-plugin", + "@kbn/es-query", + "@kbn/utility-types", + "@kbn/core-http-server", + "@kbn/logging", + "@kbn/config-schema", + "@kbn/std", + "@kbn/logging-mocks", + "@kbn/kibana-react-plugin", + "@kbn/test-subj-selector", + "@kbn/observability-shared-plugin", + "@kbn/observability-plugin", + "@kbn/datemath", + "@kbn/core-http-browser", + "@kbn/ui-actions-plugin", + ] +} diff --git a/x-pack/plugins/monitoring/kibana.jsonc b/x-pack/plugins/monitoring/kibana.jsonc index 236e6390d1bcea..8da632c4b7d6ff 100644 --- a/x-pack/plugins/monitoring/kibana.jsonc +++ b/x-pack/plugins/monitoring/kibana.jsonc @@ -19,6 +19,7 @@ ], "optionalPlugins": [ "infra", + "logsShared", "usageCollection", "home", "cloud", diff --git a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts b/x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts similarity index 74% rename from x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts rename to x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts index 43fb8f7cc5dbd8..52b0f436473864 100644 --- a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts +++ b/x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts @@ -5,20 +5,20 @@ * 2.0. */ -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { CCS_REMOTE_PATTERN, INFRA_SOURCE_ID } from '../../../common/constants'; import { MonitoringConfig } from '../../config'; import { getIndexPatterns } from '../cluster/get_index_patterns'; -export const initInfraSource = (config: MonitoringConfig, infraPlugin: InfraPluginSetup) => { - if (infraPlugin) { +export const initLogView = (config: MonitoringConfig, logsShared: LogsSharedPluginSetup) => { + if (logsShared) { const logsIndexPattern = getIndexPatterns({ config, type: 'logs', ccs: CCS_REMOTE_PATTERN, }); - infraPlugin.logViews.defineInternalLogView(INFRA_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(INFRA_SOURCE_ID, { name: 'Elastic Stack Logs', logIndices: { type: 'index_name', diff --git a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts index b743e0300aef61..e7ffe701fbd1ae 100644 --- a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts +++ b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts @@ -7,6 +7,7 @@ import { featuresPluginMock } from '@kbn/features-plugin/server/mocks'; import { infraPluginMock } from '@kbn/infra-plugin/server/mocks'; +import { logsSharedPluginMock } from '@kbn/logs-shared-plugin/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/server/mocks'; import { configSchema, createConfig } from '../../../config'; @@ -38,6 +39,7 @@ const mockReq = ( usageCollection: usageCollectionSetup, features: featuresPluginMock.createSetup(), infra: infraPluginMock.createSetupContract(), + logsShared: logsSharedPluginMock.createSetupContract(), }, }, }, diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 5996eb125b6dc8..1747855112964b 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -35,7 +35,7 @@ import { configSchema, createConfig, MonitoringConfig } from './config'; import { instantiateClient } from './es_client/instantiate_client'; import { initBulkUploader } from './kibana_monitoring'; import { registerCollectors } from './kibana_monitoring/collectors'; -import { initInfraSource } from './lib/logs/init_infra_source'; +import { initLogView } from './lib/logs/init_log_view'; import { LicenseService } from './license_service'; import { requireUIRoutes } from './routes'; import { EndpointTypes, Globals } from './static_globals'; @@ -202,7 +202,7 @@ export class MonitoringPlugin alerting: plugins.alerting, logger: this.log, }); - initInfraSource(config, plugins.infra); + initLogView(config, plugins.logsShared); } } diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index 64931f58885140..7e056cbac5fb81 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -35,6 +35,7 @@ import { PluginSetupContract as FeaturesPluginSetupContract } from '@kbn/feature import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; import { RouteConfig, RouteMethod, Headers } from '@kbn/core/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { ElasticsearchModifiedSource } from '../common/types/es'; import { RulesByType } from '../common/types/alerts'; import { configSchema, MonitoringConfig } from './config'; @@ -56,6 +57,7 @@ export interface PluginsSetup { alerting?: AlertingPluginSetupContract; infra: InfraPluginSetup; cloud?: CloudSetup; + logsShared: LogsSharedPluginSetup; } export type RequestHandlerContextMonitoringPlugin = CustomRequestHandlerContext<{ diff --git a/x-pack/plugins/monitoring/tsconfig.json b/x-pack/plugins/monitoring/tsconfig.json index 5ebd037e046481..00ca9625681410 100644 --- a/x-pack/plugins/monitoring/tsconfig.json +++ b/x-pack/plugins/monitoring/tsconfig.json @@ -41,6 +41,7 @@ "@kbn/shared-ux-router", "@kbn/observability-shared-plugin", "@kbn/shared-ux-link-redirect-app", + "@kbn/logs-shared-plugin", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1f9d308c783fbf..29c1982ae0d3b1 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -18117,7 +18117,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "Aucun index ne correspond au modèle {index}", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "Il manque un champ {field} obligatoire dans au moins un index correspondant à {index}.", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "Au moins un index correspondant à {index} comprend un champ appelé {field} sans le type correct.", - "xpack.infra.dataSearch.shardFailureErrorMessage": "Index {indexName} : {errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "Ajustez votre indexation pour identifier les conteneurs Docker utilisant \"{field}\"", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "La configuration de \"xpack.infra.sources.default.fields.{fieldKey}\" a été déclassée et sera retirée dans la version 8.0.0.", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "\"{fieldKey}\" est déclassé.", @@ -18138,8 +18137,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} n'existe pas.", "xpack.infra.linkTo.hostWithIp.error": "Hôte avec l'adresse IP \"{hostIp}\" introuvable.", "xpack.infra.linkTo.hostWithIp.loading": "Chargement de l'hôte avec l'adresse IP \"{hostIp}\" en cours.", - "xpack.infra.logFlyout.flyoutSubTitle": "À partir de l'index {indexName}", - "xpack.infra.logFlyout.flyoutTitle": "Détails de l'entrée de log {logEntryId}", "xpack.infra.logs.alertDetails.chart.chartTitle": "Logs pour {criteria}", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "Lors de la définition d'une valeur \"regrouper par\", nous recommandons fortement d'utiliser le comparateur \"{comparator}\" pour votre seuil. Cela peut permettre d'améliorer considérablement les performances.", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "{actualCount, plural, one {la {actualCount} dernière entrée de log} many {les {actualCount} dernières entrées de log} other {les {actualCount} dernières entrées de log}} dans {duration} pour {groupName}. Alerte lorsque {comparator} {expectedCount}.", @@ -18157,22 +18154,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "Pour en savoir plus, consultez {machineLearningAppLink}.", "xpack.infra.logs.common.invalidStateMessage": "Impossible de traiter l'état {stateValue}.", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {Petite} medium {Moyenne} large {Large} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {jour} many {jours} other {jours}}", - "xpack.infra.logs.extendTimeframeByHoursButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {heure} many {heures} other {heures}}", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {milliseconde} many {millisecondes} other {millisecondes}}", - "xpack.infra.logs.extendTimeframeByMinutesButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {minute} many {minutes} other {minutes}}", - "xpack.infra.logs.extendTimeframeByMonthsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {mois} many {mois} other {mois}}", - "xpack.infra.logs.extendTimeframeBySecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {seconde} many {secondes} other {secondes}}", - "xpack.infra.logs.extendTimeframeByWeeksButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {semaine} many {semaines} other {semaines}}", - "xpack.infra.logs.extendTimeframeByYearsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {an} many {années} other {années}}", - "xpack.infra.logs.lastUpdate": "Dernière mise à jour {timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "Le rapport de catégories par document analysé est très élevé avec {categoriesDocumentRatio, number}.", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "Aucun nouveau message n'est attribué à {deadCategoriesRatio, number, percent} des catégories, car des catégories moins spécifiques les masquent.", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "Les messages sont rarement attribués à {rareCategoriesRatio, number, percent} des catégories.", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, one {un autre segment} many {# autres segments} other {# autres segments}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, one {# entrée mise en surbrillance} many {# entrées mises en surbrillance} other {# entrées mises en surbrillance}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "Affichage des entrées à partir de {timestamp}", - "xpack.infra.logs.showingEntriesUntilTimestamp": "Affichage des entrées jusqu'à {timestamp}", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "Les logs affichés proviennent du conteneur {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "Les logs affichés proviennent du fichier {file} et de l'hôte {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "Le champ {messageField} doit être un champ textuel.", @@ -18283,9 +18269,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "Données insuffisantes", "xpack.infra.common.tabBetaBadgeLabel": "Version bêta", "xpack.infra.configureSourceActionLabel": "Modifier la configuration de la source", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "La demande a été annulée.", - "xpack.infra.dataSearch.cancelButtonLabel": "Annuler la demande", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "Réessayer", "xpack.infra.deprecations.containerIdFieldName": "ID de conteneur", "xpack.infra.deprecations.containerIdFieldTitle": "Le champ de configuration source \"ID de conteneur\" est déclassé.", "xpack.infra.deprecations.hostnameFieldName": "nom d'hôte", @@ -18439,18 +18422,7 @@ "xpack.infra.legendControls.stepsLabel": "Nombre de couleurs", "xpack.infra.legendControls.switchLabel": "Calculer automatiquement la plage", "xpack.infra.legnedControls.boundRangeError": "La valeur minimale doit être inférieure à la valeur maximale", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "Afficher en contexte", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "Afficher les actions de l'entrée du log", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "Afficher dans APM", - "xpack.infra.logEntryActionsMenu.buttonLabel": "Examiner", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "Afficher le statut dans Uptime", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "Afficher les actions de la ligne", - "xpack.infra.logFlyout.fieldColumnLabel": "Champ", - "xpack.infra.logFlyout.filterAriaLabel": "Filtre", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "Erreur lors de la recherche de l'entrée de log", - "xpack.infra.logFlyout.loadingMessage": "Recherche de l'entrée de log dans les partitions", - "xpack.infra.logFlyout.setFilterTooltip": "Afficher l'événement avec filtre", - "xpack.infra.logFlyout.valueColumnLabel": "Valeur", "xpack.infra.logs.alertDetails.chart.ratioTitle": "Ratio de Requête A à Requête B", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "Alerte démarrée", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "Alertes déclenchées", @@ -18569,9 +18541,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "Retour automatique à la ligne", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "Taille du texte", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "Formater les longues lignes", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "Rechercher de nouvelles données", - "xpack.infra.logs.emptyView.noLogMessageDescription": "Essayez d'ajuster votre filtre.", - "xpack.infra.logs.emptyView.noLogMessageTitle": "Il n'y a aucun message de log à afficher.", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "Effacer les termes à mettre en surbrillance", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "Passer au surlignage suivant", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "Passer au surlignage précédent", @@ -18581,10 +18550,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "Catégories", "xpack.infra.logs.index.settingsTabTitle": "Paramètres", "xpack.infra.logs.index.streamTabTitle": "Flux", - "xpack.infra.logs.jumpToTailText": "Passer aux entrées les plus récentes", - "xpack.infra.logs.loadingNewEntriesText": "Chargement des nouvelles entrées", "xpack.infra.logs.logCategoriesTitle": "Catégories", - "xpack.infra.logs.logEntryActionsDetailsButton": "Afficher les détails", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "Analyse dans ML", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "Analysez cette catégorie dans l'application ML.", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "Catégorie", @@ -18615,7 +18581,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "Ajouter une intégration au logging", "xpack.infra.logs.noDataConfig.solutionName": "Observabilité", "xpack.infra.logs.pluginTitle": "Logs", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "Chargement des entrées", "xpack.infra.logs.search.nextButtonLabel": "Suivant", "xpack.infra.logs.search.previousButtonLabel": "Précédent", "xpack.infra.logs.search.searchInLogsAriaLabel": "rechercher", @@ -18625,10 +18590,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "Vue de log en ligne utilisée", "xpack.infra.logs.startStreamingButtonLabel": "Diffuser en direct", "xpack.infra.logs.stopStreamingButtonLabel": "Arrêter la diffusion", - "xpack.infra.logs.stream.messageColumnTitle": "Message", - "xpack.infra.logs.stream.timestampColumnTitle": "Horodatage", - "xpack.infra.logs.streamingNewEntriesText": "Diffusion de nouvelles entrées", - "xpack.infra.logs.streamLive": "Diffuser en direct", "xpack.infra.logs.streamPageTitle": "Flux", "xpack.infra.logsHeaderAddDataButtonLabel": "Ajouter des données", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "L'état d'au moins un champ du formulaire est non valide.", @@ -18655,8 +18616,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "Réessayer", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "Recherche d'entrées de log… (par ex. host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "Erreur de filtrage du log", - "xpack.infra.logStream.kqlErrorTitle": "Expression KQL non valide", - "xpack.infra.logStream.unknownErrorTitle": "Une erreur s'est produite", "xpack.infra.logStreamEmbeddable.description": "Ajoutez un tableau de logs de diffusion en direct.", "xpack.infra.logStreamEmbeddable.displayName": "Flux de log", "xpack.infra.logStreamEmbeddable.title": "Flux de log", @@ -19283,6 +19242,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "Impossible de sélectionner les options ou la valeur pour l'indicateur.", "xpack.infra.waffleTime.autoRefreshButtonLabel": "Actualisation automatique", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "Arrêter l'actualisation", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "Index {indexName} : {errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "À partir de l'index {indexName}", + "xpack.logsShared.logFlyout.flyoutTitle": "Détails de l'entrée de log {logEntryId}", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {jour} many {jours} other {jours}}", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {heure} many {heures} other {heures}}", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {milliseconde} many {millisecondes} other {millisecondes}}", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {minute} many {minutes} other {minutes}}", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {mois} many {mois} other {mois}}", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {seconde} many {secondes} other {secondes}}", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {semaine} many {semaines} other {semaines}}", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {an} many {années} other {années}}", + "xpack.logsShared.logs.lastUpdate": "Dernière mise à jour {timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "Affichage des entrées à partir de {timestamp}", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "Affichage des entrées jusqu'à {timestamp}", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "La demande a été annulée.", + "xpack.logsShared.dataSearch.cancelButtonLabel": "Annuler la demande", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "Réessayer", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "Afficher en contexte", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "Afficher dans APM", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "Examiner", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "Afficher le statut dans Uptime", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "Afficher les actions de la ligne", + "xpack.logsShared.logFlyout.fieldColumnLabel": "Champ", + "xpack.logsShared.logFlyout.filterAriaLabel": "Filtre", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "Erreur lors de la recherche de l'entrée de log", + "xpack.logsShared.logFlyout.loadingMessage": "Recherche de l'entrée de log dans les partitions", + "xpack.logsShared.logFlyout.setFilterTooltip": "Afficher l'événement avec filtre", + "xpack.logsShared.logFlyout.valueColumnLabel": "Valeur", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "Rechercher de nouvelles données", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "Essayez d'ajuster votre filtre.", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "Il n'y a aucun message de log à afficher.", + "xpack.logsShared.logs.jumpToTailText": "Passer aux entrées les plus récentes", + "xpack.logsShared.logs.loadingNewEntriesText": "Chargement des nouvelles entrées", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "Afficher les détails", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "Chargement des entrées", + "xpack.logsShared.logs.stream.messageColumnTitle": "Message", + "xpack.logsShared.logs.stream.timestampColumnTitle": "Horodatage", + "xpack.logsShared.logs.streamingNewEntriesText": "Diffusion de nouvelles entrées", + "xpack.logsShared.logs.streamLive": "Diffuser en direct", + "xpack.logsShared.logStream.kqlErrorTitle": "Expression KQL non valide", + "xpack.logsShared.logStream.unknownErrorTitle": "Une erreur s'est produite", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "Pour utiliser l'option Ingérer des pipelines, vous devez avoir {privilegesCount, plural, one {ce privilège de cluster} many {ces privilèges de cluster} other {ces privilèges de cluster}} : {missingPrivileges}.", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "Impossible de charger {name}.", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 602616c9ffacce..2b610e8af95c6f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18116,7 +18116,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "インデックスがパターン{index}と一致しません", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "{index}と一致する1つ以上のインデックスに、必須フィールド{field}がありません。", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "{index}と一致する1つ以上のインデックスに、正しい型がない{field}フィールドがあります。", - "xpack.infra.dataSearch.shardFailureErrorMessage": "インデックス{indexName}:{errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "インデックスを調整し、\"{field}\"を使用してDockerコンテナーを特定", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "「xpack.infra.sources.default.fields.{fieldKey}」の構成は廃止予定であり、8.0.0で削除されます。", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "\"{fieldKey}\"は廃止予定です。", @@ -18137,8 +18136,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId}は存在しません。", "xpack.infra.linkTo.hostWithIp.error": "IPアドレス「{hostIp}」でホストが見つかりません。", "xpack.infra.linkTo.hostWithIp.loading": "IPアドレス「{hostIp}」のホストを読み込み中です。", - "xpack.infra.logFlyout.flyoutSubTitle": "インデックス{indexName}から", - "xpack.infra.logFlyout.flyoutTitle": "ログエントリ{logEntryId}の詳細", "xpack.infra.logs.alertDetails.chart.chartTitle": "{criteria} のログ", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "「group by」を設定するときには、しきい値で\"{comparator}\"比較演算子を使用することを強くお勧めします。これにより、パフォーマンスを大きく改善できます。", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "{groupName}の過去{duration}の{actualCount, plural, other {{actualCount}件のログエントリ}}。{comparator} {expectedCount}のときにアラートを通知します。", @@ -18156,22 +18153,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "詳細は {machineLearningAppLink} をご覧ください。", "xpack.infra.logs.common.invalidStateMessage": "状態{stateValue}を処理できません。", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {小} medium {中} large {大} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "タイムフレームを{amount, number}{amount, plural, other {日}}延長", - "xpack.infra.logs.extendTimeframeByHoursButton": "タイムフレームを{amount, number}{amount, plural, other {時間}}延長", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "タイムフレームを{amount, number}{amount, plural, other {ミリ秒}}延長", - "xpack.infra.logs.extendTimeframeByMinutesButton": "タイムフレームを{amount, number}{amount, plural, other {分}}延長", - "xpack.infra.logs.extendTimeframeByMonthsButton": "タイムフレームを{amount, number}{amount, plural, other {月}}延長", - "xpack.infra.logs.extendTimeframeBySecondsButton": "タイムフレームを{amount, number}{amount, plural, other {秒}}延長", - "xpack.infra.logs.extendTimeframeByWeeksButton": "タイムフレームを{amount, number}{amount, plural, other {週}}延長", - "xpack.infra.logs.extendTimeframeByYearsButton": "タイムフレームを{amount, number}{amount, plural, other {年}}延長", - "xpack.infra.logs.lastUpdate": "最終更新:{timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "分析されたドキュメントごとのカテゴリ比率が{categoriesDocumentRatio, number}で、非常に高い値です。", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "特定のカテゴリが少ないことで、目立たなくなるため、{deadCategoriesRatio, number, percent}のカテゴリには新しいメッセージが割り当てられません。", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "{rareCategoriesRatio, number, percent}のカテゴリには、ほとんどメッセージが割り当てられません。", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, other {#個の追加のセグメント}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {#個のハイライトされたエントリ}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "{timestamp}以降のエントリーを表示中", - "xpack.infra.logs.showingEntriesUntilTimestamp": "{timestamp}までのエントリーを表示中", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "表示されたログはコンテナー{container}から取得されました", "xpack.infra.logs.viewInContext.logsFromFileTitle": "表示されたログは、ファイル{file}およびホスト{host}から取得されました", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField}フィールドはテキストフィールドでなければなりません。", @@ -18282,9 +18268,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "データが不十分です", "xpack.infra.common.tabBetaBadgeLabel": "ベータ", "xpack.infra.configureSourceActionLabel": "ソース構成を変更", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "リクエストが中断されましたか。", - "xpack.infra.dataSearch.cancelButtonLabel": "リクエストのキャンセル", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "再試行", "xpack.infra.deprecations.containerIdFieldName": "コンテナーID", "xpack.infra.deprecations.containerIdFieldTitle": "ソース構成フィールド[コンテナーID]は廃止予定です。", "xpack.infra.deprecations.hostnameFieldName": "ホスト名", @@ -18438,18 +18421,7 @@ "xpack.infra.legendControls.stepsLabel": "色の数", "xpack.infra.legendControls.switchLabel": "自動計算範囲", "xpack.infra.legnedControls.boundRangeError": "最小値は最大値よりも小さくなければなりません", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "コンテキストで表示", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "ログエントリのアクションを表示", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "APMで表示", - "xpack.infra.logEntryActionsMenu.buttonLabel": "調査", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "行のアクションを表示", - "xpack.infra.logFlyout.fieldColumnLabel": "フィールド", - "xpack.infra.logFlyout.filterAriaLabel": "フィルター", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "ログエントリの検索中のエラー", - "xpack.infra.logFlyout.loadingMessage": "シャードのログエントリを検索しています", - "xpack.infra.logFlyout.setFilterTooltip": "フィルターでイベントを表示", - "xpack.infra.logFlyout.valueColumnLabel": "値", "xpack.infra.logs.alertDetails.chart.ratioTitle": "クエリAとクエリBの比率", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "アラートが開始しました", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "アラートがトリガーされました", @@ -18568,9 +18540,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "改行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "テキストサイズ", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "長い行を改行", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "新規データを確認", - "xpack.infra.logs.emptyView.noLogMessageDescription": "フィルターを調整してみてください。", - "xpack.infra.logs.emptyView.noLogMessageTitle": "表示するログメッセージがありません。", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "ハイライトする用語をクリア", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "次のハイライトにスキップ", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "前のハイライトにスキップ", @@ -18580,10 +18549,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "カテゴリー", "xpack.infra.logs.index.settingsTabTitle": "設定", "xpack.infra.logs.index.streamTabTitle": "ストリーム", - "xpack.infra.logs.jumpToTailText": "最も新しいエントリーに移動", - "xpack.infra.logs.loadingNewEntriesText": "新しいエントリーを読み込み中", "xpack.infra.logs.logCategoriesTitle": "カテゴリー", - "xpack.infra.logs.logEntryActionsDetailsButton": "詳細を表示", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "ML で分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "ML アプリでこのカテゴリーを分析します。", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "カテゴリー", @@ -18614,7 +18580,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "ロギング統合を追加", "xpack.infra.logs.noDataConfig.solutionName": "Observability", "xpack.infra.logs.pluginTitle": "ログ", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "エントリーを読み込み中", "xpack.infra.logs.search.nextButtonLabel": "次へ", "xpack.infra.logs.search.previousButtonLabel": "前へ", "xpack.infra.logs.search.searchInLogsAriaLabel": "検索", @@ -18624,10 +18589,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "使用中のインラインログビュー", "xpack.infra.logs.startStreamingButtonLabel": "ライブストリーム", "xpack.infra.logs.stopStreamingButtonLabel": "ストリーム停止", - "xpack.infra.logs.stream.messageColumnTitle": "メッセージ", - "xpack.infra.logs.stream.timestampColumnTitle": "タイムスタンプ", - "xpack.infra.logs.streamingNewEntriesText": "新しいエントリーをストリーム中", - "xpack.infra.logs.streamLive": "ライブストリーム", "xpack.infra.logs.streamPageTitle": "ストリーム", "xpack.infra.logsHeaderAddDataButtonLabel": "データの追加", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "1つ以上のフォームフィールドが無効な状態です。", @@ -18654,8 +18615,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "再試行", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "ログエントリーを検索中…(例:host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "ログフィルターエラー", - "xpack.infra.logStream.kqlErrorTitle": "無効なKQL式", - "xpack.infra.logStream.unknownErrorTitle": "エラーが発生しました", "xpack.infra.logStreamEmbeddable.description": "ライブストリーミングログのテーブルを追加します。", "xpack.infra.logStreamEmbeddable.displayName": "ログストリーム", "xpack.infra.logStreamEmbeddable.title": "ログストリーム", @@ -19282,6 +19241,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "メトリックのオプションまたは値を選択できません。", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自動更新", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "更新中止", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "インデックス{indexName}:{errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "インデックス{indexName}から", + "xpack.logsShared.logFlyout.flyoutTitle": "ログエントリ{logEntryId}の詳細", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "タイムフレームを{amount, number}{amount, plural, other {日}}延長", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "タイムフレームを{amount, number}{amount, plural, other {時間}}延長", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "タイムフレームを{amount, number}{amount, plural, other {ミリ秒}}延長", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "タイムフレームを{amount, number}{amount, plural, other {分}}延長", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "タイムフレームを{amount, number}{amount, plural, other {月}}延長", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "タイムフレームを{amount, number}{amount, plural, other {秒}}延長", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "タイムフレームを{amount, number}{amount, plural, other {週}}延長", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "タイムフレームを{amount, number}{amount, plural, other {年}}延長", + "xpack.logsShared.logs.lastUpdate": "最終更新:{timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "{timestamp}以降のエントリーを表示中", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "{timestamp}までのエントリーを表示中", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "リクエストが中断されましたか。", + "xpack.logsShared.dataSearch.cancelButtonLabel": "リクエストのキャンセル", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "再試行", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "コンテキストで表示", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "APMで表示", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "調査", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "行のアクションを表示", + "xpack.logsShared.logFlyout.fieldColumnLabel": "フィールド", + "xpack.logsShared.logFlyout.filterAriaLabel": "フィルター", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "ログエントリの検索中のエラー", + "xpack.logsShared.logFlyout.loadingMessage": "シャードのログエントリを検索しています", + "xpack.logsShared.logFlyout.setFilterTooltip": "フィルターでイベントを表示", + "xpack.logsShared.logFlyout.valueColumnLabel": "値", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "新規データを確認", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "フィルターを調整してみてください。", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "表示するログメッセージがありません。", + "xpack.logsShared.logs.jumpToTailText": "最も新しいエントリーに移動", + "xpack.logsShared.logs.loadingNewEntriesText": "新しいエントリーを読み込み中", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "詳細を表示", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "エントリーを読み込み中", + "xpack.logsShared.logs.stream.messageColumnTitle": "メッセージ", + "xpack.logsShared.logs.stream.timestampColumnTitle": "タイムスタンプ", + "xpack.logsShared.logs.streamingNewEntriesText": "新しいエントリーをストリーム中", + "xpack.logsShared.logs.streamLive": "ライブストリーム", + "xpack.logsShared.logStream.kqlErrorTitle": "無効なKQL式", + "xpack.logsShared.logStream.unknownErrorTitle": "エラーが発生しました", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "インジェストパイプラインを使用するには、{privilegesCount, plural, other {これらのクラスター権限}}が必要です:{missingPrivileges}。", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "{name}を読み込めません。", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9c38c99996e8f4..90059adb4de1fa 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18116,7 +18116,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "没有索引匹配模式 {index}", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "匹配 {index} 的索引至少有一个缺少必需字段 {field}。", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "匹配 {index} 的索引至少有一个具有称作 {field} 且类型不正确的字段。", - "xpack.infra.dataSearch.shardFailureErrorMessage": "索引 {indexName}:{errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "调整索引以使用“{field}”标识 Docker 容器", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "配置“xpack.infra.sources.default.fields.{fieldKey}”已过时,将在 8.0.0 中移除。", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "“{fieldKey}”已过时。", @@ -18137,8 +18136,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} 不存在。", "xpack.infra.linkTo.hostWithIp.error": "未找到 IP 地址为“{hostIp}”的主机。", "xpack.infra.linkTo.hostWithIp.loading": "正在加载 IP 地址为“{hostIp}”的主机。", - "xpack.infra.logFlyout.flyoutSubTitle": "从索引 {indexName}", - "xpack.infra.logFlyout.flyoutTitle": "日志条目 {logEntryId} 的详细信息", "xpack.infra.logs.alertDetails.chart.chartTitle": "{criteria} 的日志", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "设置“分组依据”时,强烈建议将“{comparator}”比较符用于阈值。这会使性能有较大提升。", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "对于 {groupName},过去 {duration}中有 {actualCount, plural, other {{actualCount} 个日志条目}}。{comparator} {expectedCount} 时告警。", @@ -18156,22 +18153,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "查看 {machineLearningAppLink}以了解更多信息。", "xpack.infra.logs.common.invalidStateMessage": "无法处理状态 {stateValue}。", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {小} medium {中} large {大} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "将时间范围延伸 {amount, number} {amount, plural, other {天}}", - "xpack.infra.logs.extendTimeframeByHoursButton": "将时间范围延伸 {amount, number} {amount, plural, other {小时}}", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {毫秒}}", - "xpack.infra.logs.extendTimeframeByMinutesButton": "将时间范围延伸 {amount, number} {amount, plural, other {分钟}}", - "xpack.infra.logs.extendTimeframeByMonthsButton": "将时间范围延伸 {amount, number} 个{amount, plural, other {月}}", - "xpack.infra.logs.extendTimeframeBySecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {秒}}", - "xpack.infra.logs.extendTimeframeByWeeksButton": "将时间范围延伸 {amount, number} {amount, plural, other {周}}", - "xpack.infra.logs.extendTimeframeByYearsButton": "将时间范围延伸 {amount, number} {amount, plural, other {年}}", - "xpack.infra.logs.lastUpdate": "上次更新时间 {timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "每个分析文档的类别比率非常高,达到 {categoriesDocumentRatio, number}。", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "不会为 {deadCategoriesRatio, number, percent} 的类别分配新消息,因为较为笼统的类别遮蔽了它们。", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "仅很少的时候为 {rareCategoriesRatio, number, percent} 的类别分配消息。", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, other {另 # 个分段}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {# 个高亮条目}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", - "xpack.infra.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "显示的日志来自容器 {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "显示的日志来自文件 {file} 和主机 {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField} 字段必须是文本字段。", @@ -18282,9 +18268,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "没有足够的数据", "xpack.infra.common.tabBetaBadgeLabel": "公测版", "xpack.infra.configureSourceActionLabel": "更改源配置", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "请求已中止。", - "xpack.infra.dataSearch.cancelButtonLabel": "取消请求", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "重试", "xpack.infra.deprecations.containerIdFieldName": "容器 ID", "xpack.infra.deprecations.containerIdFieldTitle": "源配置字段“容器 ID”已过时。", "xpack.infra.deprecations.hostnameFieldName": "主机名", @@ -18438,18 +18421,7 @@ "xpack.infra.legendControls.stepsLabel": "颜色个数", "xpack.infra.legendControls.switchLabel": "自动计算范围", "xpack.infra.legnedControls.boundRangeError": "最小值必须小于最大值", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "在上下文中查看", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "查看日志条目的操作", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", - "xpack.infra.logEntryActionsMenu.buttonLabel": "调查", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "在Uptime 中查看状态", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "查看适用于以下行的操作:", - "xpack.infra.logFlyout.fieldColumnLabel": "字段", - "xpack.infra.logFlyout.filterAriaLabel": "筛选", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "搜索日志条目时出错", - "xpack.infra.logFlyout.loadingMessage": "正在分片中搜索日志条目", - "xpack.infra.logFlyout.setFilterTooltip": "使用筛选查看事件", - "xpack.infra.logFlyout.valueColumnLabel": "值", "xpack.infra.logs.alertDetails.chart.ratioTitle": "查询 A 到查询 B 的比率", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "已启动告警", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "已触发告警", @@ -18568,9 +18540,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "换行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "文本大小", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "长行换行", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "检查新数据", - "xpack.infra.logs.emptyView.noLogMessageDescription": "尝试调整您的筛选。", - "xpack.infra.logs.emptyView.noLogMessageTitle": "没有可显示的日志消息。", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "清除要突出显示的词", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "跳转到下一高亮条目", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "跳转到上一高亮条目", @@ -18580,10 +18549,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "类别", "xpack.infra.logs.index.settingsTabTitle": "设置", "xpack.infra.logs.index.streamTabTitle": "流式传输", - "xpack.infra.logs.jumpToTailText": "跳到最近的条目", - "xpack.infra.logs.loadingNewEntriesText": "正在加载新条目", "xpack.infra.logs.logCategoriesTitle": "类别", - "xpack.infra.logs.logEntryActionsDetailsButton": "查看详情", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "在 ML 中分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "在 ML 应用中分析此类别。", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "类别", @@ -18614,7 +18580,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "添加日志记录集成", "xpack.infra.logs.noDataConfig.solutionName": "Observability", "xpack.infra.logs.pluginTitle": "日志", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "正在加载条目", "xpack.infra.logs.search.nextButtonLabel": "下一页", "xpack.infra.logs.search.previousButtonLabel": "上一页", "xpack.infra.logs.search.searchInLogsAriaLabel": "搜索", @@ -18624,10 +18589,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "正使用内联日志视图", "xpack.infra.logs.startStreamingButtonLabel": "实时流式传输", "xpack.infra.logs.stopStreamingButtonLabel": "停止流式传输", - "xpack.infra.logs.stream.messageColumnTitle": "消息", - "xpack.infra.logs.stream.timestampColumnTitle": "时间戳", - "xpack.infra.logs.streamingNewEntriesText": "正在流式传输新条目", - "xpack.infra.logs.streamLive": "实时流式传输", "xpack.infra.logs.streamPageTitle": "流式传输", "xpack.infra.logsHeaderAddDataButtonLabel": "添加数据", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "至少一个表单字段处于无效状态。", @@ -18654,8 +18615,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "重试", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "搜索日志条目……(例如 host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "日志筛选错误", - "xpack.infra.logStream.kqlErrorTitle": "KQL 表达式无效", - "xpack.infra.logStream.unknownErrorTitle": "发生错误", "xpack.infra.logStreamEmbeddable.description": "添加实时流式传输日志的表。", "xpack.infra.logStreamEmbeddable.displayName": "日志流", "xpack.infra.logStreamEmbeddable.title": "日志流", @@ -19282,6 +19241,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "无法选择指标选项或指标值。", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自动刷新", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "停止刷新", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "索引 {indexName}:{errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "从索引 {indexName}", + "xpack.logsShared.logFlyout.flyoutTitle": "日志条目 {logEntryId} 的详细信息", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "将时间范围延伸 {amount, number} {amount, plural, other {天}}", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "将时间范围延伸 {amount, number} {amount, plural, other {小时}}", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {毫秒}}", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "将时间范围延伸 {amount, number} {amount, plural, other {分钟}}", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "将时间范围延伸 {amount, number} 个{amount, plural, other {月}}", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {秒}}", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "将时间范围延伸 {amount, number} {amount, plural, other {周}}", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "将时间范围延伸 {amount, number} {amount, plural, other {年}}", + "xpack.logsShared.logs.lastUpdate": "上次更新时间 {timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "请求已中止。", + "xpack.logsShared.dataSearch.cancelButtonLabel": "取消请求", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "重试", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "在上下文中查看", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "调查", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "在Uptime 中查看状态", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "查看适用于以下行的操作:", + "xpack.logsShared.logFlyout.fieldColumnLabel": "字段", + "xpack.logsShared.logFlyout.filterAriaLabel": "筛选", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "搜索日志条目时出错", + "xpack.logsShared.logFlyout.loadingMessage": "正在分片中搜索日志条目", + "xpack.logsShared.logFlyout.setFilterTooltip": "使用筛选查看事件", + "xpack.logsShared.logFlyout.valueColumnLabel": "值", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "检查新数据", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "尝试调整您的筛选。", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "没有可显示的日志消息。", + "xpack.logsShared.logs.jumpToTailText": "跳到最近的条目", + "xpack.logsShared.logs.loadingNewEntriesText": "正在加载新条目", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "查看详情", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "正在加载条目", + "xpack.logsShared.logs.stream.messageColumnTitle": "消息", + "xpack.logsShared.logs.stream.timestampColumnTitle": "时间戳", + "xpack.logsShared.logs.streamingNewEntriesText": "正在流式传输新条目", + "xpack.logsShared.logs.streamLive": "实时流式传输", + "xpack.logsShared.logStream.kqlErrorTitle": "KQL 表达式无效", + "xpack.logsShared.logStream.unknownErrorTitle": "发生错误", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "要使用采集管道,您必须具有{privilegesCount, plural, other {以下集群权限}}:{missingPrivileges}。", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "无法加载 {name}。", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/upgrade_assistant/kibana.jsonc b/x-pack/plugins/upgrade_assistant/kibana.jsonc index 3f04775f4ca10c..ff3584ef714bf1 100644 --- a/x-pack/plugins/upgrade_assistant/kibana.jsonc +++ b/x-pack/plugins/upgrade_assistant/kibana.jsonc @@ -21,7 +21,8 @@ "usageCollection", "cloud", "security", - "infra" + "infra", + "logsShared" ], "requiredBundles": [ "esUiShared", diff --git a/x-pack/plugins/upgrade_assistant/server/plugin.ts b/x-pack/plugins/upgrade_assistant/server/plugin.ts index f77a5eabe1bda1..6dfb65be85d7b8 100644 --- a/x-pack/plugins/upgrade_assistant/server/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/server/plugin.ts @@ -16,7 +16,7 @@ import { SavedObjectsServiceStart, } from '@kbn/core/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; @@ -43,7 +43,7 @@ interface PluginsSetup { usageCollection: UsageCollectionSetup; licensing: LicensingPluginSetup; features: FeaturesPluginSetup; - infra: InfraPluginSetup; + logsShared: LogsSharedPluginSetup; security?: SecurityPluginSetup; } @@ -83,7 +83,7 @@ export class UpgradeAssistantServerPlugin implements Plugin { setup( { http, getStartServices, savedObjects }: CoreSetup, - { usageCollection, features, licensing, infra, security }: PluginsSetup + { usageCollection, features, licensing, logsShared, security }: PluginsSetup ) { this.licensing = licensing; @@ -105,7 +105,7 @@ export class UpgradeAssistantServerPlugin implements Plugin { // We need to initialize the deprecation logs plugin so that we can // navigate from this app to the observability app using a source_id. - infra?.logViews.defineInternalLogView(DEPRECATION_LOGS_SOURCE_ID, { + logsShared?.logViews.defineInternalLogView(DEPRECATION_LOGS_SOURCE_ID, { name: 'deprecationLogs', description: 'deprecation logs', logIndices: { diff --git a/x-pack/plugins/upgrade_assistant/tsconfig.json b/x-pack/plugins/upgrade_assistant/tsconfig.json index c9d8201c1607a7..59d562c03c87d3 100644 --- a/x-pack/plugins/upgrade_assistant/tsconfig.json +++ b/x-pack/plugins/upgrade_assistant/tsconfig.json @@ -20,7 +20,6 @@ "@kbn/features-plugin", "@kbn/licensing-plugin", "@kbn/es-ui-shared-plugin", - "@kbn/infra-plugin", "@kbn/cloud-plugin", "@kbn/test-jest-helpers", "@kbn/share-plugin", @@ -37,6 +36,7 @@ "@kbn/core-elasticsearch-client-server-mocks", "@kbn/utility-types", "@kbn/shared-ux-router", + "@kbn/logs-shared-plugin", ], "exclude": [ "target/**/*", diff --git a/x-pack/test/api_integration/apis/logs_ui/log_views.ts b/x-pack/test/api_integration/apis/logs_ui/log_views.ts index 646d9fd3bb5e34..07b2ffdbf6832d 100644 --- a/x-pack/test/api_integration/apis/logs_ui/log_views.ts +++ b/x-pack/test/api_integration/apis/logs_ui/log_views.ts @@ -6,14 +6,14 @@ */ import expect from '@kbn/expect'; -import { defaultLogViewId, LogViewAttributes } from '@kbn/infra-plugin/common/log_views'; +import { defaultLogViewId, LogViewAttributes } from '@kbn/logs-shared-plugin/common/log_views'; import { defaultSourceConfiguration, infraSourceConfigurationSavedObjectName, mergeSourceConfiguration, } from '@kbn/infra-plugin/server/lib/sources'; import { extractSavedObjectReferences } from '@kbn/infra-plugin/server/lib/sources/saved_object_references'; -import { logViewSavedObjectName } from '@kbn/infra-plugin/server/saved_objects/log_view'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts index 6efb17e1571cc8..fd87af88ebc8b8 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts @@ -17,7 +17,7 @@ import { LOG_ENTRIES_HIGHLIGHTS_PATH, logEntriesHighlightsRequestRT, logEntriesHighlightsResponseRT, -} from '@kbn/infra-plugin/common/http_api'; +} from '@kbn/logs-shared-plugin/common'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts index 9c7c5548fcdbcc..4ae51422ea688f 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts @@ -19,7 +19,7 @@ import { LOG_ENTRIES_SUMMARY_PATH, logEntriesSummaryRequestRT, logEntriesSummaryResponseRT, -} from '@kbn/infra-plugin/common/http_api'; +} from '@kbn/logs-shared-plugin/common'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/common/services/infra_log_views.ts b/x-pack/test/common/services/infra_log_views.ts index a6a87da67e1aa1..3862295e997adf 100644 --- a/x-pack/test/common/services/infra_log_views.ts +++ b/x-pack/test/common/services/infra_log_views.ts @@ -10,8 +10,8 @@ import { PutLogViewRequestPayload, putLogViewRequestPayloadRT, putLogViewResponsePayloadRT, -} from '@kbn/infra-plugin/common/http_api'; -import { getLogViewUrl } from '@kbn/infra-plugin/common/http_api/log_views'; +} from '@kbn/logs-shared-plugin/common/http_api'; +import { getLogViewUrl } from '@kbn/logs-shared-plugin/common/http_api/log_views'; import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types'; import { FtrProviderContext } from '../ftr_provider_context'; diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 03496116b2072f..4a2aff8ae77390 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -130,6 +130,7 @@ "@kbn/slo-schema", "@kbn/lens-plugin", "@kbn/notifications-plugin", + "@kbn/logs-shared-plugin", "@kbn/telemetry-tools", "@kbn/profiling-plugin", "@kbn/observability-onboarding-plugin" diff --git a/yarn.lock b/yarn.lock index dec901f6e1b294..3037b73b85d8ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4618,6 +4618,10 @@ version "0.0.0" uid "" +"@kbn/logs-shared-plugin@link:x-pack/plugins/logs_shared": + version "0.0.0" + uid "" + "@kbn/logstash-plugin@link:x-pack/plugins/logstash": version "0.0.0" uid "" From e654c8e936853e1952b2f46b862fd34911618d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Wed, 5 Jul 2023 10:38:55 +0200 Subject: [PATCH 72/98] [Enterprise Search]Add 404 error handling for mappings and documents endpoints (#161203) ## Summary Add 404 handler for the Document and mappings endpoints. They were default handlers before and returning 502. Error message is much more meaningful at the moment. ![Screenshot 2023-07-04 at 18 16 53](https://github.com/elastic/kibana/assets/1410658/f595391b-2889-4370-907f-7e5c0d331f2c) ![Screenshot 2023-07-04 at 18 17 01](https://github.com/elastic/kibana/assets/1410658/018d34d1-273a-4d85-9f5a-78bbf15cf526) ### 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 --- .../enterprise_search/common/constants.ts | 2 + .../components/search_index/documents.tsx | 4 +- .../search_index/index_mappings.tsx | 4 +- .../plugins/enterprise_search/server/index.ts | 1 - .../server/lib/connectors/start_sync.test.ts | 8 ++-- .../server/lib/connectors/start_sync.ts | 11 +++-- .../indices/delete_access_control_index.ts | 2 +- .../routes/enterprise_search/mapping.ts | 26 ++++++++--- .../server/routes/enterprise_search/search.ts | 43 +++++++++++++------ 9 files changed, 67 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index c2af49bb9e9519..88290c2ed48312 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -210,3 +210,5 @@ export const DEFAULT_PRODUCT_FEATURES: ProductFeatures = { hasNativeConnectors: true, hasWebCrawler: true, }; + +export const CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX = '.search-acl-filter-'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx index 8cf25e16426a86..ea1b1aaecd23f6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx @@ -20,6 +20,8 @@ import { import { i18n } from '@kbn/i18n'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../../../common/constants'; + import { KibanaLogic } from '../../../shared/kibana'; import { @@ -44,7 +46,7 @@ export const SearchIndexDocuments: React.FC = () => { const indexToShow = selectedIndexType === 'content-index' ? indexName - : indexName.replace('search-', '.search-acl-filter-'); + : indexName.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX); const shouldShowAccessControlSwitcher = hasDocumentLevelSecurityFeature && productFeatures.hasDocumentLevelSecurityEnabled; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx index 4bc77672f5f7b0..5ec31986b2fe40 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx @@ -25,6 +25,8 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../../../common/constants'; + import { docLinks } from '../../../shared/doc_links'; import { KibanaLogic } from '../../../shared/kibana'; @@ -51,7 +53,7 @@ export const SearchIndexIndexMappings: React.FC = () => { const indexToShow = selectedIndexType === 'content-index' ? indexName - : indexName.replace('search-', '.search-acl-filter-'); + : indexName.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX); const shouldShowAccessControlSwitch = hasDocumentLevelSecurityFeature && productFeatures.hasDocumentLevelSecurityEnabled; diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts index 704595b708c5ea..29186418143417 100644 --- a/x-pack/plugins/enterprise_search/server/index.ts +++ b/x-pack/plugins/enterprise_search/server/index.ts @@ -53,4 +53,3 @@ export const CURRENT_CONNECTORS_INDEX = '.elastic-connectors-v1'; export const CONNECTORS_JOBS_INDEX = '.elastic-connectors-sync-jobs'; export const CONNECTORS_VERSION = 1; export const CRAWLERS_INDEX = '.ent-search-actastic-crawler2_configurations_v2'; -export const CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX = '.search-acl-filter-'; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts index ca7ae9fc76a668..4e35acd1434b46 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts @@ -7,11 +7,9 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { - CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, - CONNECTORS_INDEX, - CONNECTORS_JOBS_INDEX, -} from '../..'; +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../common/constants'; + import { SyncJobType, SyncStatus, TriggerMethod } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts index e4ef3288819f69..a3b2164c467a1f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts @@ -7,14 +7,13 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { - CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, - CONNECTORS_INDEX, - CONNECTORS_JOBS_INDEX, -} from '../..'; +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; import { isConfigEntry } from '../../../common/connectors/is_category_entry'; -import { ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE } from '../../../common/constants'; +import { + CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, + ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE, +} from '../../../common/constants'; import { ConnectorConfiguration, diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts index 2df773b1af30e0..3d185c9fde6f78 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts @@ -8,7 +8,7 @@ import { isIndexNotFoundException } from '@kbn/core-saved-objects-migration-server-internal'; import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../..'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../common/constants'; export const deleteAccessControlIndex = async (client: IScopedClusterClient, index: string) => { try { diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts index b963157694acf1..0ce48c33a9d38a 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts @@ -7,9 +7,13 @@ import { schema } from '@kbn/config-schema'; +import { ErrorCode } from '../../../common/types/error_codes'; + import { fetchMapping } from '../../lib/fetch_mapping'; import { RouteDependencies } from '../../plugin'; +import { createError } from '../../utils/create_error'; import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; export function registerMappingRoute({ router, log }: RouteDependencies) { router.get( @@ -24,12 +28,24 @@ export function registerMappingRoute({ router, log }: RouteDependencies) { elasticsearchErrorHandler(log, async (context, request, response) => { const { client } = (await context.core).elasticsearch; - const mapping = await fetchMapping(client, request.params.index_name); + try { + const mapping = await fetchMapping(client, request.params.index_name); - return response.ok({ - body: mapping, - headers: { 'content-type': 'application/json' }, - }); + return response.ok({ + body: mapping, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not found index', + response, + statusCode: 404, + }); + } + throw error; + } }) ); } diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts index 3ea14a2013a59f..40158204e3ea39 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts @@ -10,10 +10,13 @@ import { SearchResponseBody } from '@elastic/elasticsearch/lib/api/types'; import { schema } from '@kbn/config-schema'; import { ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } from '../../../common/constants'; +import { ErrorCode } from '../../../common/types/error_codes'; import { fetchSearchResults } from '../../lib/fetch_search_results'; import { RouteDependencies } from '../../plugin'; +import { createError } from '../../utils/create_error'; import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; const calculateMeta = (searchResults: SearchResponseBody, page: number, size: number) => { let totalResults = 0; @@ -64,21 +67,33 @@ export function registerSearchRoute({ router, log }: RouteDependencies) { const { client } = (await context.core).elasticsearch; const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query; const from = page * size; - const searchResults: SearchResponseBody = await fetchSearchResults( - client, - indexName, - searchQuery, - from, - size - ); + try { + const searchResults: SearchResponseBody = await fetchSearchResults( + client, + indexName, + searchQuery, + from, + size + ); - return response.ok({ - body: { - meta: calculateMeta(searchResults, page, size), - results: searchResults, - }, - headers: { 'content-type': 'application/json' }, - }); + return response.ok({ + body: { + meta: calculateMeta(searchResults, page, size), + results: searchResults, + }, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not found index', + response, + statusCode: 404, + }); + } + throw error; + } }) ); } From 77285193045db36453f367d61552638218fde013 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 5 Jul 2023 10:53:02 +0200 Subject: [PATCH 73/98] [ML] Fix Anomaly Explorer URL for alerting context with non-default space (#160899) ## Summary Fixes #160762 ### 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/server/lib/alerts/alerting_service.ts | 16 +++++++++++++--- .../register_anomaly_detection_alert_type.ts | 4 ++-- .../ml_rule_types/anomaly_detection/alert.ts | 7 ++++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts index 68b3ed34915035..31794a901416f8 100644 --- a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts @@ -23,6 +23,7 @@ import { type MlAnomalyResultType, ML_ANOMALY_RESULT_TYPE, } from '@kbn/ml-anomaly-utils'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { MlClient } from '../ml_client'; import { MlAnomalyDetectionAlertParams, @@ -78,6 +79,7 @@ export function buildExplorerUrl( jobIds: string[], timeRange: { from: string; to: string; mode?: string }, type: MlAnomalyResultType, + spaceId: string, r?: AlertExecutionResult ): string { const isInfluencerResult = type === ML_ANOMALY_RESULT_TYPE.INFLUENCER; @@ -145,7 +147,11 @@ export function buildExplorerUrl( }, }, }; - return `/app/ml/explorer/?_g=${encodeURIComponent( + + const spacePathComponent: string = + !spaceId || spaceId === DEFAULT_SPACE_ID ? '' : `/s/${spaceId}`; + + return `${spacePathComponent}/app/ml/explorer/?_g=${encodeURIComponent( rison.encode(globalState) )}&_a=${encodeURIComponent(rison.encode(appState))}`; } @@ -765,9 +771,11 @@ export function alertingServiceProvider( * Return the result of an alert condition execution. * * @param params - Alert params + * @param spaceId */ execute: async ( - params: MlAnomalyDetectionAlertParams + params: MlAnomalyDetectionAlertParams, + spaceId: string ): Promise< { context: AnomalyDetectionAlertContext; name: string; isHealthy: boolean } | undefined > => { @@ -784,6 +792,7 @@ export function alertingServiceProvider( result.jobIds, { from: result.bucketRange.start, to: result.bucketRange.end }, params.resultType, + spaceId, result ); @@ -806,7 +815,8 @@ export function alertingServiceProvider( to: 'now', mode: 'relative', }, - queryParams.resultType + queryParams.resultType, + spaceId ), jobIds: queryParams.jobIds, message: i18n.translate( diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 7cee5917f6567e..d68e40f44b4a6e 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -137,13 +137,13 @@ export function registerAnomalyDetectionAlertType({ minimumLicenseRequired: MINIMUM_FULL_LICENSE, isExportable: true, doesSetRecoveryContext: true, - async executor({ services, params }) { + async executor({ services, params, spaceId }) { const fakeRequest = {} as KibanaRequest; const { execute } = mlSharedServices.alertingServiceProvider( services.savedObjectsClient, fakeRequest ); - const executionResult = await execute(params); + const executionResult = await execute(params, spaceId); if (executionResult && !executionResult.isHealthy) { const alertInstanceName = executionResult.name; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts index 1d69200a277d42..9bd615b99e53ba 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts @@ -133,12 +133,16 @@ export default function alertTests({ getService }: FtrProviderContext) { const docs = await waitForDocs(1); for (const doc of docs) { - const { name, message } = doc._source.params; + const { name, message, anomalyExplorerUrl } = doc._source.params; expect(name).to.be('Test AD job'); expect(message).to.be( 'Alerts are raised based on real-time scores. Remember that scores may be adjusted over time as data continues to be analyzed.' ); + // check only part of the URL as time bounds vary based on the anomaly + expect(anomalyExplorerUrl).to.contain( + '/s/space1/app/ml/explorer/?_g=(ml%3A(jobIds%3A!(rt-anomaly-mean-value))' + ); } }); @@ -166,6 +170,7 @@ export default function alertTests({ getService }: FtrProviderContext) { params: { name: '{{{alertName}}}', message: '{{{context.message}}}', + anomalyExplorerUrl: '{{{context.anomalyExplorerUrl}}}', }, }, ], From 0b13a843f86097ed38086791d846754edd17b25a Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 5 Jul 2023 11:23:46 +0200 Subject: [PATCH 74/98] Update publicBaseUrl warning id (#161204) Related to #161091 ## Summary I learned that when we update a default message, we should manually remove outdated translations. In this PR, I updated the ID and removed outdated translations. I will not backport this PR since the translation for the previous version is already started so I will keep the previous translation for v8.9. Please let me know if there is an issue with this approach. --- x-pack/plugins/translations/translations/fr-FR.json | 1 - x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - .../public/application/lib/validate_params_for_warnings.ts | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 29c1982ae0d3b1..9ab100fe729a5d 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -37760,7 +37760,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "Ajouter un connecteur", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "Les intervalles d'action personnalisés ne peuvent pas être plus courts que l'intervalle de vérification de la règle", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "Résumé des alertes", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "server.publicBaseUrl n'est pas défini. Les actions utiliseront des URL relatives.", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "Compatibilité :", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "Sélectionner un connecteur", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "Création de \"{connectorName}\" effectuée", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2b610e8af95c6f..c79922135bd8ed 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -37734,7 +37734,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "コネクターの追加", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "カスタムアクション間隔をルールのチェック間隔よりも短くすることはできません", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "アラートの概要", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "server.publicBaseUrlが設定されていません。アクションは相対URLを使用します。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "互換性:", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "コネクターを選択", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "「{connectorName}」を作成しました", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 90059adb4de1fa..163f3c66e14482 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -37728,7 +37728,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "添加连接器", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "定制操作时间间隔不能短于规则的检查时间间隔", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "告警的摘要", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "未设置 server.publicBaseUrl。操作将使用相对 URL。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "兼容性:", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "选择连接器", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "已创建“{connectorName}”", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts index 447a751f32a3c8..e0f552f6bb0f78 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts @@ -11,7 +11,7 @@ import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; import Mustache from 'mustache'; const publicUrlWarning = i18n.translate( - 'xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl', + 'xpack.triggersActionsUI.sections.actionTypeForm.warning.publicBaseUrl', { defaultMessage: 'server.publicBaseUrl is not set. Generated URLs will be either relative or empty.', From 38b487a879ba12a2a6b37930fd05d60aa3c7ae10 Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Wed, 5 Jul 2023 11:27:54 +0200 Subject: [PATCH 75/98] [Fleet] Fix permissions in integrations Assets page (#161233) Fixes https://github.com/elastic/kibana/issues/161058 ## Summary Fix permissions for Integrations assets tab. A user with role "Fleet All - Integration Read" wasn't able to visualize the assets tab. ### Test - Create a user with "Fleet All - Integration Read" as shown in this video: https://github.com/elastic/kibana/assets/16084106/a13c6ddd-a3d1-4e15-9c9d-9d56e1dbb0f0 - Log in with this new user - Navigate to any installed integration, then to the Assets tab - Verify that the assets are shown as usual (no warnings are shown) Screenshot 2023-07-05 at 10 22 36 --- .../integrations/sections/epm/screens/detail/assets/assets.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx index b9a023bef1ef79..2f6e20f097601f 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx @@ -46,7 +46,7 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { const { spaces } = useStartServices(); const customAssetsExtension = useUIExtension(packageInfo.name, 'package-detail-assets'); - const canReadPackageSettings = useAuthz().integrations.readPackageSettings; + const canReadPackageSettings = useAuthz().integrations.readPackageInfo; const { getPath } = useLink(); const getPackageInstallStatus = useGetPackageInstallStatus(); From 3d146f3eff411ecd12dc7c1f561bd74e8b60a02d Mon Sep 17 00:00:00 2001 From: Andrew Gizas Date: Wed, 5 Jul 2023 12:41:24 +0300 Subject: [PATCH 76/98] fixing the path of manifets for hints autodiscover (#161075) ## Summary Bug: Fixing the path for downloading hint templates for elastic standalone agent. See that the path had changed to https://github.com/elastic/elastic-agent/tree/main/deploy/kubernetes/elastic-agent-standalone/templates.d --- x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts index 63691b878eaa71..f01f6d71df89dd 100644 --- a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts +++ b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts @@ -42,7 +42,7 @@ spec: # - -c # - >- # mkdir -p /etc/elastic-agent/inputs.d && - # wget -O - https://github.com/elastic/elastic-agent/archive/main.tar.gz | tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-main/deploy/kubernetes/elastic-agent/templates.d" + # wget -O - https://github.com/elastic/elastic-agent/archive/main.tar.gz | tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-main/deploy/kubernetes/elastic-agent-standalone/templates.d" # volumeMounts: # - name: external-inputs # mountPath: /etc/elastic-agent/inputs.d From 6a84ea186b664b55c19a9465b2ea80ddd29c6ffd Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 5 Jul 2023 11:55:38 +0200 Subject: [PATCH 77/98] [Synthetics] Remove TLS alert option for ICMP monitor (#161173) --- .../monitor_add_edit/form/field_config.tsx | 21 ++++++++++--------- .../monitor_add_edit/form/form_config.tsx | 1 - .../tls_rule/tls_rule_executor.test.ts | 3 ++- .../alert_rules/tls_rule/tls_rule_executor.ts | 5 +++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx index 56987e86b9c83b..133f509c4b0ec5 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx @@ -507,9 +507,13 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({ controlled: true, props: ({ setValue, field }): EuiSwitchProps => ({ id: 'syntheticsMonitorConfigIsAlertEnabled', - label: i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.label', { - defaultMessage: 'Enable status alerts', - }), + label: field?.value + ? i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.label', { + defaultMessage: 'Disable status alerts on this monitor', + }) + : i18n.translate('xpack.synthetics.monitorConfig.disabledAlerting.label', { + defaultMessage: 'Enable status alerts on this monitor', + }), checked: field?.value || false, onChange: (event) => { setValue(AlertConfigKey.STATUS_ENABLED, !!event.target.checked); @@ -522,18 +526,15 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({ [AlertConfigKey.TLS_ENABLED]: { fieldKey: AlertConfigKey.TLS_ENABLED, component: Switch, - label: i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.tls.label', { - defaultMessage: 'Enable TLS alerts', - }), controlled: true, - props: ({ isEdit, setValue, field }): EuiSwitchProps => ({ + props: ({ setValue, field }): EuiSwitchProps => ({ id: 'syntheticsMonitorConfigIsTlsAlertEnabled', - label: isEdit + label: field?.value ? i18n.translate('xpack.synthetics.monitorConfig.edit.alertTlsEnabled.label', { - defaultMessage: 'Disabling will stop tls alerting on this monitor.', + defaultMessage: 'Disable TLS alerts on this monitor.', }) : i18n.translate('xpack.synthetics.monitorConfig.create.alertTlsEnabled.label', { - defaultMessage: 'Enable tls alerts on this monitor.', + defaultMessage: 'Enable TLS alerts on this monitor.', }), checked: field?.value || false, onChange: (event) => { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx index ffd8f1c3cfccd0..8e44f9727a5c3a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx @@ -287,7 +287,6 @@ export const FORM_CONFIG = (readOnly: boolean): FieldConfig => ({ FIELD(readOnly)[ConfigKey.TIMEOUT], FIELD(readOnly)[ConfigKey.ENABLED], FIELD(readOnly)[AlertConfigKey.STATUS_ENABLED], - FIELD(readOnly)[AlertConfigKey.TLS_ENABLED], ], advanced: [DEFAULT_DATA_OPTIONS(readOnly), ICMP_ADVANCED(readOnly).requestConfig], }, diff --git a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts index ac89f6f6bbbba6..eec9a8be02fd78 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts @@ -75,7 +75,8 @@ describe('tlsRuleExecutor', () => { expect(certs).toEqual([]); expect(spy).toHaveBeenCalledWith({ - filter: 'synthetics-monitor.attributes.alert.tls.enabled: true', + filter: + 'synthetics-monitor.attributes.alert.tls.enabled: true and (synthetics-monitor.attributes.type: http or synthetics-monitor.attributes.type: tcp)', soClient, }); }); diff --git a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts index ad5f6ad2b88d04..71cfd7453c12f8 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts @@ -21,7 +21,7 @@ import { getAllMonitors, processMonitors, } from '../../saved_objects/synthetics_monitor/get_all_monitors'; -import { CertResult, EncryptedSyntheticsMonitor } from '../../../common/runtime_types'; +import { CertResult, ConfigKey, EncryptedSyntheticsMonitor } from '../../../common/runtime_types'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; import { monitorAttributes } from '../../../common/types/saved_objects'; import { AlertConfigKey } from '../../../common/constants/monitor_management'; @@ -55,9 +55,10 @@ export class TLSRuleExecutor { } async getMonitors() { + const HTTP_OR_TCP = `${monitorAttributes}.${ConfigKey.MONITOR_TYPE}: http or ${monitorAttributes}.${ConfigKey.MONITOR_TYPE}: tcp`; this.monitors = await getAllMonitors({ soClient: this.soClient, - filter: `${monitorAttributes}.${AlertConfigKey.TLS_ENABLED}: true`, + filter: `${monitorAttributes}.${AlertConfigKey.TLS_ENABLED}: true and (${HTTP_OR_TCP})`, }); const { From 54dc40ff69f8ca0035cc722594b6cfc1512e499b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 5 Jul 2023 12:10:32 +0200 Subject: [PATCH 78/98] [Synthetics] Overview page fix last refresh value display (#161086) Co-authored-by: Abdul Zahid --- .../plugins/synthetics/common/constants/ui.ts | 21 --------- .../common/components/last_refreshed.tsx | 11 ----- .../synthetics/utils/formatting/format.ts | 38 ---------------- .../utils/monitor_test_result/timestamp.ts | 45 ------------------- .../public/hooks/use_date_format.test.tsx | 25 +++++++++++ .../public/hooks/use_date_format.ts | 11 +++-- 6 files changed, 33 insertions(+), 118 deletions(-) delete mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts diff --git a/x-pack/plugins/synthetics/common/constants/ui.ts b/x-pack/plugins/synthetics/common/constants/ui.ts index d014b8b8ea6ff6..189dd40660ae7b 100644 --- a/x-pack/plugins/synthetics/common/constants/ui.ts +++ b/x-pack/plugins/synthetics/common/constants/ui.ts @@ -67,27 +67,6 @@ export const ML_MODULE_ID = 'uptime_heartbeat'; export const UNNAMED_LOCATION = 'Unnamed-location'; -export const SHORT_TS_LOCALE = 'en-short-locale'; - -export const SHORT_TIMESPAN_LOCALE = { - relativeTime: { - future: 'in %s', - past: '%s ago', - s: '%ds', - ss: '%ss', - m: '%dm', - mm: '%dm', - h: '%dh', - hh: '%dh', - d: '%dd', - dd: '%dd', - M: '%d Mon', - MM: '%d Mon', - y: '%d Yr', - yy: '%d Yr', - }, -}; - export enum CERT_STATUS { OK = 'OK', EXPIRING_SOON = 'EXPIRING_SOON', diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx index 28a4ef1c5b1017..bc086f67c822bd 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx @@ -10,7 +10,6 @@ import moment from 'moment'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useSelector } from 'react-redux'; -import { SHORT_TIMESPAN_LOCALE, SHORT_TS_LOCALE } from '../../../../../../common/constants'; import { useSyntheticsRefreshContext } from '../../../contexts'; import { selectRefreshPaused } from '../../../state'; @@ -41,18 +40,8 @@ export function LastRefreshed() { const isWarning = moment().diff(moment(lastRefreshed), 'minutes') > 1; const isDanger = moment().diff(moment(lastRefreshed), 'minutes') > 5; - const prevLocal: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - const updatedDate = moment(lastRefreshed).from(refresh); - // Need to reset locale so it doesn't effect other parts of the app - moment.locale(prevLocal); - return ( { - if (relative) { - const prevLocale: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - - let shortTimestamp; - if (typeof timeStamp === 'string') { - shortTimestamp = parseTimestamp(timeStamp).fromNow(); - } else { - shortTimestamp = timeStamp.fromNow(); - } - - // Reset it so, it doesn't impact other part of the app - moment.locale(prevLocale); - return shortTimestamp; - } else { - if (moment().diff(timeStamp, 'd') >= 1) { - return timeStamp.format('ll LTS'); - } - return timeStamp.format('LTS'); - } -}; - -export const parseTimestamp = (tsValue: string): Moment => { - let parsed = Date.parse(tsValue); - if (isNaN(parsed)) { - parsed = parseInt(tsValue, 10); - } - return moment(parsed); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts b/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts deleted file mode 100644 index c9c4d022b869da..00000000000000 --- a/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts +++ /dev/null @@ -1,45 +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 moment from 'moment'; -import { SHORT_TIMESPAN_LOCALE, SHORT_TS_LOCALE } from '../../../../../common/constants'; - -export const parseTimestamp = (tsValue: string): moment.Moment => { - let parsed = Date.parse(tsValue); - if (isNaN(parsed)) { - parsed = parseInt(tsValue, 10); - } - return moment(parsed); -}; - -export const getShortTimeStamp = (timeStamp: moment.Moment, relative = false) => { - if (relative) { - const prevLocale: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - - let shortTimestamp; - if (typeof (timeStamp as unknown) === 'string') { - shortTimestamp = parseTimestamp(timeStamp as unknown as string).fromNow(); - } else { - shortTimestamp = timeStamp.fromNow(); - } - - // Reset it so, it doesn't impact other part of the app - moment.locale(prevLocale); - return shortTimestamp; - } else { - if (moment().diff(timeStamp, 'd') >= 1) { - return timeStamp.format('ll LTS'); - } - return timeStamp.format('LTS'); - } -}; diff --git a/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx b/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx index 3ddfe441d38954..42cee2817e8f27 100644 --- a/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx +++ b/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx @@ -6,10 +6,25 @@ */ import { renderHook } from '@testing-library/react-hooks'; +import { i18n } from '@kbn/i18n'; + +jest.mock('@kbn/i18n', () => ({ + i18n: { + getLocale: jest.fn().mockReturnValue(undefined), + }, +})); import { useDateFormat } from './use_date_format'; describe('useDateFormat', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + Object.defineProperty(global.navigator, 'language', { value: 'en-US', writable: true, @@ -26,4 +41,14 @@ describe('useDateFormat', () => { const response = renderHook(() => useDateFormat()); expect(response.result.current('2023-02-01 13:00:00')).toEqual('1 Feb 2023 @ 13:00'); }); + it('prefers Kibana locale if set', () => { + jest.spyOn(i18n, 'getLocale').mockReturnValue('fr-FR'); + + Object.defineProperty(global.navigator, 'language', { + value: 'en-GB', + writable: true, + }); + const response = renderHook(() => useDateFormat()); + expect(response.result.current('2023-02-01 13:00:00')).toEqual('1 févr. 2023 @ 13:00'); + }); }); diff --git a/x-pack/plugins/synthetics/public/hooks/use_date_format.ts b/x-pack/plugins/synthetics/public/hooks/use_date_format.ts index 2fc143af4a87f6..4b402cc2367cd2 100644 --- a/x-pack/plugins/synthetics/public/hooks/use_date_format.ts +++ b/x-pack/plugins/synthetics/public/hooks/use_date_format.ts @@ -7,13 +7,18 @@ import moment from 'moment'; import { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; export function useDateFormat(): (timestamp?: string) => string { - const locale = navigator.language; + const kibanaLocale = i18n.getLocale(); + const clientLocale = navigator.language; useEffect(() => { - moment.locale(locale); - }, [locale]); + const preferredLocale = kibanaLocale ?? clientLocale; + if (moment.locale() !== preferredLocale) { + moment.locale(preferredLocale); + } + }, [kibanaLocale, clientLocale]); return (timestamp?: string) => { if (!timestamp) return ''; From ee6ca657eeadd498f4783331539b102ec619097b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:38:55 +0200 Subject: [PATCH 79/98] [Console] Add logic for query params (#160515) ## Summary Fixes https://github.com/elastic/kibana/issues/160528 Follow up to https://github.com/elastic/kibana/pull/159241 This PR adds logic for query parameters to the new script generating Console autocomplete definitions from ES specification. The logic is explained in details in the [file](https://github.com/elastic/kibana/pull/160515/files#diff-b6853462c38db4e237dbb3cdec9d9f6659aa3fdc5f96a6193f2c4bac1439db43) but here is a short version: - Currently, the autocomplete engine only works with url params of 2 types: boolean (`__flag__`) and a list of options (for example `['all', 'open', 'hidden']`). The script will convert all of the url params from the specification into this format: a boolean or a list. If there are no set options for a parameter, but a default value is known, then it will be converted into a list with 1 option, for example `['random']` so that the autocomplete engine will display it as a single suggestion. We also need to convert any numbers to strings, because they won't be displayed otherwise. - Endpoints in the specification have a property `request` which in turn has 2 properties describing url params: `attachedBehaviours` and `query`. Both object contain an array of `property`'s each describing a url param. `property` is configured with either a built in type (`string`, `number`, `boolean`) or defined type, for example `ExpandWildcards`. By finding the type `ExpandWildcards` in the specification, we can convert this type to a list of options `['open', 'all', 'none', 'hidden']`. ### How to test Similar to https://github.com/elastic/kibana/pull/159241, you need to re-generenate the definitions and see if local changes to definitions files make sense. 1. Checkout the ES specification [repo](https://github.com/elastic/elasticsearch-specification) 2. Run the command `node scripts/generate_console_definitions.js --source --emptyDest` 3. Check the changes in the folder `KIBANA_REPO/src/plugins/console/server/lib/spec_definitions/json/generated` #### Intended changes to the definitions files - Most of endpoints have 4 default url params that previously were not in the definitions files but added to all endpoints in this [file](https://github.com/elastic/kibana/blob/main/src/plugins/console/public/lib/autocomplete/url_params.js). These params are configured in the interface `CommonQueryParameters` in the specification (see this [file](https://github.com/elastic/elasticsearch-specification/blob/main/specification/_spec_utils/behaviors.ts)).
The interface in the specification ```js export interface CommonQueryParameters { error_trace?: boolean filter_path?: string | string[] human?: boolean pretty?: boolean } ``` The converted url params ```json "error_trace": "__flag__", "filter_path": [], "human": "__flag__", "pretty": "__flag__", ```
- Previously existing `url_components` property in the definitions is deleted and this change will be addressed separately. (not sure it is currently working but added a task to the meta issue) - Previously numbers were configured as `0` or `0.0` but that is not currently displayed in suggestions. Instead, the new script converts numbers to strings and if any default value is present, it will be displayed as a suggestion. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../README.md | 11 +- .../src/generate_console_definitions.ts | 98 ++-- .../src/generate_query_params.test.ts | 375 +++++++++++++++ .../src/generate_query_params.ts | 219 +++++++++ .../types/autocomplete_definition_types.ts | 23 + .../src/types/index.ts | 15 + .../src/types/specification_types.ts | 442 ++++++++++++++++++ .../src/utils.ts | 17 + 8 files changed, 1131 insertions(+), 69 deletions(-) create mode 100644 packages/kbn-generate-console-definitions/src/generate_query_params.test.ts create mode 100644 packages/kbn-generate-console-definitions/src/generate_query_params.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/index.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/specification_types.ts create mode 100644 packages/kbn-generate-console-definitions/src/utils.ts diff --git a/packages/kbn-generate-console-definitions/README.md b/packages/kbn-generate-console-definitions/README.md index 71596b6fdf0bc4..75d43fd7c493e7 100644 --- a/packages/kbn-generate-console-definitions/README.md +++ b/packages/kbn-generate-console-definitions/README.md @@ -1,3 +1,10 @@ -# @kbn/generate-console-definitions +# Generate console definitions +This package is a script to generate definitions used in Console to display autocomplete suggestions. The script is +a new implementation of `kbn-spec-to-console` package: The old script uses [JSON specs](https://github.com/elastic/elasticsearch/tree/main/rest-api-spec) from the Elasticsearch repo as the source, whereas this script uses the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification) as the source. + +## Instructions +1. Checkout the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification). +2. Run the command `node scripts/generate_console_definitions.js --source --emptyDest` + This command will use the folder `` as the source and the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) as the destination. Based on the value of the constant, the autocomplete definitions will be generated in the folder `/src/plugins/server/lib/spec_definitions/json/generated`. Using the flag `--emptyDest` will remove any existing files in the destination folder. +3. It's possible to generate the definitions into a different folder. For that pass an option to the command `--dest ` and also update the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) so that the Console server will load the definitions from this folder. -Empty package generated by @kbn/generate diff --git a/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts b/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts index f5bb7cd687c7b5..1d4918f44c6b17 100644 --- a/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts +++ b/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts @@ -9,51 +9,16 @@ import fs from 'fs'; import Path, { join } from 'path'; import { ToolingLog } from '@kbn/tooling-log'; - -interface EndpointRequest { - name: string; - namespace: string; -} - -interface Endpoint { - name: string; - urls: Array<{ - methods: string[]; - path: string; - }>; - docUrl: string; - request: null | EndpointRequest; -} - -interface SchemaType { - name: { - name: string; - namespace: string; - }; -} - -interface Schema { - endpoints: Endpoint[]; - types: SchemaType[]; -} - -interface UrlParams { - [key: string]: number | string; -} - -interface BodyParams { - [key: string]: number | string; -} - -interface Definition { - documentation?: string; - methods: string[]; - patterns: string[]; - url_params?: UrlParams; - data_autocomplete_rules?: BodyParams; -} - -const generateMethods = (endpoint: Endpoint): string[] => { +import { generateQueryParams } from './generate_query_params'; +import type { + AutocompleteBodyParams, + AutocompleteDefinition, + AutocompleteUrlParams, + SpecificationTypes, +} from './types'; +import { findTypeDefinition } from './utils'; + +const generateMethods = (endpoint: SpecificationTypes.Endpoint): string[] => { // this array consists of arrays of strings const methodsArray = endpoint.urls.map((url) => url.methods); // flatten to return array of strings @@ -62,7 +27,7 @@ const generateMethods = (endpoint: Endpoint): string[] => { return [...new Set(flattenMethodsArray)]; }; -const generatePatterns = (endpoint: Endpoint): string[] => { +const generatePatterns = (endpoint: SpecificationTypes.Endpoint): string[] => { return endpoint.urls.map(({ path }) => { let pattern = path; // remove leading / if present @@ -73,42 +38,37 @@ const generatePatterns = (endpoint: Endpoint): string[] => { }); }; -const generateDocumentation = (endpoint: Endpoint): string => { +const generateDocumentation = (endpoint: SpecificationTypes.Endpoint): string => { return endpoint.docUrl; }; const generateParams = ( - endpoint: Endpoint, - schema: Schema -): { urlParams: UrlParams; bodyParams: BodyParams } | undefined => { + endpoint: SpecificationTypes.Endpoint, + schema: SpecificationTypes.Model +): { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams } | undefined => { const { request } = endpoint; if (!request) { return; } - const requestType = schema.types.find( - ({ name: { name, namespace } }) => name === request.name && namespace === request.namespace - ); + const requestType = findTypeDefinition(schema, request); if (!requestType) { return; } - - const urlParams = generateUrlParams(requestType); + const urlParams = generateQueryParams(requestType as SpecificationTypes.Request, schema); const bodyParams = generateBodyParams(requestType); return { urlParams, bodyParams }; }; -const generateUrlParams = (requestType: SchemaType): UrlParams => { - return {}; -}; - -const generateBodyParams = (requestType: SchemaType): BodyParams => { +const generateBodyParams = ( + requestType: SpecificationTypes.TypeDefinition +): AutocompleteBodyParams => { return {}; }; const addParams = ( - definition: Definition, - params: { urlParams: UrlParams; bodyParams: BodyParams } -): Definition => { + definition: AutocompleteDefinition, + params: { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams } +): AutocompleteDefinition => { const { urlParams, bodyParams } = params; if (urlParams && Object.keys(urlParams).length > 0) { definition.url_params = urlParams; @@ -119,15 +79,19 @@ const addParams = ( return definition; }; -const generateDefinition = (endpoint: Endpoint, schema: Schema): Definition => { +const generateDefinition = ( + endpoint: SpecificationTypes.Endpoint, + schema: SpecificationTypes.Model +): AutocompleteDefinition => { const methods = generateMethods(endpoint); const patterns = generatePatterns(endpoint); const documentation = generateDocumentation(endpoint); - let definition: Definition = { methods, patterns, documentation }; + let definition: AutocompleteDefinition = {}; const params = generateParams(endpoint, schema); if (params) { definition = addParams(definition, params); } + definition = { ...definition, methods, patterns, documentation }; return definition; }; @@ -143,7 +107,7 @@ export function generateConsoleDefinitions({ }) { const pathToSchemaFile = Path.resolve(specsRepo, 'output/schema/schema.json'); log.info('loading the ES specification schema file'); - const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as Schema; + const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as SpecificationTypes.Model; const { endpoints } = schema; log.info(`iterating over endpoints array: ${endpoints.length} endpoints`); @@ -151,7 +115,7 @@ export function generateConsoleDefinitions({ const { name } = endpoint; log.info(name); const definition = generateDefinition(endpoint, schema); - const fileContent: { [name: string]: Definition } = { + const fileContent: { [name: string]: AutocompleteDefinition } = { [name]: definition, }; fs.writeFileSync( diff --git a/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts b/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts new file mode 100644 index 00000000000000..3d658ba60f1741 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts @@ -0,0 +1,375 @@ +/* + * Copyright 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 { SpecificationTypes } from './types'; +import { generateQueryParams } from './generate_query_params'; +import { UrlParamValue } from './types/autocomplete_definition_types'; + +describe('generateQueryParams', () => { + const mockRequestType: SpecificationTypes.Request = { + body: { kind: 'no_body' }, + kind: 'request', + name: { + name: 'TestRequest', + namespace: 'test.namespace', + }, + path: [], + query: [], + specLocation: '', + }; + + const getMockProperty = ({ + propertyName, + typeName, + serverDefault, + type, + }: { + propertyName: string; + typeName?: SpecificationTypes.TypeName; + serverDefault?: SpecificationTypes.Property['serverDefault']; + type?: SpecificationTypes.ValueOf; + }): SpecificationTypes.Property => { + return { + description: 'Description', + name: propertyName, + required: false, + serverDefault: serverDefault ?? undefined, + type: type ?? { + kind: 'instance_of', + type: typeName ?? { + name: 'string', + namespace: '_builtins', + }, + }, + }; + }; + + const mockSchema: SpecificationTypes.Model = { + endpoints: [], + types: [], + }; + + it('iterates over attachedBehaviours', () => { + const behaviour1: SpecificationTypes.Interface = { + kind: 'interface', + name: { + name: 'behaviour1', + namespace: 'test.namespace', + }, + properties: [getMockProperty({ propertyName: 'property1' })], + specLocation: '', + }; + const behaviour2: SpecificationTypes.Interface = { + kind: 'interface', + name: { + name: 'behaviour2', + namespace: 'test.namespace', + }, + properties: [ + getMockProperty({ propertyName: 'property2' }), + getMockProperty({ propertyName: 'property3' }), + ], + specLocation: '', + }; + const schema: SpecificationTypes.Model = { + ...mockSchema, + types: [behaviour1, behaviour2], + }; + const requestType: SpecificationTypes.Request = { + ...mockRequestType, + attachedBehaviors: ['behaviour1', 'behaviour2'], + }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + property1: '', + property2: '', + property3: '', + }); + }); + + it('iterates over query properties', () => { + const requestType = { + ...mockRequestType, + query: [ + getMockProperty({ propertyName: 'property1' }), + getMockProperty({ propertyName: 'property2' }), + ], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + property1: '', + property2: '', + }); + }); + + it('converts builtin types', () => { + const stringProperty = getMockProperty({ + propertyName: 'stringProperty', + typeName: { name: 'string', namespace: '_builtins' }, + }); + const numberProperty = getMockProperty({ + propertyName: 'numberProperty', + typeName: { name: 'number', namespace: '_builtins' }, + }); + const booleanProperty = getMockProperty({ + propertyName: 'booleanProperty', + typeName: { name: 'boolean', namespace: '_builtins' }, + }); + const requestType = { + ...mockRequestType, + query: [stringProperty, numberProperty, booleanProperty], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + stringProperty: '', + numberProperty: '', + booleanProperty: '__flag__', + }); + }); + + it('adds serverDefault value if any', () => { + const propertyWithDefault = getMockProperty({ + propertyName: 'propertyWithDefault', + serverDefault: 'default', + }); + const requestType = { ...mockRequestType, query: [propertyWithDefault] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + propertyWithDefault: ['default'], + }); + }); + + it('converts an enum property', () => { + const enumProperty = getMockProperty({ + propertyName: 'enumProperty', + typeName: { name: 'EnumType', namespace: 'test.namespace' }, + }); + const enumType: SpecificationTypes.Enum = { + kind: 'enum', + members: [ + { + name: 'enum1', + }, + { + name: 'enum2', + }, + ], + name: { + name: 'EnumType', + namespace: 'test.namespace', + }, + specLocation: '', + }; + const requestType = { ...mockRequestType, query: [enumProperty] }; + const schema = { ...mockSchema, types: [enumType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + enumProperty: ['enum1', 'enum2'], + }); + }); + + it('converts a type alias', () => { + const typeAliasProperty = getMockProperty({ + propertyName: 'typeAliasProperty', + typeName: { + name: 'SomeTypeAlias', + namespace: 'test.namespace', + }, + }); + const typeAliasType: SpecificationTypes.TypeAlias = { + kind: 'type_alias', + name: { + name: 'SomeTypeAlias', + namespace: 'test.namespace', + }, + specLocation: '', + type: { + kind: 'instance_of', + type: { + name: 'integer', + namespace: '_types', + }, + }, + }; + const requestType = { ...mockRequestType, query: [typeAliasProperty] }; + const schema: SpecificationTypes.Model = { ...mockSchema, types: [typeAliasType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + typeAliasProperty: '', + }); + }); + + it('converts a literal_value to a string', () => { + const stringProperty = getMockProperty({ + propertyName: 'stringProperty', + type: { kind: 'literal_value', value: 'stringValue' }, + }); + const numberProperty = getMockProperty({ + propertyName: 'numberProperty', + type: { kind: 'literal_value', value: 14 }, + }); + const booleanProperty = getMockProperty({ + propertyName: 'booleanProperty', + type: { kind: 'literal_value', value: true }, + }); + const requestType = { + ...mockRequestType, + query: [stringProperty, numberProperty, booleanProperty], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + stringProperty: ['stringValue'], + numberProperty: ['14'], + booleanProperty: ['true'], + }); + }); + + describe('converts a union_of', () => { + it('flattens the array if one of the items is converted to an array', () => { + const enumType: SpecificationTypes.Enum = { + kind: 'enum', + members: [ + { + name: 'enum1', + }, + { name: 'enum2' }, + ], + name: { name: 'EnumType', namespace: 'test.namespace' }, + specLocation: '', + }; + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'EnumType', + namespace: 'test.namespace', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const schema: SpecificationTypes.Model = { ...mockSchema, types: [enumType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + unionProperty: ['enum1', 'enum2'], + }); + }); + + it('removes empty string from the array', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'string', + namespace: '_builtins', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unionProperty: [], + }); + }); + + it('if one item is a boolean and others are empty, converts to a flag', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'string', + namespace: '_builtins', + }, + }, + { + kind: 'instance_of', + type: { + name: 'number', + namespace: '_builtins', + }, + }, + { + kind: 'instance_of', + type: { + name: 'boolean', + namespace: '_builtins', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unionProperty: '__flag__', + }); + }); + + it('if one item is an unknown type, converts it to an empty string', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'literal_value', + value: 'test', + }, + { + kind: 'instance_of', + type: { + name: 'UnknownType', + namespace: 'test.namespace', + }, + }, + ], + }, + }); + + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + // check that no `undefined` values are added + const value = urlParams.unionProperty as UrlParamValue[]; + expect(value.length).toEqual(1); + }); + }); + + it('converts an unknown type to an empty string', () => { + const unknownTypeProperty = getMockProperty({ + propertyName: 'unknownTypeProperty', + type: { + kind: 'instance_of', + type: { + name: 'UnknownType', + namespace: 'test.namespace', + }, + }, + }); + + const requestType = { ...mockRequestType, query: [unknownTypeProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unknownTypeProperty: '', + }); + }); +}); diff --git a/packages/kbn-generate-console-definitions/src/generate_query_params.ts b/packages/kbn-generate-console-definitions/src/generate_query_params.ts new file mode 100644 index 00000000000000..5310e85d689368 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/generate_query_params.ts @@ -0,0 +1,219 @@ +/* + * Copyright 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. + */ + +/** + * Types that are important for query params conversion: + * TypeDefinition = Interface | Request | Response | Enum | TypeAlias + * ValueOf = InstanceOf | ArrayOf | UnionOf | DictionaryOf | UserDefinedValue | LiteralValue; + * + * Conversion steps: + * 1. The schema has a property `endpoints` which is "Endpoint[]" + * 2. Each "Endpoint" has a property `request` which is "TypeName" + * 3. Using "TypeName" we find the "TypeDefinition" in the property `types` of the schema + * 4. the "TypeDefinition" is cast to "Request" + * - "Request" has a property `query` which is "Property[]" + * - "Request" has a property `attachedBehaviours` which is "string[]" + * With "string" we find a "TypeDefinition" that is "Interface" + * This "Interface" has a property `properties` which is "Property[]" + * 5. Each "Property" (from both `query` and `attachedBehaviours`) now can be converted + * 6. Each "Property" has a property `type` that is "ValueOf" + * 7. If "ValueOf" can be one of "InstanceOf", "ArrayOf", "UnionOf", "DictionaryOf", "UserDefinedValue", "LiteralValue" + * - "InstanceOf": it has a property `type` which is a "TypeName" + * - if "TypeName" has a `namespace` = "_builtins" then it's a primitive type like "string" -> convert according to set rules for primitives + * - if "TypeName" has a `namespace` = "_types" then it's a defined type that can be found in the schema + * - the found "TypeDefinition" can be either "Enum" or "TypeAlias" (not "Interface", "Request" or "Response") + * - if it's "TypeAlias", it has a property `type` which is "ValueOf" -> handle it as "ValueOf" (recursion) + * - if it's "Enum", it has a property `members` which is "EnumMember[]" -> convert each "EnumMember" (only need `name` property) + * - "ArrayOf": it has a property `value` which is "ValueOf" -> convert as "ValueOf" + * - "UnionOf": it has a property `items` which is "ValueOf[]" -> convert each as "ValueOf" + * - "DictionaryOf": not used for query params + * - "UserDefinedValue": not used for query params + * - "LiteralValue": it has `value` that is `string`, `number` or `boolean` + * + * Autocomplete definitions currently work with 2 url param types: + * - "__flag__" for a boolean (suggesting value 'true' and 'false') + * - list of options in an array, for example ['30s', '-1', '0'], suggesting all 3 values in a list + * If there is only a default value, we need to wrap it in an array, so that this value is displayed in a suggestion (similar to the list). + * Numbers need to be converted to strings, otherwise they are not displayed as suggestions. + * + */ + +import { UrlParamValue } from './types/autocomplete_definition_types'; +import type { AutocompleteUrlParams, SpecificationTypes } from './types'; +import { findTypeDefinition } from './utils'; + +const booleanFlagString = '__flag__'; +const trueValueString = String(true); +const falseValueString = String(false); + +export const generateQueryParams = ( + requestType: SpecificationTypes.Request, + schema: SpecificationTypes.Model +): AutocompleteUrlParams => { + let urlParams = {} as AutocompleteUrlParams; + const { types } = schema; + const { attachedBehaviors, query } = requestType; + // if there are any attached behaviors, iterate over each and find its type + if (attachedBehaviors) { + for (const attachedBehavior of attachedBehaviors) { + const foundBehavior = types.find((type) => type.name.name === attachedBehavior); + if (foundBehavior) { + // attached behaviours are interfaces + const behaviorType = foundBehavior as SpecificationTypes.Interface; + // if there are any properties in the behavior, iterate over each and add it to url params + const { properties } = behaviorType; + urlParams = convertProperties(properties, urlParams, schema); + } + } + } + + // iterate over properties in query and add it to url params + urlParams = convertProperties(query, urlParams, schema); + + return urlParams; +}; + +const convertProperties = ( + properties: SpecificationTypes.Property[], + urlParams: AutocompleteUrlParams, + schema: SpecificationTypes.Model +): AutocompleteUrlParams => { + for (const property of properties) { + const { name, serverDefault, type } = property; + // property has `type` which is `ValueOf` + const convertedValue = convertValueOf(type, serverDefault, schema); + urlParams[name] = convertedValue ?? ''; + } + return urlParams; +}; + +const convertValueOf = ( + valueOf: SpecificationTypes.ValueOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { kind } = valueOf; + if (kind === 'instance_of') { + return convertInstanceOf(valueOf, serverDefault, schema); + } else if (kind === 'array_of') { + return convertArrayOf(valueOf, serverDefault, schema); + } else if (kind === 'union_of') { + return convertUnionOf(valueOf, serverDefault, schema); + } else if (kind === 'literal_value') { + return convertLiteralValue(valueOf); + } + // for query params we can ignore 'dictionary_of' and 'user_defined_value' + return ''; +}; + +const convertInstanceOf = ( + type: SpecificationTypes.InstanceOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { type: typeName } = type; + const { name: propertyName, namespace } = typeName; + if (namespace === '_builtins') { + /** + * - `string` + * - `boolean` + * - `number` + * - `null` // ignore for query params + * - `void` // ignore for query params + * - `binary` // ignore for query params + */ + + if (propertyName === 'boolean') { + // boolean is converted to a flag param + return booleanFlagString; + } else { + // if default value, convert to string and put in an array + return serverDefault ? [serverDefault.toString()] : ''; + } + } else { + // if it's a defined type, try to convert it + const definedType = findTypeDefinition(schema, typeName); + if (definedType) { + // TypeDefinition can only be Enum or TypeAlias + if (definedType.kind === 'enum') { + return convertEnum(definedType as SpecificationTypes.Enum); + } else if (definedType.kind === 'type_alias') { + const aliasValueOf = definedType.type; + return convertValueOf(aliasValueOf, serverDefault, schema); + } + } + } + return ''; +}; + +const convertArrayOf = ( + type: SpecificationTypes.ArrayOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { value } = type; + // simply convert the value of an array item + return convertValueOf(value, serverDefault, schema); +}; + +const convertUnionOf = ( + type: SpecificationTypes.UnionOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { items } = type; + const itemValues = new Set(); + for (const item of items) { + // each item is ValueOf + const convertedValue = convertValueOf(item, serverDefault, schema); + // flatten array if needed + if (convertedValue instanceof Array) { + convertedValue.forEach((v) => itemValues.add(v)); + } else itemValues.add(convertedValue); + } + + // if an empty string is in values, delete it + if (itemValues.has('')) { + itemValues.delete(''); + } + + // if there is a flag in the values, convert it to "true" + "false" + if (itemValues.size > 1 && itemValues.has(booleanFlagString)) { + itemValues.delete(booleanFlagString); + itemValues.add(trueValueString); + itemValues.add(falseValueString); + } + + // if only 2 values ("true","false"), convert back to a flag + // that can happen if the values before were ("true", "__flag__") or ("false", "__flag__") + if ( + itemValues.size === 2 && + itemValues.has(trueValueString) && + itemValues.has(falseValueString) + ) { + itemValues.clear(); + itemValues.add(booleanFlagString); + } + + // if only 1 element that is a flag, don't put it in an array + if (itemValues.size === 1 && itemValues.has(booleanFlagString)) { + return itemValues.values().next().value; + } + return [...itemValues] as UrlParamValue; +}; + +const convertLiteralValue = (type: SpecificationTypes.LiteralValue): UrlParamValue | undefined => { + // convert the value to a string + return [type.value.toString()]; +}; + +const convertEnum = (enumDefinition: SpecificationTypes.Enum): UrlParamValue => { + const { members } = enumDefinition; + // only need the `name` property + return members.map((member) => member.name); +}; diff --git a/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts b/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts new file mode 100644 index 00000000000000..edbb9bd74d9a87 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts @@ -0,0 +1,23 @@ +/* + * Copyright 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 type UrlParamValue = number | string | number[] | string[] | boolean; +export interface AutocompleteUrlParams { + [key: string]: UrlParamValue; +} + +export interface AutocompleteBodyParams { + [key: string]: number | string; +} + +export interface AutocompleteDefinition { + documentation?: string; + methods?: string[]; + patterns?: string[]; + url_params?: AutocompleteUrlParams; + data_autocomplete_rules?: AutocompleteBodyParams; +} diff --git a/packages/kbn-generate-console-definitions/src/types/index.ts b/packages/kbn-generate-console-definitions/src/types/index.ts new file mode 100644 index 00000000000000..a1825923506812 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 type { + AutocompleteDefinition, + AutocompleteUrlParams, + AutocompleteBodyParams, +} from './autocomplete_definition_types'; + +export * as SpecificationTypes from './specification_types'; diff --git a/packages/kbn-generate-console-definitions/src/types/specification_types.ts b/packages/kbn-generate-console-definitions/src/types/specification_types.ts new file mode 100644 index 00000000000000..b9e61ded064488 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/specification_types.ts @@ -0,0 +1,442 @@ +/* + * Copyright 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. + */ + +/** + * --------------- THIS FILE IS COPIED FROM ES SPECIFICATION REPO ------------------- + * + */ + +/** + * The name of a type, composed of a simple name and a namespace. Hierarchical namespace elements are separated by + * a dot, e.g 'cat.cat_aliases'. + * + * Builtin namespaces: + * - "generic" for type names that are generic parameter values from the enclosing type. + * - "internal" for primitive and builtin types (e.g. Id, IndexName, etc) + * Builtin types: + * - boolean, + * - string, + * - number: a 64bits floating point number. Additional types will be added for integers. + * - null: the null value. Since JS distinguishes undefined and null, some APIs make use of this value. + * - object: used to represent "any". We may forbid it at some point. UserDefinedValue should be used for user data. + */ +export interface TypeName { + namespace: string; + name: string; +} + +// ------------------------------------------------------------------------------------------------ +// Value types + +// Note: "required" is part of Property. This means we can have optional properties but we can't have null entries in +// containers (array and dictionary), which doesn't seem to be needed. +// +// The 'kind' property is used to tag and disambiguate union type members, and allow type-safe pattern matching in TS: +// see https://blog.logrocket.com/pattern-matching-and-type-safety-in-typescript-1da1231a2e34/ +// and https://medium.com/@fillopeter/pattern-matching-with-typescript-done-right-94049ddd671c + +/** + * Type of a value. Used both for property types and nested type definitions. + */ +export type ValueOf = + | InstanceOf + | ArrayOf + | UnionOf + | DictionaryOf + | UserDefinedValue + | LiteralValue; + +/** + * A single value + */ +export interface InstanceOf { + kind: 'instance_of'; + type: TypeName; + /** generic parameters: either concrete types or open parameters from the enclosing type */ + generics?: ValueOf[]; +} + +/** + * An array + */ +export interface ArrayOf { + kind: 'array_of'; + value: ValueOf; +} + +/** + * One of several possible types which don't necessarily have a common superinterface + */ +export interface UnionOf { + kind: 'union_of'; + items: ValueOf[]; +} + +/** + * A dictionary (or map). The key is a string or a number (or a union thereof), possibly through an alias. + * + * If `singleKey` is true, then this dictionary can only have a single key. This is a common pattern in ES APIs, + * used to associate a value to a field name or some other identifier. + */ +export interface DictionaryOf { + kind: 'dictionary_of'; + key: ValueOf; + value: ValueOf; + singleKey: boolean; +} + +/** + * A user defined value. To be used when bubbling a generic parameter up to the top-level interface is + * inconvenient or impossible (e.g. for lists of user-defined values of possibly different types). + * + * Clients will allow providing a serializer/deserializer when reading/writing properties of this type, + * and should also accept raw json. + * + * Think twice before using this as it defeats the purpose of a strongly typed API, and deserialization + * will also require to buffer raw JSON data which may have performance implications. + */ +export interface UserDefinedValue { + kind: 'user_defined_value'; +} + +/** + * A literal value. This is used for tagged unions, where each type member of a union has a 'type' + * attribute that defines its kind. This metamodel heavily uses this approach with its 'kind' attributes. + * + * It may later be used to set a property to a constant value, which is why it accepts not only strings but also + * other primitive types. + */ +export interface LiteralValue { + kind: 'literal_value'; + value: string | number | boolean; +} + +/** + * An interface or request interface property. + */ +export interface Property { + name: string; + type: ValueOf; + required: boolean; + description?: string; + docUrl?: string; + docId?: string; + since?: string; + serverDefault?: boolean | string | number | string[] | number[]; + deprecation?: Deprecation; + availability?: Availabilities; + stability?: Stability; + /** + * If specified takes precedence over `name` when generating code. `name` is always the value + * to be sent over the wire + */ + codegenName?: string; + /** An optional set of aliases for `name` */ + aliases?: string[]; + /** If the enclosing interface is a variants container, is this a property of the container and not a variant? */ + containerProperty?: boolean; + /** If this property has a quirk that needs special attention, give a short explanation about it */ + esQuirk?: string; +} + +// ------------------------------------------------------------------------------------------------ +// Type definitions + +export type TypeDefinition = Interface | Request | Response | Enum | TypeAlias; + +// ------------------------------------------------------------------------------------------------ + +/** + * Common attributes for all type definitions + */ +export interface BaseType { + name: TypeName; + description?: string; + /** Link to public documentation */ + docUrl?: string; + docId?: string; + deprecation?: Deprecation; + /** If this endpoint has a quirk that needs special attention, give a short explanation about it */ + esQuirk?: string; + kind: string; + /** Variant name for externally tagged variants */ + variantName?: string; + /** + * Additional identifiers for use by code generators. Usage depends on the actual type: + * - on unions (modeled as alias(union_of)), these are identifiers for the union members + * - for additional properties, this is the name of the dict that holds these properties + * - for additional property, this is the name of the key and value fields that hold the + * additional property + */ + codegenNames?: string[]; + /** + * Location of an item. The path is relative to the "specification" directory, e.g "_types/common.ts#L1-L2" + */ + specLocation: string; +} + +export type Variants = ExternalTag | InternalTag | Container; + +export interface VariantBase { + /** + * Is this variant type open to extensions? Default to false. Used for variants that can + * be extended with plugins. If true, target clients should allow for additional variants + * with a variant tag outside the ones defined in the spec and arbitrary data as the value. + */ + nonExhaustive?: boolean; +} + +export interface ExternalTag extends VariantBase { + kind: 'external_tag'; +} + +export interface InternalTag extends VariantBase { + kind: 'internal_tag'; + /* Name of the property that holds the variant tag */ + tag: string; + /* Default value for the variant tag if it's missing */ + defaultTag?: string; +} + +export interface Container extends VariantBase { + kind: 'container'; +} + +/** + * Inherits clause (aka extends or implements) for an interface or request + */ +export interface Inherits { + type: TypeName; + generics?: ValueOf[]; +} + +/** + * An interface type + */ +export interface Interface extends BaseType { + kind: 'interface'; + /** + * Open generic parameters. The name is that of the parameter, the namespace is an arbitrary value that allows + * this fully qualified type name to be used when this open generic parameter is used in property's type. + */ + generics?: TypeName[]; + inherits?: Inherits; + implements?: Inherits[]; + + /** + * Behaviors directly implemented by this interface + */ + behaviors?: Inherits[]; + + /** + * Behaviors attached to this interface, coming from the interface itself (see `behaviors`) + * or from inherits and implements ancestors + */ + attachedBehaviors?: string[]; + properties: Property[]; + /** + * The property that can be used as a shortcut for the entire data structure in the JSON. + */ + shortcutProperty?: string; + + /** Identify containers */ + variants?: Container; +} + +/** + * A request type + */ +export interface Request extends BaseType { + // Note: does not extend Interface as properties are split across path, query and body + kind: 'request'; + generics?: TypeName[]; + /** The parent defines additional body properties that are added to the body, that has to be a PropertyBody */ + inherits?: Inherits; + implements?: Inherits[]; + /** URL path properties */ + path: Property[]; + /** Query string properties */ + query: Property[]; + // FIXME: we need an annotation that lists query params replaced by a body property so that we can skip them. + // Examples on _search: sort -> sort, _source -> (_source, _source_include, _source_exclude) + // Or can we say that implicitly a body property replaces all path params starting with its name? + // Is there a priority rule between path and body parameters? + // + // We can also pull path parameter descriptions on body properties they replace + + /** + * Body type. Most often a list of properties (that can extend those of the inherited interface, see above), except for a + * few specific cases that use other types such as bulk (array) or create (generic parameter). Or NoBody for requests + * that don't have a body. + */ + body: Body; + behaviors?: Inherits[]; + attachedBehaviors?: string[]; +} + +/** + * A response type + */ +export interface Response extends BaseType { + kind: 'response'; + generics?: TypeName[]; + body: Body; + behaviors?: Inherits[]; + attachedBehaviors?: string[]; + exceptions?: ResponseException[]; +} + +export interface ResponseException { + description?: string; + body: Body; + statusCodes: number[]; +} + +export type Body = ValueBody | PropertiesBody | NoBody; + +export interface ValueBody { + kind: 'value'; + value: ValueOf; + codegenName?: string; +} + +export interface PropertiesBody { + kind: 'properties'; + properties: Property[]; +} + +export interface NoBody { + kind: 'no_body'; +} + +/** + * An enumeration member. + * + * When enumeration members can become ambiguous when translated to an identifier, the `name` property will be a good + * identifier name, and `stringValue` will be the string value to use on the wire. + * See DateMathTimeUnit for an example of this, which have members for "m" (minute) and "M" (month). + */ +export interface EnumMember { + /** The identifier to use for this enum */ + name: string; + /** An optional set of aliases for `name` */ + aliases?: string[]; + /** + * If specified takes precedence over `name` when generating code. `name` is always the value + * to be sent over the wire + */ + codegenName?: string; + description?: string; + deprecation?: Deprecation; + since?: string; +} + +/** + * An enumeration + */ +export interface Enum extends BaseType { + kind: 'enum'; + /** + * If the enum is open, it means that other than the specified values it can accept an arbitrary value. + * If this property is not present, it means that the enum is not open (in other words, is closed). + */ + isOpen?: boolean; + members: EnumMember[]; +} + +/** + * An alias for an existing type. + */ +export interface TypeAlias extends BaseType { + kind: 'type_alias'; + type: ValueOf; + /** generic parameters: either concrete types or open parameters from the enclosing type */ + generics?: TypeName[]; + /** Only applicable to `union_of` aliases: identify typed_key unions (external) and variant inventories (internal) */ + variants?: InternalTag | ExternalTag; +} + +// ------------------------------------------------------------------------------------------------ + +export enum Stability { + stable = 'stable', + beta = 'beta', + experimental = 'experimental', +} +export enum Visibility { + public = 'public', + feature_flag = 'feature_flag', + private = 'private', +} + +export interface Deprecation { + version: string; + description: string; +} + +export interface Availabilities { + stack?: Availability; + serverless?: Availability; +} + +export interface Availability { + since?: string; + featureFlag?: string; + stability?: Stability; + visibility?: Visibility; +} + +export interface Endpoint { + name: string; + description: string; + docUrl: string; + docId?: string; + deprecation?: Deprecation; + availability: Availabilities; + + /** + * If the request value is `null` it means that there is not yet a + * request type definition for this endpoint. + */ + request: TypeName | null; + requestBodyRequired: boolean; // Not sure this is useful + + /** + * If the response value is `null` it means that there is not yet a + * response type definition for this endpoint. + */ + response: TypeName | null; + + urls: UrlTemplate[]; + + /** + * The version when this endpoint reached its current stability level. + * Missing data means "forever", i.e. before any of the target client versions produced from this spec. + */ + since?: string; + stability?: Stability; + visibility?: Visibility; + featureFlag?: string; + requestMediaType?: string[]; + responseMediaType?: string[]; + privileges?: { + index?: string[]; + cluster?: string[]; + }; +} + +export interface UrlTemplate { + path: string; + methods: string[]; + deprecation?: Deprecation; +} + +export interface Model { + types: TypeDefinition[]; + endpoints: Endpoint[]; +} diff --git a/packages/kbn-generate-console-definitions/src/utils.ts b/packages/kbn-generate-console-definitions/src/utils.ts new file mode 100644 index 00000000000000..29c24e63fa58f9 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/utils.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 type { SpecificationTypes } from './types'; +export const findTypeDefinition = ( + schema: SpecificationTypes.Model, + typeName: SpecificationTypes.TypeName +): SpecificationTypes.TypeDefinition | undefined => { + return schema.types.find( + (type) => type.name.name === typeName.name && type.name.namespace === typeName.namespace + ); +}; From f758ba47507fb3ec18ffbaeab32ff36ea828dd2c Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 5 Jul 2023 12:39:58 +0200 Subject: [PATCH 80/98] Use alert details page URL for the log threshold rule if the config is enabled (#161175) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #161117 ## Summary If `xpack.observability.unsafe.alertDetails.logs.enabled` is enabled, we will use the new alert details page URL in `context.alertDetailsUrl` otherwise, we send the user to the alerts page filtered for that alert. (Partially brings back [the logic for alert details URL](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027) and [getAlertDetailsConfig](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027)) ## 🧪 How to test 1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as false in Kibana yml config or remove the config 2. Create a log threshold rule with an action for both active state and recovered state 3. When the alert is triggered, check the default message, it should include the alertDetailsURL, by clicking on that, you should land on the alerts page filtered for that alert 4. Make the alert recovered and check and similar URL should be generated New alert details page: 1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as true in Kibana yml config 2. Repeat the steps 2,3,4 as mentioned before 3. This time, you should land on the new alert details page ![image](https://github.com/elastic/kibana/assets/12370520/a2f99bd7-cfaa-4146-bedf-72458973b463) --- .../infra/server/lib/alerting/common/utils.ts | 10 +++++ .../log_threshold/log_threshold_executor.ts | 43 ++++++++++++------- .../plugins/infra/server/lib/infra_types.ts | 2 + x-pack/plugins/infra/server/plugin.ts | 1 + 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts index 8377756654a9e3..dc518e1e08cf76 100644 --- a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts +++ b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts @@ -9,6 +9,7 @@ import { isEmpty, isError } from 'lodash'; import { schema } from '@kbn/config-schema'; import { Logger, LogMeta } from '@kbn/logging'; import type { ElasticsearchClient, IBasePath } from '@kbn/core/server'; +import { ObservabilityConfig } from '@kbn/observability-plugin/server'; import { addSpaceIdToPath } from '@kbn/spaces-plugin/common'; import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils'; import { @@ -109,6 +110,15 @@ export const createScopedLogger = ( }; }; +export const getAlertDetailsPageEnabledForApp = ( + config: ObservabilityConfig['unsafe']['alertDetails'] | null, + appName: keyof ObservabilityConfig['unsafe']['alertDetails'] +): boolean => { + if (!config) return false; + + return config[appName].enabled; +}; + export const getViewInInventoryAppUrl = ({ basePath, criteria, diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 9b93e021ae8f1f..e36ae54746b3de 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -7,7 +7,11 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { i18n } from '@kbn/i18n'; -import { getAlertUrl, AlertsLocatorParams } from '@kbn/observability-plugin/common'; +import { + AlertsLocatorParams, + getAlertDetailsUrl, + getAlertUrl, +} from '@kbn/observability-plugin/common'; import { ALERT_CONTEXT, ALERT_EVALUATION_THRESHOLD, @@ -59,6 +63,7 @@ import { InfraBackendLibs } from '../../infra_types'; import { AdditionalContext, flattenAdditionalContext, + getAlertDetailsPageEnabledForApp, getContextForRecoveredAlerts, getGroupByObject, unflattenObject, @@ -133,6 +138,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => getAlertByAlertUuid, } = services; const { basePath, alertsLocator } = libs; + const config = libs.getAlertDetailsConfig(); const alertFactory: LogThresholdAlertFactory = ( id, @@ -183,13 +189,15 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => alert.scheduleActions(actionGroup, { ...sharedContext, ...context, - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - libs.alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: getAlertDetailsPageEnabledForApp(config, 'logs') + ? getAlertDetailsUrl(libs.basePath, spaceId, alertUuid) + : await getAlertUrl( + alertUuid, + spaceId, + indexedStartedAt, + libs.alertsLocator, + libs.basePath.publicBaseUrl + ), }); }); } @@ -246,6 +254,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => validatedParams, getAlertByAlertUuid, alertsLocator, + isAlertDetailsPageEnabled: getAlertDetailsPageEnabledForApp(config, 'logs'), }); } catch (e) { throw new Error(e); @@ -859,6 +868,7 @@ const processRecoveredAlerts = async ({ validatedParams, getAlertByAlertUuid, alertsLocator, + isAlertDetailsPageEnabled = false, }: { basePath: IBasePath; getAlertStartedDate: (alertId: string) => string | null; @@ -871,6 +881,7 @@ const processRecoveredAlerts = async ({ alertUuid: string ) => Promise | null> | null; alertsLocator?: LocatorPublic; + isAlertDetailsPageEnabled?: boolean; }) => { const groupByKeysObjectForRecovered = getGroupByObject( validatedParams.groupBy, @@ -887,13 +898,15 @@ const processRecoveredAlerts = async ({ const viewInAppUrl = addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl); const baseContext = { - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ), + alertDetailsUrl: isAlertDetailsPageEnabled + ? getAlertDetailsUrl(basePath, spaceId, alertUuid) + : await getAlertUrl( + alertUuid, + spaceId, + indexedStartedAt, + alertsLocator, + basePath.publicBaseUrl + ), group: hasGroupBy(validatedParams) ? recoveredAlertId : null, groupByKeys: groupByKeysObjectForRecovered[recoveredAlertId], timestamp: startedAt.toISOString(), diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index e31bad1b5ffeb2..6bb24c722fe819 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -9,6 +9,7 @@ import type { Logger } from '@kbn/logging'; import type { IBasePath } from '@kbn/core/server'; import type { handleEsError } from '@kbn/es-ui-shared-plugin/server'; import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; +import { ObservabilityConfig } from '@kbn/observability-plugin/server'; import type { LocatorPublic } from '@kbn/share-plugin/common'; import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server'; import { RulesServiceSetup } from '../services/rules'; @@ -33,6 +34,7 @@ export interface InfraBackendLibs extends InfraDomainLibs { metricsRules: RulesServiceSetup; sources: InfraSources; sourceStatus: InfraSourceStatus; + getAlertDetailsConfig: () => ObservabilityConfig['unsafe']['alertDetails']; getStartServices: InfraPluginStartServicesAccessor; handleEsError: typeof handleEsError; logger: Logger; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index 2449293dfa3aa0..07bafb4781e70a 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -193,6 +193,7 @@ export class InfraServerPlugin logsRules: this.logsRules.setup(core, plugins), metricsRules: this.metricsRules.setup(core, plugins), getStartServices: () => core.getStartServices(), + getAlertDetailsConfig: () => plugins.observability.getAlertDetailsConfig(), logger: this.logger, basePath: core.http.basePath, alertsLocator: plugins.share.url.locators.get(alertsLocatorID), From 16528cf28994b30642262a018c89c5217c28f884 Mon Sep 17 00:00:00 2001 From: Wafaa Nasr Date: Wed, 5 Jul 2023 11:44:03 +0100 Subject: [PATCH 81/98] [Security Solution] [Exceptions] Amend `Rule Exception's Comment` text (#161092) ## Summary - Addresses Docs team comment https://github.com/elastic/kibana/pull/159908#discussion_r1247964658 --- .../e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts | 4 ++-- .../components/add_exception_flyout/translations.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts index 59af4592d2ebe7..0861bf1231e28d 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts @@ -169,7 +169,7 @@ describe('Rule Exceptions workflows from Alert', () => { */ validateExceptionCommentCountAndText( 1, - 'Exception conditions are pre-filled with relevant data from alert with "id"' + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id):' ); addExceptionFlyoutItemName(ITEM_NAME); @@ -207,7 +207,7 @@ describe('Rule Exceptions workflows from Alert', () => { */ validateExceptionCommentCountAndText( 1, - 'Exception conditions are pre-filled with relevant data from alert with "id"' + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id):' ); addExceptionFlyoutItemName(ITEM_NAME); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts index 215bb3fc29923e..d27d7994bb375e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts @@ -90,6 +90,6 @@ export const ADD_RULE_EXCEPTION_FROM_ALERT_COMMENT = (alertId: string) => { values: { alertId }, defaultMessage: - 'Exception conditions are pre-filled with relevant data from alert with "id" {alertId}.', + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id): {alertId}.', } ); From f43601d294a3d789c0aa40892c80e9e40859cab6 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 5 Jul 2023 13:33:09 +0200 Subject: [PATCH 82/98] [Cases] Validate page and perPage parameters in find APIs (#161111) Connected to https://github.com/elastic/kibana/issues/146945 ## Summary | Description | Limit | Done? | Documented? | ------------- | ---- | :---: | ---- | | Total number of cases/user actions/comments per page | 100 | :white_check_mark: | No | N/A | | Maximum number of cases/user actions/comments returned from the API | 10.000 | :white_check_mark: | No | N/A | ### 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] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### Release Notes Max value for perPage parameter in find Cases API is now 100. Max value for perPage parameter in find User Actions API is now 100. Max value for perPage parameter in find Comments API is now 100. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: lcawl --- .../cases/case-apis-passthru.asciidoc | 17 +- x-pack/plugins/cases/common/api/cases/case.ts | 218 +++++++++--------- .../cases/common/api/cases/comment/index.ts | 32 ++- .../api/cases/user_actions/operations/find.ts | 20 +- .../plugins/cases/common/constants/index.ts | 2 + .../plugins/cases/common/schema/index.test.ts | 164 +++++++++++-- x-pack/plugins/cases/common/schema/index.ts | 42 ++++ x-pack/plugins/cases/common/schema/types.ts | 20 ++ .../plugins/cases/docs/openapi/bundled.json | 45 ++-- .../plugins/cases/docs/openapi/bundled.yaml | 24 +- .../components/parameters/page_size.yaml | 3 +- ...id}@api@cases@{caseid}@comments@_find.yaml | 9 +- .../server/client/attachments/get.test.ts | 6 +- .../cases/server/client/attachments/get.ts | 3 - .../client/attachments/validators.test.ts | 52 ----- .../server/client/attachments/validators.ts | 24 +- .../cases/server/client/cases/find.test.ts | 23 +- .../server/client/user_actions/find.test.ts | 41 +++- .../tests/common/cases/find_cases.ts | 79 ++++--- .../tests/common/comments/find_comments.ts | 4 +- .../common/user_actions/find_user_actions.ts | 19 ++ 21 files changed, 505 insertions(+), 342 deletions(-) create mode 100644 x-pack/plugins/cases/common/schema/types.ts delete mode 100644 x-pack/plugins/cases/server/client/attachments/validators.test.ts diff --git a/docs/api-generated/cases/case-apis-passthru.asciidoc b/docs/api-generated/cases/case-apis-passthru.asciidoc index f35863d23eb883..8970186559032f 100644 --- a/docs/api-generated/cases/case-apis-passthru.asciidoc +++ b/docs/api-generated/cases/case-apis-passthru.asciidoc @@ -859,7 +859,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
sortOrder (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
sortOrder (optional)
Query Parameter — Determines the sort order. default: desc
types (optional)
@@ -951,7 +951,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
sortOrder (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
sortOrder (optional)
Query Parameter — Determines the sort order. default: desc
types (optional)
@@ -1278,7 +1278,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
reporters (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
reporters (optional)
Query Parameter — Filters the returned cases by the user name of the reporter. default: null
search (optional)
@@ -1471,7 +1471,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
reporters (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
reporters (optional)
Query Parameter — Filters the returned cases by the user name of the reporter. default: null
search (optional)
@@ -4156,7 +4156,6 @@ Any modifications made to this file will be overwritten.
  • findCaseConnectorsDefaultSpace_200_response_inner_config -
  • findCasesDefaultSpace_200_response -
  • findCasesDefaultSpace_assignees_parameter -
  • -
  • findCasesDefaultSpace_category_parameter -
  • findCasesDefaultSpace_owner_parameter -
  • findCasesDefaultSpace_searchFields_parameter -
  • getCaseCommentDefaultSpace_200_response -
  • @@ -4580,6 +4579,7 @@ Any modifications made to this file will be overwritten.
    settings
    severity (optional)
    tags
    array[String] The words and phrases that help categorize cases. It can be an empty array.
    +
    category (optional)
    String Category for the case. It could be a word or a phrase to categorize the case.
    title
    String A title for the case.

    @@ -4659,12 +4659,6 @@ Any modifications made to this file will be overwritten.
    -

    findCasesDefaultSpace_owner_parameter - Up

    @@ -5056,6 +5050,7 @@ Any modifications made to this file will be overwritten.
    severity (optional)
    status (optional)
    tags (optional)
    array[String] The words and phrases that help categorize cases.
    +
    category (optional)
    String Category for the case. It could be a word or a phrase to categorize the case.
    title (optional)
    String A title for the case.
    version
    String The current version of the case. To determine this value, use the get case or find cases APIs.
    diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index 9778195465432e..ff6b8416f24dd5 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -7,13 +7,17 @@ import * as rt from 'io-ts'; -import { NumberFromString } from '../saved_object'; import { UserRt } from '../user'; import { CommentRt } from './comment'; import { CasesStatusResponseRt, CaseStatusRt } from './status'; import { CaseConnectorRt } from '../connectors/connector'; import { CaseAssigneesRt } from './assignee'; -import { limitedArraySchema, limitedStringSchema, NonEmptyString } from '../../schema'; +import { + limitedArraySchema, + limitedStringSchema, + NonEmptyString, + paginationSchema, +} from '../../schema'; import { MAX_DELETE_IDS_LENGTH, MAX_DESCRIPTION_LENGTH, @@ -25,6 +29,7 @@ import { MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, MAX_BULK_GET_CASES, + MAX_CASES_PER_PAGE, } from '../../constants'; export const AttachmentTotalsRt = rt.strict({ @@ -227,110 +232,113 @@ const CasesFindRequestSearchFieldsRt = rt.keyof({ 'updated_by.profile_uid': null, }); -export const CasesFindRequestRt = rt.exact( - rt.partial({ - /** - * Tags to filter by - */ - tags: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'tags', - min: 0, - max: MAX_TAGS_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * The status of the case (open, closed, in-progress) - */ - status: CaseStatusRt, - /** - * The severity of the case - */ - severity: CaseSeverityRt, - /** - * The uids of the user profiles to filter by - */ - assignees: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'assignees', - min: 0, - max: MAX_ASSIGNEES_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * The reporters to filter by - */ - reporters: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'reporters', - min: 0, - max: MAX_REPORTERS_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * Operator to use for the `search` field - */ - defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]), - /** - * A KQL date. If used all cases created after (gte) the from date will be returned - */ - from: rt.string, - /** - * The page of objects to return - */ - page: NumberFromString, - /** - * The number of objects to include in each page - */ - perPage: NumberFromString, - /** - * An Elasticsearch simple_query_string - */ - search: rt.string, - /** - * The fields to perform the simple_query_string parsed query against - */ - searchFields: rt.union([ - rt.array(CasesFindRequestSearchFieldsRt), - CasesFindRequestSearchFieldsRt, - ]), - /** - * The root fields to perform the simple_query_string parsed query against - */ - rootSearchFields: rt.array(rt.string), - /** - * The field to use for sorting the found objects. - * - */ - sortField: rt.string, - /** - * The order to sort by - */ - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), +export const CasesFindRequestRt = rt.intersection([ + rt.exact( + rt.partial({ + /** + * Tags to filter by + */ + tags: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'tags', + min: 0, + max: MAX_TAGS_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * The status of the case (open, closed, in-progress) + */ + status: CaseStatusRt, + /** + * The severity of the case + */ + severity: CaseSeverityRt, + /** + * The uids of the user profiles to filter by + */ + assignees: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'assignees', + min: 0, + max: MAX_ASSIGNEES_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * The reporters to filter by + */ + reporters: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'reporters', + min: 0, + max: MAX_REPORTERS_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * Operator to use for the `search` field + */ + defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]), + /** + * A KQL date. If used all cases created after (gte) the from date will be returned + */ + from: rt.string, + /** + * The page of objects to return + */ + // page: rt.union([rt.number, NumberFromString]), + /** + * The number of objects to include in each page + */ + // perPage: rt.union([rt.number, NumberFromString]), + /** + * An Elasticsearch simple_query_string + */ + search: rt.string, + /** + * The fields to perform the simple_query_string parsed query against + */ + searchFields: rt.union([ + rt.array(CasesFindRequestSearchFieldsRt), + CasesFindRequestSearchFieldsRt, + ]), + /** + * The root fields to perform the simple_query_string parsed query against + */ + rootSearchFields: rt.array(rt.string), + /** + * The field to use for sorting the found objects. + * + */ + sortField: rt.string, + /** + * The order to sort by + */ + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - /** - * A KQL date. If used all cases created before (lte) the to date will be returned. - */ - to: rt.string, - /** - * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that - * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response - * that the user has access to. - */ + /** + * A KQL date. If used all cases created before (lte) the to date will be returned. + */ + to: rt.string, + /** + * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that + * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response + * that the user has access to. + */ - owner: rt.union([rt.array(rt.string), rt.string]), - /** - * The category of the case. - */ - category: rt.union([rt.array(rt.string), rt.string]), - }) -); + owner: rt.union([rt.array(rt.string), rt.string]), + /** + * The category of the case. + */ + category: rt.union([rt.array(rt.string), rt.string]), + }) + ), + paginationSchema({ maxPerPage: MAX_CASES_PER_PAGE }), +]); export const CasesDeleteRequestRt = limitedArraySchema({ codec: NonEmptyString, @@ -532,8 +540,8 @@ export type Case = rt.TypeOf; export type CaseResolveResponse = rt.TypeOf; export type Cases = rt.TypeOf; export type CasesDeleteRequest = rt.TypeOf; -export type CasesFindRequest = rt.TypeOf; export type CasesByAlertIDRequest = rt.TypeOf; +export type CasesFindRequest = rt.TypeOf; export type CasesFindResponse = rt.TypeOf; export type CasePatchRequest = rt.TypeOf; export type CasesPatchRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/api/cases/comment/index.ts b/x-pack/plugins/cases/common/api/cases/comment/index.ts index 1662631ae2b797..f53e7d88289309 100644 --- a/x-pack/plugins/cases/common/api/cases/comment/index.ts +++ b/x-pack/plugins/cases/common/api/cases/comment/index.ts @@ -6,10 +6,9 @@ */ import * as rt from 'io-ts'; -import { MAX_BULK_GET_ATTACHMENTS } from '../../../constants'; -import { limitedArraySchema } from '../../../schema'; +import { MAX_BULK_GET_ATTACHMENTS, MAX_COMMENTS_PER_PAGE } from '../../../constants'; +import { limitedArraySchema, paginationSchema } from '../../../schema'; import { jsonValueRt } from '../../runtime_types'; -import { NumberFromString } from '../../saved_object'; import { UserRt } from '../../user'; @@ -289,22 +288,17 @@ export const CommentsFindResponseRt = rt.strict({ export const CommentsRt = rt.array(CommentRt); -export const FindCommentsQueryParamsRt = rt.exact( - rt.partial({ - /** - * The page of objects to return - */ - page: rt.union([rt.number, NumberFromString]), - /** - * The number of objects to return for a page - */ - perPage: rt.union([rt.number, NumberFromString]), - /** - * Order to sort the response - */ - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - }) -); +export const FindCommentsQueryParamsRt = rt.intersection([ + rt.exact( + rt.partial({ + /** + * Order to sort the response + */ + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), + }) + ), + paginationSchema({ maxPerPage: MAX_COMMENTS_PER_PAGE }), +]); export const BulkCreateCommentRequestRt = rt.array(CommentRequestRt); diff --git a/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts b/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts index 336c94a7a4fec1..90dc408b5e8862 100644 --- a/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts +++ b/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts @@ -6,9 +6,10 @@ */ import * as rt from 'io-ts'; +import { MAX_USER_ACTIONS_PER_PAGE } from '../../../../constants'; import { UserActionsRt } from '../response'; import { ActionTypes } from '../common'; -import { NumberFromString } from '../../../saved_object'; +import { paginationSchema } from '../../../../schema'; const AdditionalFilterTypes = { action: 'action', @@ -26,14 +27,15 @@ const FindTypeFieldRt = rt.keyof(FindTypes); export type FindTypeField = rt.TypeOf; -export const UserActionFindRequestRt = rt.exact( - rt.partial({ - types: rt.array(FindTypeFieldRt), - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - page: NumberFromString, - perPage: NumberFromString, - }) -); +export const UserActionFindRequestRt = rt.intersection([ + rt.exact( + rt.partial({ + types: rt.array(FindTypeFieldRt), + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), + }) + ), + paginationSchema({ maxPerPage: MAX_USER_ACTIONS_PER_PAGE }), +]); export type UserActionFindRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index b7b49870424956..ffd627c8de865c 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -105,6 +105,8 @@ export const MAX_BULK_GET_ATTACHMENTS = 100 as const; export const MAX_CONCURRENT_SEARCHES = 10 as const; export const MAX_BULK_GET_CASES = 1000 as const; export const MAX_COMMENTS_PER_PAGE = 100 as const; +export const MAX_CASES_PER_PAGE = 100 as const; +export const MAX_USER_ACTIONS_PER_PAGE = 100 as const; export const MAX_CATEGORY_FILTER_LENGTH = 100 as const; export const MAX_TAGS_FILTER_LENGTH = 100 as const; export const MAX_ASSIGNEES_FILTER_LENGTH = 100 as const; diff --git a/x-pack/plugins/cases/common/schema/index.test.ts b/x-pack/plugins/cases/common/schema/index.test.ts index 1a810c8003ff79..008cbc86cae80a 100644 --- a/x-pack/plugins/cases/common/schema/index.test.ts +++ b/x-pack/plugins/cases/common/schema/index.test.ts @@ -7,7 +7,8 @@ import { PathReporter } from 'io-ts/lib/PathReporter'; -import { limitedArraySchema, limitedStringSchema, NonEmptyString } from '.'; +import { limitedArraySchema, limitedStringSchema, NonEmptyString, paginationSchema } from '.'; +import { MAX_DOCS_PER_PAGE } from '../constants'; describe('schema', () => { describe('limitedArraySchema', () => { @@ -19,10 +20,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['']) ) ).toMatchInlineSnapshot(` - Array [ - "string must have length >= 1", - ] - `); + Array [ + "string must have length >= 1", + ] + `); }); it('fails when given an empty array', () => { @@ -31,10 +32,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode([]) ) ).toMatchInlineSnapshot(` - Array [ - "The length of the field foobar is too short. Array must be of length >= 1.", - ] - `); + Array [ + "The length of the field foobar is too short. Array must be of length >= 1.", + ] + `); }); it('fails when given an array larger than the limit of one item', () => { @@ -46,10 +47,10 @@ describe('schema', () => { ]) ) ).toMatchInlineSnapshot(` - Array [ - "The length of the field foobar is too long. Array must be of length <= 1.", - ] - `); + Array [ + "The length of the field foobar is too long. Array must be of length <= 1.", + ] + `); }); it('succeeds when given an array of 1 item with a non-empty string', () => { @@ -58,10 +59,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['a']) ) ).toMatchInlineSnapshot(` - Array [ - "No errors!", - ] - `); + Array [ + "No errors!", + ] + `); }); it('succeeds when given an array of 0 item with a non-empty string when the min is 0', () => { @@ -70,10 +71,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 0, max: 2 }).decode([]) ) ).toMatchInlineSnapshot(` - Array [ - "No errors!", - ] - `); + Array [ + "No errors!", + ] + `); }); }); @@ -84,7 +85,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 2, max: 1 }).decode('a'))) .toMatchInlineSnapshot(` Array [ - "The length of the ${fieldName} is too short. The minimum length is 2.", + "The length of the foo is too short. The minimum length is 2.", ] `); }); @@ -93,7 +94,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(''))) .toMatchInlineSnapshot(` Array [ - "The ${fieldName} field cannot be an empty string.", + "The foo field cannot be an empty string.", ] `); }); @@ -102,7 +103,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(' '))) .toMatchInlineSnapshot(` Array [ - "The ${fieldName} field cannot be an empty string.", + "The foo field cannot be an empty string.", ] `); }); @@ -114,7 +115,7 @@ describe('schema', () => { ) ).toMatchInlineSnapshot(` Array [ - "The length of the ${fieldName} is too long. The maximum length is 5.", + "The length of the foo is too long. The maximum length is 5.", ] `); }); @@ -167,4 +168,117 @@ describe('schema', () => { `); }); }); + + describe('paginationSchema', () => { + it('succeeds when no page or perPage passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 1 }).decode({}))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when only valid page is passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 2 }).decode({ page: 0 }))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when only valid perPage is passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: 1 }))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when page and perPage are passed and valid', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: 1, perPage: 2 })) + ).toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('fails when perPage > maxPerPage', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: 4 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided perPage value is too high. The maximum allowed perPage value is 3.", + ] + `); + }); + + it(`fails when page > ${MAX_DOCS_PER_PAGE}`, () => { + expect( + PathReporter.report( + paginationSchema({ maxPerPage: 3 }).decode({ page: MAX_DOCS_PER_PAGE + 1 }) + ) + ).toMatchInlineSnapshot(` + Array [ + "The number of documents is too high. Paginating through more than 10000 documents is not possible.", + ] + `); + }); + + it(`fails when page * perPage > ${MAX_DOCS_PER_PAGE}`, () => { + expect( + PathReporter.report( + paginationSchema({ maxPerPage: 3 }).decode({ page: MAX_DOCS_PER_PAGE, perPage: 2 }) + ) + ).toMatchInlineSnapshot(` + Array [ + "The number of documents is too high. Paginating through more than 10000 documents is not possible.", + ] + `); + }); + + it('validate params as strings work correctly', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: '1', perPage: '2' })) + ).toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('invalid NumberFromString work correctly', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: 'a', perPage: 'b' })) + ).toMatchInlineSnapshot(` + Array [ + "Invalid value \\"a\\" supplied to : Pagination/page: (number | NumberFromString)/0: number", + "cannot parse to a number", + "Invalid value \\"b\\" supplied to : Pagination/perPage: (number | NumberFromString)/0: number", + "cannot parse to a number", + ] + `); + }); + + it.skip('fails when page number is negative', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: -1 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided page value is too low. The minimum allowed page value is 0.", + ] + `); + }); + + it.skip('fails when perPage number is negative', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: -1 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided perPage value is too low. The minimum allowed perPage value is 0.", + ] + `); + }); + }); }); diff --git a/x-pack/plugins/cases/common/schema/index.ts b/x-pack/plugins/cases/common/schema/index.ts index 9003360ae11b82..764119b06159b3 100644 --- a/x-pack/plugins/cases/common/schema/index.ts +++ b/x-pack/plugins/cases/common/schema/index.ts @@ -8,6 +8,10 @@ import * as rt from 'io-ts'; import { either } from 'fp-ts/lib/Either'; +import { MAX_DOCS_PER_PAGE } from '../constants'; +import type { PartialPaginationType } from './types'; +import { PaginationSchemaRt } from './types'; + export interface LimitedSchemaType { fieldName: string; min: number; @@ -92,3 +96,41 @@ export const limitedArraySchema = ({ }), rt.identity ); + +export const paginationSchema = ({ maxPerPage }: { maxPerPage: number }) => + new rt.PartialType( + 'Pagination', + PaginationSchemaRt.is, + (u, c) => + either.chain(PaginationSchemaRt.validate(u, c), (params) => { + if (params.page == null && params.perPage == null) { + return rt.success(params); + } + + const pageAsNumber = params.page ?? 0; + const perPageAsNumber = params.perPage ?? 0; + + if (perPageAsNumber > maxPerPage) { + return rt.failure( + u, + c, + `The provided perPage value is too high. The maximum allowed perPage value is ${maxPerPage}.` + ); + } + + if (Math.max(pageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS_PER_PAGE) { + return rt.failure( + u, + c, + `The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + } + + return rt.success({ + ...(params.page != null && { page: pageAsNumber }), + ...(params.perPage != null && { perPage: perPageAsNumber }), + }); + }), + rt.identity, + undefined + ); diff --git a/x-pack/plugins/cases/common/schema/types.ts b/x-pack/plugins/cases/common/schema/types.ts new file mode 100644 index 00000000000000..d2ece265042547 --- /dev/null +++ b/x-pack/plugins/cases/common/schema/types.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { NumberFromString } from '../api/saved_object'; + +const PageTypeRt = rt.union([rt.number, NumberFromString]); +type PageNumberType = rt.TypeOf; + +export interface Pagination { + page: PageNumberType; + perPage: PageNumberType; +} + +export const PaginationSchemaRt = rt.exact(rt.partial({ page: PageTypeRt, perPage: PageTypeRt })); +export type PartialPaginationType = Partial; diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 4d6905006c08d1..c504d966cb9d29 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -12,26 +12,18 @@ "url": "https://www.elastic.co/licensing/elastic-license" } }, - "servers": [ - { - "url": "http://localhost:5601", - "description": "local" - } - ], - "security": [ - { - "basicAuth": [] - }, - { - "apiKeyAuth": [] - } - ], "tags": [ { "name": "cases", "description": "Case APIs enable you to open and track issues." } ], + "servers": [ + { + "url": "http://localhost:5601", + "description": "local" + } + ], "paths": { "/api/cases": { "post": { @@ -3415,15 +3407,7 @@ "$ref": "#/components/parameters/page_index" }, { - "name": "perPage", - "in": "query", - "description": "The number of items to return. Limited to 100 items.", - "required": false, - "schema": { - "type": "integer", - "default": 20, - "maximum": 100 - } + "$ref": "#/components/parameters/page_size" }, { "$ref": "#/components/parameters/sort_order" @@ -3916,11 +3900,12 @@ "page_size": { "in": "query", "name": "perPage", - "description": "The number of items to return.", + "description": "The number of items to return. Limited to 100 items.", "required": false, "schema": { "type": "integer", - "default": 20 + "default": 20, + "maximum": 100 } }, "reporters": { @@ -7161,5 +7146,13 @@ ] } } - } + }, + "security": [ + { + "basicAuth": [] + }, + { + "apiKeyAuth": [] + } + ] } \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index 7608a44f3e45e0..d393da4d334a05 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -8,15 +8,12 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license -servers: - - url: http://localhost:5601 - description: local -security: - - basicAuth: [] - - apiKeyAuth: [] tags: - name: cases description: Case APIs enable you to open and track issues. +servers: + - url: http://localhost:5601 + description: local paths: /api/cases: post: @@ -2085,14 +2082,7 @@ paths: parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/page_index' - - name: perPage - in: query - description: The number of items to return. Limited to 100 items. - required: false - schema: - type: integer - default: 20 - maximum: 100 + - $ref: '#/components/parameters/page_size' - $ref: '#/components/parameters/sort_order' - $ref: '#/components/parameters/space_id' responses: @@ -2382,11 +2372,12 @@ components: page_size: in: query name: perPage - description: The number of items to return. + description: The number of items to return. Limited to 100 items. required: false schema: type: integer default: 20 + maximum: 100 reporters: in: query name: reporters @@ -4772,3 +4763,6 @@ components: isPreconfigured: false isDeprecated: false referencedByCount: 0 +security: + - basicAuth: [] + - apiKeyAuth: [] diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml index f59ff5301f9c25..0c78946a39fcff 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml @@ -1,7 +1,8 @@ in: query name: perPage -description: The number of items to return. +description: The number of items to return. Limited to 100 items. required: false schema: type: integer default: 20 + maximum: 100 diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml index bb43f4dcc0b263..b1dd32a6595153 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml @@ -10,14 +10,7 @@ get: parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/page_index.yaml' - - name: perPage - in: query - description: The number of items to return. Limited to 100 items. - required: false - schema: - type: integer - default: 20 - maximum: 100 + - $ref: '../components/parameters/page_size.yaml' - $ref: '../components/parameters/sort_order.yaml' - $ref: '../components/parameters/space_id.yaml' responses: diff --git a/x-pack/plugins/cases/server/client/attachments/get.test.ts b/x-pack/plugins/cases/server/client/attachments/get.test.ts index c2c3423b2388bf..d093793417c7a2 100644 --- a/x-pack/plugins/cases/server/client/attachments/get.test.ts +++ b/x-pack/plugins/cases/server/client/attachments/get.test.ts @@ -20,7 +20,7 @@ describe('get', () => { await expect(() => findComment({ caseID: 'mock-id', findQueryParams: { page: 209, perPage: 100 } }, clientArgs) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to find comments case id: mock-id: Error: The number of documents is too high. Paginating through more than 10,000 documents is not possible."` + `"Failed to find comments case id: mock-id: Error: The number of documents is too high. Paginating through more than 10000 documents is not possible."` ); }); @@ -28,7 +28,7 @@ describe('get', () => { await expect(() => findComment({ caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9001 } }, clientArgs) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to find comments case id: mock-id: Error: The provided perPage value was too high. The maximum allowed perPage value is 100."` + `"Failed to find comments case id: mock-id: Error: The provided perPage value is too high. The maximum allowed perPage value is 100."` ); }); @@ -36,7 +36,7 @@ describe('get', () => { await expect( findComment( // @ts-expect-error: excess attribute - { caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9001, foo: 'bar' } }, + { caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9, foo: 'bar' } }, clientArgs ) ).rejects.toThrowErrorMatchingInlineSnapshot( diff --git a/x-pack/plugins/cases/server/client/attachments/get.ts b/x-pack/plugins/cases/server/client/attachments/get.ts index 62f647434e8904..7e4bc311a65721 100644 --- a/x-pack/plugins/cases/server/client/attachments/get.ts +++ b/x-pack/plugins/cases/server/client/attachments/get.ts @@ -39,7 +39,6 @@ import { createCaseError } from '../../common/error'; import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../../routes/api'; import { buildFilter, combineFilters } from '../utils'; import { Operations } from '../../authorization'; -import { validateFindCommentsPagination } from './validators'; import { decodeOrThrow } from '../../../common/api/runtime_types'; const normalizeAlertResponse = (alerts: Array>): AlertResponse => @@ -124,8 +123,6 @@ export async function find( try { const queryParams = decodeWithExcessOrThrow(FindCommentsQueryParamsRt)(findQueryParams); - validateFindCommentsPagination(queryParams); - const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = await authorization.getAuthorizationFilter(Operations.findComments); diff --git a/x-pack/plugins/cases/server/client/attachments/validators.test.ts b/x-pack/plugins/cases/server/client/attachments/validators.test.ts deleted file mode 100644 index ce6c43a665a10d..00000000000000 --- a/x-pack/plugins/cases/server/client/attachments/validators.test.ts +++ /dev/null @@ -1,52 +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 { validateFindCommentsPagination } from './validators'; -import { MAX_COMMENTS_PER_PAGE } from '../../../common/constants'; - -const ERROR_MSG = - 'The number of documents is too high. Paginating through more than 10,000 documents is not possible.'; - -const ERROR_MSG_PER_PAGE = `The provided perPage value was too high. The maximum allowed perPage value is ${MAX_COMMENTS_PER_PAGE}.`; - -describe('validators', () => { - describe('validateFindCommentsPagination', () => { - it('does not throw if only page is undefined', () => { - expect(() => validateFindCommentsPagination({ perPage: 100 })).not.toThrowError(); - }); - - it('does not throw if only perPage is undefined', () => { - expect(() => validateFindCommentsPagination({ page: 100 })).not.toThrowError(); - }); - - it('does not throw if page and perPage are defined and valid', () => { - expect(() => validateFindCommentsPagination({ page: 2, perPage: 100 })).not.toThrowError(); - }); - - it('returns if page and perPage are undefined', () => { - expect(() => validateFindCommentsPagination({})).not.toThrowError(); - }); - - it('returns if perPage < 0', () => { - expect(() => validateFindCommentsPagination({ perPage: -1 })).not.toThrowError(); - }); - - it('throws if page > 10k', () => { - expect(() => validateFindCommentsPagination({ page: 10001 })).toThrow(ERROR_MSG); - }); - - it('throws if perPage > 100', () => { - expect(() => - validateFindCommentsPagination({ perPage: MAX_COMMENTS_PER_PAGE + 1 }) - ).toThrowError(ERROR_MSG_PER_PAGE); - }); - - it('throws if page * perPage > 10k', () => { - expect(() => validateFindCommentsPagination({ page: 101, perPage: 100 })).toThrow(ERROR_MSG); - }); - }); -}); diff --git a/x-pack/plugins/cases/server/client/attachments/validators.ts b/x-pack/plugins/cases/server/client/attachments/validators.ts index ea38fa71e702a8..4a66d32c31c19c 100644 --- a/x-pack/plugins/cases/server/client/attachments/validators.ts +++ b/x-pack/plugins/cases/server/client/attachments/validators.ts @@ -6,12 +6,11 @@ */ import Boom from '@hapi/boom'; -import { MAX_DOCS_PER_PAGE, MAX_COMMENTS_PER_PAGE } from '../../../common/constants'; import { isCommentRequestTypeExternalReference, isCommentRequestTypePersistableState, } from '../../../common/utils/attachments'; -import type { CommentRequest, FindCommentsQueryParams } from '../../../common/api'; +import type { CommentRequest } from '../../../common/api'; import type { ExternalReferenceAttachmentTypeRegistry } from '../../attachment_framework/external_reference_registry'; import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry'; @@ -42,24 +41,3 @@ export const validateRegisteredAttachments = ({ ); } }; - -export const validateFindCommentsPagination = (params?: FindCommentsQueryParams) => { - if (params?.page == null && params?.perPage == null) { - return; - } - - const pageAsNumber = params.page ?? 0; - const perPageAsNumber = params.perPage ?? 0; - - if (perPageAsNumber > MAX_COMMENTS_PER_PAGE) { - throw Boom.badRequest( - `The provided perPage value was too high. The maximum allowed perPage value is ${MAX_COMMENTS_PER_PAGE}.` - ); - } - - if (Math.max(pageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS_PER_PAGE) { - throw Boom.badRequest( - 'The number of documents is too high. Paginating through more than 10,000 documents is not possible.' - ); - } -}; diff --git a/x-pack/plugins/cases/server/client/cases/find.test.ts b/x-pack/plugins/cases/server/client/cases/find.test.ts index b7d9d9117ad7ed..988aebd33e2af1 100644 --- a/x-pack/plugins/cases/server/client/cases/find.test.ts +++ b/x-pack/plugins/cases/server/client/cases/find.test.ts @@ -10,7 +10,9 @@ import type { Case } from '../../../common/api'; import { MAX_ASSIGNEES_FILTER_LENGTH, + MAX_CASES_PER_PAGE, MAX_CATEGORY_FILTER_LENGTH, + MAX_DOCS_PER_PAGE, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, } from '../../../common/constants'; @@ -81,7 +83,7 @@ describe('find', () => { }); }); - describe('searchFields errors', () => { + describe('errors', () => { const clientArgs = createCasesClientMockArgs(); beforeEach(() => { @@ -149,5 +151,24 @@ describe('find', () => { `Error: The length of the field reporters is too long. Array must be of length <= ${MAX_REPORTERS_FILTER_LENGTH}.` ); }); + + it('Invalid total items results in error', async () => { + const findRequest = createCasesClientMockFindRequest({ page: 209, perPage: 100 }); + + await expect(find(findRequest, clientArgs)).rejects.toThrowError( + `Error: The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + }); + + it('Invalid perPage items results in error', async () => { + const findRequest = createCasesClientMockFindRequest({ + page: 1, + perPage: MAX_CASES_PER_PAGE + 1, + }); + + await expect(find(findRequest, clientArgs)).rejects.toThrowError( + `Error: The provided perPage value is too high. The maximum allowed perPage value is ${MAX_CASES_PER_PAGE}.` + ); + }); }); }); diff --git a/x-pack/plugins/cases/server/client/user_actions/find.test.ts b/x-pack/plugins/cases/server/client/user_actions/find.test.ts index a8df2782117ce7..e0655bc1d2d516 100644 --- a/x-pack/plugins/cases/server/client/user_actions/find.test.ts +++ b/x-pack/plugins/cases/server/client/user_actions/find.test.ts @@ -5,11 +5,12 @@ * 2.0. */ +import { MAX_DOCS_PER_PAGE, MAX_USER_ACTIONS_PER_PAGE } from '../../../common/constants'; import { createMockClient } from '../metrics/test_utils/client'; import { createCasesClientMockArgs } from '../mocks'; import { find } from './find'; -describe('addComment', () => { +describe('findUserActions', () => { const client = createMockClient(); const clientArgs = createCasesClientMockArgs(); @@ -17,10 +18,38 @@ describe('addComment', () => { jest.clearAllMocks(); }); - it('throws with excess fields', async () => { - await expect( - // @ts-expect-error: excess attribute - find({ caseId: 'test-case', params: { foo: 'bar' } }, client, clientArgs) - ).rejects.toThrow('invalid keys "foo"'); + describe('errors', () => { + it('throws with excess fields', async () => { + await expect( + // @ts-expect-error: excess attribute + find({ caseId: 'test-case', params: { foo: 'bar' } }, client, clientArgs) + ).rejects.toThrow('invalid keys "foo"'); + }); + + it(`throws when trying to fetch more than ${MAX_DOCS_PER_PAGE} items`, async () => { + await expect( + find({ caseId: 'test-case', params: { page: 209, perPage: 100 } }, client, clientArgs) + ).rejects.toThrow( + `Error: The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + }); + + it(`throws when perPage > ${MAX_USER_ACTIONS_PER_PAGE}`, async () => { + await expect( + find( + { + caseId: 'test-case', + params: { + page: 1, + perPage: MAX_USER_ACTIONS_PER_PAGE + 1, + }, + }, + client, + clientArgs + ) + ).rejects.toThrow( + `Error: The provided perPage value is too high. The maximum allowed perPage value is ${MAX_USER_ACTIONS_PER_PAGE}.` + ); + }); }); }); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts index 6875bc043a6c56..f4c044415190f7 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts @@ -11,6 +11,7 @@ import expect from '@kbn/expect'; import { CASES_URL, MAX_ASSIGNEES_FILTER_LENGTH, + MAX_CASES_PER_PAGE, MAX_CATEGORY_FILTER_LENGTH, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, @@ -341,39 +342,6 @@ export default ({ getService }: FtrProviderContext): void => { }); }); - describe('errors', () => { - it('unhappy path - 400s when bad query supplied', async () => { - await findCases({ supertest, query: { perPage: true }, expectedHttpCode: 400 }); - }); - - for (const field of ['owner', 'tags', 'severity', 'status']) { - it(`should return a 400 when attempting to query a keyword field [${field}] when using a wildcard query`, async () => { - await findCases({ - supertest, - query: { searchFields: [field], search: 'some search string*' }, - expectedHttpCode: 400, - }); - }); - } - - for (const scenario of [ - { fieldName: 'category', sizeLimit: MAX_CATEGORY_FILTER_LENGTH }, - { fieldName: 'tags', sizeLimit: MAX_TAGS_FILTER_LENGTH }, - { fieldName: 'assignees', sizeLimit: MAX_ASSIGNEES_FILTER_LENGTH }, - { fieldName: 'reporters', sizeLimit: MAX_REPORTERS_FILTER_LENGTH }, - ]) { - it(`unhappy path - 400s when the field ${scenario.fieldName} exceeds the size limit`, async () => { - const value = Array(scenario.sizeLimit + 1).fill('foobar'); - - await findCases({ - supertest, - query: { [scenario.fieldName]: value }, - expectedHttpCode: 400, - }); - }); - } - }); - describe('search and searchField', () => { beforeEach(async () => { await createCase(supertest, postCaseReq); @@ -459,6 +427,51 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + describe('errors', () => { + it('unhappy path - 400s when bad query supplied', async () => { + await findCases({ supertest, query: { perPage: true }, expectedHttpCode: 400 }); + }); + + for (const field of ['owner', 'tags', 'severity', 'status']) { + it(`should return a 400 when attempting to query a keyword field [${field}] when using a wildcard query`, async () => { + await findCases({ + supertest, + query: { searchFields: [field], search: 'some search string*' }, + expectedHttpCode: 400, + }); + }); + } + + for (const scenario of [ + { fieldName: 'category', sizeLimit: MAX_CATEGORY_FILTER_LENGTH }, + { fieldName: 'tags', sizeLimit: MAX_TAGS_FILTER_LENGTH }, + { fieldName: 'assignees', sizeLimit: MAX_ASSIGNEES_FILTER_LENGTH }, + { fieldName: 'reporters', sizeLimit: MAX_REPORTERS_FILTER_LENGTH }, + ]) { + it(`unhappy path - 400s when the field ${scenario.fieldName} exceeds the size limit`, async () => { + const value = Array(scenario.sizeLimit + 1).fill('foobar'); + + await findCases({ + supertest, + query: { [scenario.fieldName]: value }, + expectedHttpCode: 400, + }); + }); + } + + it(`400s when perPage > ${MAX_CASES_PER_PAGE} supplied`, async () => { + await findCases({ + supertest, + query: { perPage: MAX_CASES_PER_PAGE + 1 }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to fetch more than 10,000 documents', async () => { + await findCases({ supertest, query: { page: 209, perPage: 100 }, expectedHttpCode: 400 }); + }); + }); + describe('alerts', () => { const defaultSignalsIndex = '.siem-signals-default-000001'; const signalID = '4679431ee0ba3209b6fcd60a255a696886fe0a7d18f5375de510ff5b68fa6b78'; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts index 761959db29f668..0256a0ac1e562e 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; -import { CASES_URL } from '@kbn/cases-plugin/common/constants'; +import { CASES_URL, MAX_COMMENTS_PER_PAGE } from '@kbn/cases-plugin/common/constants'; import { CommentType } from '@kbn/cases-plugin/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -114,7 +114,7 @@ export default ({ getService }: FtrProviderContext): void => { { name: 'field is wrong type', queryParams: { perPage: true } }, { name: 'field is unknown', queryParams: { foo: 'bar' } }, { name: 'page > 10k', queryParams: { page: 10001 } }, - { name: 'perPage > 100', queryParams: { perPage: 101 } }, + { name: 'perPage > 100', queryParams: { perPage: MAX_COMMENTS_PER_PAGE + 1 } }, { name: 'page * perPage > 10k', queryParams: { page: 2, perPage: 9001 } }, ]) { it(`400s when ${errorScenario.name}`, async () => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts index 28bab81a70bee1..d5340beea28d9a 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts @@ -15,6 +15,7 @@ import { ConnectorTypes, FindTypes, } from '@kbn/cases-plugin/common/api'; +import { MAX_USER_ACTIONS_PER_PAGE } from '@kbn/cases-plugin/common/constants'; import { globalRead, noKibanaPrivileges, @@ -237,6 +238,24 @@ export default ({ getService }: FtrProviderContext): void => { expect(response.userActions[0].type).to.eql('create_case'); expect(response.userActions[0].action).to.eql('create'); }); + + it(`400s when perPage > ${MAX_USER_ACTIONS_PER_PAGE} supplied`, async () => { + await findCaseUserActions({ + caseID: theCase.id, + supertest, + options: { perPage: MAX_USER_ACTIONS_PER_PAGE + 1 }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to fetch more than 10,000 documents', async () => { + await findCaseUserActions({ + caseID: theCase.id, + supertest, + options: { page: 209, perPage: 100 }, + expectedHttpCode: 400, + }); + }); }); describe('filters using the type query parameter', () => { From f2e773d435a50215e952385dc2b86834364a0d1e Mon Sep 17 00:00:00 2001 From: Sergi Massaneda Date: Wed, 5 Jul 2023 13:51:49 +0200 Subject: [PATCH 83/98] [SecuritySolution] Rename security solution plugins (#161153) ## Summary closes: https://github.com/elastic/kibana/issues/159685 - Renaming _x-pack/plugins_: `serverless_security` -> `security_solution_serverless` `ess_security` -> `security_solution_ess` - All the related configurations and types have also been renamed. - i18n translation prefixes updated - relocation of internal `security_solution_serverless` directories to be consistent with `security_solution_ess` ### Eslint I also added the plugins in the `.eslintrc` configuration, defining the same rules as the `security_solution` plugin. All eslint errors have been addressed (mainly _type_ imports errors) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .eslintrc.js | 14 +++ .github/CODEOWNERS | 13 ++- config/serverless.security.yml | 6 +- config/serverless.yml | 2 +- docs/developer/plugin-list.asciidoc | 17 ++-- package.json | 4 +- packages/kbn-optimizer/limits.yml | 4 +- tsconfig.base.json | 8 +- x-pack/.i18nrc.json | 4 +- .../public/__mocks__/services.tsx | 23 ----- .../ess_security/public/get_started/index.tsx | 21 ----- .../ess_security/public/jest.config.js | 25 ----- x-pack/plugins/ess_security/public/plugin.ts | 49 ---------- .../plugins/security_solution/common/index.ts | 2 + .../.gitignore | 0 .../README.md | 4 +- .../common/index.ts | 4 +- .../jest.config.dev.js | 2 +- .../kibana.jsonc | 6 +- .../package.json | 4 +- .../public/breadcrumbs/breadcrumbs.test.ts | 0 .../public/breadcrumbs/breadcrumbs.ts | 12 +-- .../public/breadcrumbs/index.ts | 0 .../public/common/__mocks__/services.mock.ts | 15 +++ .../public/common/__mocks__/services.tsx | 10 ++ .../common/hooks/__mocks__/use_variation.ts | 0 .../public/common/hooks/use_variation.test.ts | 0 .../public/common/hooks/use_variation.ts | 0 .../public/common}/services.tsx | 19 ++-- .../public/get_started/images/cloud1.svg | 0 .../public/get_started/images/endpoint1.svg | 0 .../public/get_started/images/siem1.svg | 0 .../public/get_started/index.tsx | 19 ++++ .../public/get_started/landing_cards.test.tsx | 2 +- .../public/get_started/landing_cards.tsx | 4 +- .../public/get_started/lazy.tsx | 0 .../public/get_started/translations.tsx | 0 .../public/index.ts | 8 +- .../public/jest.config.js | 26 ++++++ .../security_solution_ess/public/plugin.ts | 49 ++++++++++ .../public/types.ts | 10 +- .../server/config.ts | 4 +- .../server/constants.ts | 0 .../server/index.ts | 8 +- .../server/plugin.ts | 26 +++--- .../server/types.ts | 10 +- .../tsconfig.json | 4 +- .../.gitignore | 0 .../security_solution_serverless/README.mdx | 4 + .../common/config.ts | 14 ++- .../common/index.ts | 4 +- .../common/jest.config.js | 28 ++++++ .../common/pli/pli_config.ts | 0 .../common/pli/pli_features.test.ts | 12 +-- .../common/pli/pli_features.ts | 0 .../common/product.ts | 17 ++++ .../jest.config.dev.js | 12 +++ .../kibana.jsonc | 9 +- .../package.json | 2 +- .../common/__mocks__}/services.mock.tsx | 18 ++-- .../public/common/__mocks__/services.tsx | 19 ++++ .../common}/hooks/__mocks__/use_link_props.ts | 0 .../common}/hooks/use_link_props.test.tsx | 27 +++--- .../public/common}/hooks/use_link_props.ts | 2 +- .../public/common}/hooks/use_nav_links.ts | 2 +- .../public/common}/lib/__mocks__/storage.ts | 0 .../public/common}/lib/storage.ts | 0 .../public/common/services.tsx | 10 +- .../get_started/__mocks__/card_step.tsx | 0 .../get_started/__mocks__/product_switch.tsx | 0 .../public}/get_started/__mocks__/storage.ts | 0 .../get_started/__mocks__/toggle_panel.tsx | 0 .../get_started/__mocks__/welcome_panel.tsx | 0 .../public}/get_started/card_item.test.tsx | 5 +- .../public}/get_started/card_item.tsx | 18 ++-- .../public}/get_started/card_step.test.tsx | 5 +- .../public}/get_started/card_step.tsx | 2 +- .../public}/get_started/get_started.test.tsx | 4 +- .../public}/get_started/get_started.tsx | 10 +- .../public}/get_started/helpers.test.ts | 8 +- .../public}/get_started/helpers.ts | 6 +- .../public}/get_started/images/invite.svg | 0 .../public}/get_started/images/progress.svg | 0 .../public}/get_started/images/protect.svg | 0 .../public}/get_started/images/respond.svg | 0 .../public}/get_started/images/step.svg | 0 .../public}/get_started/index.tsx | 20 ++-- .../public}/get_started/lazy.tsx | 4 +- .../get_started/product_switch.test.tsx | 4 +- .../public}/get_started/product_switch.tsx | 6 +- .../public}/get_started/reducer.test.ts | 12 +-- .../public}/get_started/reducer.tsx | 12 +-- .../public}/get_started/sections.tsx | 7 +- .../public}/get_started/storage.test.ts | 10 +- .../public}/get_started/storage.ts | 17 ++-- .../public}/get_started/toggle_panel.test.tsx | 7 +- .../public}/get_started/toggle_panel.tsx | 4 +- .../public}/get_started/translations.ts | 93 ++++++++++--------- .../public}/get_started/types.ts | 11 +-- .../get_started/use_setup_cards.test.tsx | 6 +- .../public}/get_started/use_setup_cards.tsx | 6 +- .../get_started/use_toggle_panel.test.tsx | 7 +- .../public}/get_started/use_toggle_panel.tsx | 8 +- .../get_started/welcome_panel.test.tsx | 2 +- .../public}/get_started/welcome_panel.tsx | 2 +- .../public/index.ts | 11 ++- .../public/jest.config.js | 29 ++++++ .../public}/navigation/breadcrumbs.ts | 2 +- .../public/navigation/index.ts | 29 ++++++ .../public}/navigation/links/index.ts | 0 .../public}/navigation/links/nav_links.ts | 0 .../public}/navigation/links/types.ts | 0 .../navigation/navigation_tree.test.ts | 47 +++++----- .../public}/navigation/navigation_tree.ts | 2 +- .../__mocks__/use_side_nav_items.ts | 0 .../navigation}/side_navigation/categories.ts | 0 .../navigation}/side_navigation/index.tsx | 15 +-- .../navigation}/side_navigation/lazy.tsx | 0 .../side_navigation/side_navigation.test.tsx | 17 ++-- .../side_navigation/side_navigation.tsx | 19 ++-- .../use_side_nav_items.test.tsx | 35 +++---- .../side_navigation}/use_side_nav_items.ts | 6 +- .../public/plugin.ts | 62 +++++++++++++ .../public/types.ts | 10 +- .../hooks/use_product_type_by_pli.ts | 2 +- .../public}/upselling/index.ts | 0 .../pages/generic_upselling_page.tsx | 6 +- .../pages/generic_upselling_section.tsx | 6 +- .../upselling/register_upsellings.test.tsx | 13 +-- .../public}/upselling/register_upsellings.tsx | 6 +- .../server/config.ts | 4 +- .../server/index.ts | 11 ++- .../server/plugin.ts | 24 ++--- .../server/types.ts | 12 +-- .../tsconfig.json | 2 +- x-pack/plugins/serverless_security/README.mdx | 3 - .../serverless_security/common/jest.config.js | 26 ------ .../public/common/jest.config.js | 28 ------ .../public/components/jest.config.js | 28 ------ .../public/hooks/jest.config.js | 28 ------ .../serverless_security/public/jest.config.js | 27 ------ .../public/lib/jest.config.js | 26 ------ .../serverless_security/public/plugin.ts | 71 -------------- .../test_suites/security/cypress/package.json | 2 +- yarn.lock | 16 ++-- 145 files changed, 759 insertions(+), 780 deletions(-) delete mode 100644 x-pack/plugins/ess_security/public/__mocks__/services.tsx delete mode 100644 x-pack/plugins/ess_security/public/get_started/index.tsx delete mode 100644 x-pack/plugins/ess_security/public/jest.config.js delete mode 100644 x-pack/plugins/ess_security/public/plugin.ts rename x-pack/plugins/{ess_security => security_solution_ess}/.gitignore (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/README.md (51%) rename x-pack/plugins/{ess_security => security_solution_ess}/common/index.ts (72%) rename x-pack/plugins/{serverless_security => security_solution_ess}/jest.config.dev.js (78%) rename x-pack/plugins/{ess_security => security_solution_ess}/kibana.jsonc (73%) rename x-pack/plugins/{serverless_security => security_solution_ess}/package.json (85%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/breadcrumbs.test.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/breadcrumbs.ts (67%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/index.ts (100%) create mode 100644 x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts create mode 100644 x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/__mocks__/use_variation.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/use_variation.test.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/use_variation.ts (100%) rename x-pack/plugins/{ess_security/public => security_solution_ess/public/common}/services.tsx (59%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/cloud1.svg (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/endpoint1.svg (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/siem1.svg (100%) create mode 100644 x-pack/plugins/security_solution_ess/public/get_started/index.tsx rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/landing_cards.test.tsx (98%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/landing_cards.tsx (98%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/lazy.tsx (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/translations.tsx (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/index.ts (62%) create mode 100644 x-pack/plugins/security_solution_ess/public/jest.config.js create mode 100644 x-pack/plugins/security_solution_ess/public/plugin.ts rename x-pack/plugins/{ess_security => security_solution_ess}/public/types.ts (69%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/config.ts (80%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/constants.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/index.ts (64%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/plugin.ts (50%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/types.ts (73%) rename x-pack/plugins/{ess_security => security_solution_ess}/tsconfig.json (92%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/.gitignore (100%) create mode 100755 x-pack/plugins/security_solution_serverless/README.mdx rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/config.ts (77%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/index.ts (69%) create mode 100644 x-pack/plugins/security_solution_serverless/common/jest.config.js rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_config.ts (100%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_features.test.ts (80%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_features.ts (100%) create mode 100644 x-pack/plugins/security_solution_serverless/common/product.ts create mode 100644 x-pack/plugins/security_solution_serverless/jest.config.dev.js rename x-pack/plugins/{serverless_security => security_solution_serverless}/kibana.jsonc (74%) rename x-pack/plugins/{ess_security => security_solution_serverless}/package.json (83%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public/common/__mocks__}/services.mock.tsx (75%) create mode 100644 x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/__mocks__/use_link_props.ts (100%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_link_props.test.tsx (82%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_link_props.ts (96%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_nav_links.ts (92%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/lib/__mocks__/storage.ts (100%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/lib/storage.ts (100%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/common/services.tsx (74%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/card_step.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/product_switch.tsx (100%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/__mocks__/storage.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/toggle_panel.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/welcome_panel.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_item.test.tsx (92%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_item.tsx (90%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_step.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_step.tsx (97%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/get_started.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/get_started.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/helpers.test.ts (98%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/helpers.ts (92%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/invite.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/progress.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/protect.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/respond.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/step.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/index.tsx (53%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/lazy.tsx (80%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/product_switch.test.tsx (95%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/product_switch.tsx (91%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/reducer.test.ts (96%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/reducer.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/sections.tsx (95%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/storage.test.ts (95%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/storage.ts (77%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/toggle_panel.test.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/toggle_panel.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/translations.ts (58%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/types.ts (88%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_setup_cards.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_setup_cards.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_toggle_panel.test.tsx (97%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_toggle_panel.tsx (90%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/welcome_panel.test.tsx (96%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/welcome_panel.tsx (98%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/index.ts (58%) create mode 100644 x-pack/plugins/security_solution_serverless/public/jest.config.js rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/breadcrumbs.ts (90%) create mode 100644 x-pack/plugins/security_solution_serverless/public/navigation/index.ts rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/index.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/nav_links.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/types.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/navigation_tree.test.ts (86%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/navigation_tree.ts (98%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/__mocks__/use_side_nav_items.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/categories.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/index.tsx (73%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/lazy.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/side_navigation.test.tsx (85%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/side_navigation.tsx (79%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/use_side_nav_items.test.tsx (82%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/use_side_nav_items.ts (95%) create mode 100644 x-pack/plugins/security_solution_serverless/public/plugin.ts rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/types.ts (78%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/hooks/use_product_type_by_pli.ts (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/index.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/pages/generic_upselling_page.tsx (83%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/pages/generic_upselling_section.tsx (83%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/register_upsellings.test.tsx (81%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/register_upsellings.tsx (91%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/config.ts (83%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/index.ts (60%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/plugin.ts (63%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/types.ts (73%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/tsconfig.json (95%) delete mode 100755 x-pack/plugins/serverless_security/README.mdx delete mode 100644 x-pack/plugins/serverless_security/common/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/common/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/components/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/hooks/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/lib/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/plugin.ts diff --git a/.eslintrc.js b/.eslintrc.js index be80d7550253a7..dacfa2d470e059 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -986,7 +986,11 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{js,mjs,ts,tsx}', 'x-pack/packages/security-solution/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/public/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/public/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/public/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/common/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/common/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/common/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/public/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/common/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/public/**/*.{js,mjs,ts,tsx}', @@ -1014,6 +1018,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{ts,tsx}', 'x-pack/plugins/cases/**/*.{ts,tsx}', ], @@ -1022,6 +1028,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{test,mock,test_helper}.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{test,mock,test_helper}.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/cases/**/*.{test,mock,test_helper}.{ts,tsx}', ], @@ -1036,6 +1044,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{ts,tsx}', 'x-pack/plugins/cases/**/*.{ts,tsx}', ], @@ -1069,6 +1079,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{js,mjs,ts,tsx}', 'x-pack/packages/security-solution/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/**/*.{js,mjs,ts,tsx}', ], @@ -1163,6 +1175,8 @@ module.exports = { { files: [ 'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/**/*.{js,mjs,ts,tsx}', ], rules: { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4248bd86c7d5b5..00dd762c71601d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -359,7 +359,6 @@ packages/kbn-eslint-plugin-eslint @elastic/kibana-operations packages/kbn-eslint-plugin-imports @elastic/kibana-operations packages/kbn-eslint-plugin-telemetry @elastic/actionable-observability x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin @elastic/kibana-security -x-pack/plugins/ess_security @elastic/security-solution src/plugins/event_annotation @elastic/kibana-visualizations x-pack/test/plugin_api_integration/plugins/event_log @elastic/response-ops x-pack/plugins/event_log @elastic/response-ops @@ -580,8 +579,10 @@ examples/search_examples @elastic/kibana-data-discovery x-pack/plugins/searchprofiler @elastic/platform-deployment-management x-pack/test/security_api_integration/packages/helpers @elastic/kibana-core x-pack/plugins/security @elastic/kibana-security +x-pack/plugins/security_solution_ess @elastic/security-solution x-pack/test/cases_api_integration/common/plugins/security_solution @elastic/response-ops x-pack/plugins/security_solution @elastic/security-solution +x-pack/plugins/security_solution_serverless @elastic/security-solution x-pack/packages/security-solution/side_nav @elastic/security-threat-hunting-explore x-pack/packages/security-solution/storybook/config @elastic/security-threat-hunting-explore x-pack/test/security_functional/plugins/test_endpoints @elastic/kibana-security @@ -609,7 +610,6 @@ x-pack/plugins/serverless @elastic/appex-sharedux x-pack/plugins/serverless_observability @elastic/appex-sharedux @elastic/apm-ui packages/serverless/project_switcher @elastic/appex-sharedux x-pack/plugins/serverless_search @elastic/enterprise-search-frontend -x-pack/plugins/serverless_security @elastic/security-solution packages/serverless/storybook/config @elastic/appex-sharedux packages/serverless/types @elastic/appex-sharedux test/plugin_functional/plugins/session_notifications @elastic/kibana-core @@ -824,7 +824,7 @@ packages/kbn-yarn-lock-validator @elastic/kibana-operations #CC# /src/plugins/home/server/services/ @elastic/appex-sharedux #CC# /src/plugins/home/ @elastic/appex-sharedux #CC# /x-pack/plugins/reporting/ @elastic/appex-sharedux -#CC# /x-pack/plugins/serverless_security/ @elastic/appex-sharedux +#CC# /x-pack/plugins/security_solution_serverless/ @elastic/appex-sharedux ### Observability Plugins @@ -1034,6 +1034,11 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/test/api_integration/apis/security_solution @elastic/security-solution #CC# /x-pack/plugins/security_solution/ @elastic/security-solution +# Security Solution Offering plugins +# TODO: assign sub directories to sub teams +/x-pack/plugins/security_solution_ess/ @elastic/security-solution +/x-pack/plugins/security_solution_serverless/ @elastic/security-solution + # Security Solution sub teams ## Security Solution sub teams - Threat Hunting Investigations @@ -1259,6 +1264,8 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience # Security design /x-pack/plugins/endpoint/**/*.scss @elastic/security-design /x-pack/plugins/security_solution/**/*.scss @elastic/security-design +/x-pack/plugins/security_solution_ess/**/*.scss @elastic/security-design +/x-pack/plugins/security_solution_serverless/**/*.scss @elastic/security-design # Logstash #CC# /x-pack/plugins/logstash/ @elastic/logstash diff --git a/config/serverless.security.yml b/config/serverless.security.yml index 5e7cd22a3500b9..bad71f38f24af9 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -6,9 +6,9 @@ xpack.apm.enabled: false xpack.observability.enabled: false xpack.uptime.enabled: false -## Enable the Serverless Security plugin -xpack.serverless.security.enabled: true -xpack.serverless.security.productTypes: +## Enable the Security Solution Serverless plugin +xpack.securitySolutionServerless.enabled: true +xpack.securitySolutionServerless.productTypes: [ { product_line: 'security', product_tier: 'complete' }, { product_line: 'endpoint', product_tier: 'complete' }, diff --git a/config/serverless.yml b/config/serverless.yml index e3ecaaa44a8d3b..897b168340cd52 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -16,7 +16,7 @@ migrations.zdt: runOnRoles: ["ui"] # Ess plugins -xpack.ess.security.enabled: false +xpack.securitySolutionEss.enabled: false # Management team plugins xpack.upgrade_assistant.enabled: false diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 8e001dcd6fdc6f..e29f0fa2ac0ed9 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -538,10 +538,6 @@ security and spaces filtering. |This plugin provides Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. -|{kib-repo}blob/{branch}/x-pack/plugins/ess_security/README.md[essSecurity] -|This plugin contains the ESS/on-prem deployments (non-serverless) customizations for Security Solution. - - |{kib-repo}blob/{branch}/x-pack/plugins/event_log/README.md[eventLog] |The event log plugin provides a persistent history of alerting and action activities. @@ -730,6 +726,15 @@ Kibana. |Welcome to the Kibana Security Solution plugin! This README will go over getting started with development and testing. +|{kib-repo}blob/{branch}/x-pack/plugins/security_solution_ess/README.md[securitySolutionEss] +|This plugin contains the ESS/on-prem deployments (non-serverless) specific logic for Security Solution. + + +|{kib-repo}blob/{branch}/x-pack/plugins/security_solution_serverless/README.mdx[securitySolutionServerless] +|This plugin contains configuration and code used to create a Serverless Security project. +It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. + + |{kib-repo}blob/{branch}/x-pack/plugins/serverless/README.mdx[serverless] | @@ -742,10 +747,6 @@ Kibana. |This plugin contains configuration and code used to create a Serverless Search project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. -|{kib-repo}blob/{branch}/x-pack/plugins/serverless_security/README.mdx[serverlessSecurity] -|This plugin contains configuration and code used to create a Serverless Security project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. - - |{kib-repo}blob/{branch}/x-pack/plugins/session_view/README.md[sessionView] |Session View is meant to provide a visualization into what is going on in a particular Linux environment where the agent is running. It looks likes a terminal emulator; however, it is a tool for introspecting process activity and understanding user and service behaviour in your Linux servers and infrastructure. It is a time-ordered series of process executions displayed in a tree over time. diff --git a/package.json b/package.json index 7658626741ea1d..bed23b10b7cfa7 100644 --- a/package.json +++ b/package.json @@ -393,7 +393,6 @@ "@kbn/es-types": "link:packages/kbn-es-types", "@kbn/es-ui-shared-plugin": "link:src/plugins/es_ui_shared", "@kbn/eso-plugin": "link:x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin", - "@kbn/ess-security": "link:x-pack/plugins/ess_security", "@kbn/event-annotation-plugin": "link:src/plugins/event_annotation", "@kbn/event-log-fixture-plugin": "link:x-pack/test/plugin_api_integration/plugins/event_log", "@kbn/event-log-plugin": "link:x-pack/plugins/event_log", @@ -582,8 +581,10 @@ "@kbn/search-examples-plugin": "link:examples/search_examples", "@kbn/searchprofiler-plugin": "link:x-pack/plugins/searchprofiler", "@kbn/security-plugin": "link:x-pack/plugins/security", + "@kbn/security-solution-ess": "link:x-pack/plugins/security_solution_ess", "@kbn/security-solution-fixtures-plugin": "link:x-pack/test/cases_api_integration/common/plugins/security_solution", "@kbn/security-solution-plugin": "link:x-pack/plugins/security_solution", + "@kbn/security-solution-serverless": "link:x-pack/plugins/security_solution_serverless", "@kbn/security-solution-side-nav": "link:x-pack/packages/security-solution/side_nav", "@kbn/security-solution-storybook-config": "link:x-pack/packages/security-solution/storybook/config", "@kbn/security-test-endpoints-plugin": "link:x-pack/test/security_functional/plugins/test_endpoints", @@ -611,7 +612,6 @@ "@kbn/serverless-observability": "link:x-pack/plugins/serverless_observability", "@kbn/serverless-project-switcher": "link:packages/serverless/project_switcher", "@kbn/serverless-search": "link:x-pack/plugins/serverless_search", - "@kbn/serverless-security": "link:x-pack/plugins/serverless_security", "@kbn/serverless-types": "link:packages/serverless/types", "@kbn/session-notifications-plugin": "link:test/plugin_functional/plugins/session_notifications", "@kbn/session-view-plugin": "link:x-pack/plugins/session_view", diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index c0a9f99b09d4c0..ae6543232fa8f4 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -40,7 +40,6 @@ pageLoadAssetSize: embeddable: 87309 embeddableEnhanced: 22107 enterpriseSearch: 50858 - essSecurity: 16573 esUiShared: 326654 eventAnnotation: 48565 exploratoryView: 74673 @@ -119,10 +118,11 @@ pageLoadAssetSize: searchprofiler: 67080 security: 65433 securitySolution: 66738 + securitySolutionEss: 16573 + securitySolutionServerless: 40000 serverless: 16573 serverlessObservability: 68747 serverlessSearch: 71995 - serverlessSecurity: 40000 sessionView: 77750 share: 71239 snapshotRestore: 79032 diff --git a/tsconfig.base.json b/tsconfig.base.json index 1f70f847156465..8b4c52078c35a1 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -712,8 +712,6 @@ "@kbn/eslint-plugin-telemetry/*": ["packages/kbn-eslint-plugin-telemetry/*"], "@kbn/eso-plugin": ["x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin"], "@kbn/eso-plugin/*": ["x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin/*"], - "@kbn/ess-security": ["x-pack/plugins/ess_security"], - "@kbn/ess-security/*": ["x-pack/plugins/ess_security/*"], "@kbn/event-annotation-plugin": ["src/plugins/event_annotation"], "@kbn/event-annotation-plugin/*": ["src/plugins/event_annotation/*"], "@kbn/event-log-fixture-plugin": ["x-pack/test/plugin_api_integration/plugins/event_log"], @@ -1154,10 +1152,14 @@ "@kbn/security-api-integration-helpers/*": ["x-pack/test/security_api_integration/packages/helpers/*"], "@kbn/security-plugin": ["x-pack/plugins/security"], "@kbn/security-plugin/*": ["x-pack/plugins/security/*"], + "@kbn/security-solution-ess": ["x-pack/plugins/security_solution_ess"], + "@kbn/security-solution-ess/*": ["x-pack/plugins/security_solution_ess/*"], "@kbn/security-solution-fixtures-plugin": ["x-pack/test/cases_api_integration/common/plugins/security_solution"], "@kbn/security-solution-fixtures-plugin/*": ["x-pack/test/cases_api_integration/common/plugins/security_solution/*"], "@kbn/security-solution-plugin": ["x-pack/plugins/security_solution"], "@kbn/security-solution-plugin/*": ["x-pack/plugins/security_solution/*"], + "@kbn/security-solution-serverless": ["x-pack/plugins/security_solution_serverless"], + "@kbn/security-solution-serverless/*": ["x-pack/plugins/security_solution_serverless/*"], "@kbn/security-solution-side-nav": ["x-pack/packages/security-solution/side_nav"], "@kbn/security-solution-side-nav/*": ["x-pack/packages/security-solution/side_nav/*"], "@kbn/security-solution-storybook-config": ["x-pack/packages/security-solution/storybook/config"], @@ -1212,8 +1214,6 @@ "@kbn/serverless-project-switcher/*": ["packages/serverless/project_switcher/*"], "@kbn/serverless-search": ["x-pack/plugins/serverless_search"], "@kbn/serverless-search/*": ["x-pack/plugins/serverless_search/*"], - "@kbn/serverless-security": ["x-pack/plugins/serverless_security"], - "@kbn/serverless-security/*": ["x-pack/plugins/serverless_security/*"], "@kbn/serverless-storybook-config": ["packages/serverless/storybook/config"], "@kbn/serverless-storybook-config/*": ["packages/serverless/storybook/config/*"], "@kbn/serverless-types": ["packages/serverless/types"], diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 2fa461531b4995..6fbc0f935b9400 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -74,9 +74,9 @@ "xpack.serverless": "plugins/serverless", "xpack.serverlessSearch": "plugins/serverless_search", "xpack.serverlessObservability": "plugins/serverless_observability", - "xpack.serverlessSecurity": "plugins/serverless_security", "xpack.securitySolution": "plugins/security_solution", - "xpack.securitySolutionEss": "plugins/ess_security", + "xpack.securitySolutionEss": "plugins/security_solution_ess", + "xpack.securitySolutionServerless": "plugins/security_solution_serverless", "xpack.sessionView": "plugins/session_view", "xpack.snapshotRestore": "plugins/snapshot_restore", "xpack.spaces": "plugins/spaces", diff --git a/x-pack/plugins/ess_security/public/__mocks__/services.tsx b/x-pack/plugins/ess_security/public/__mocks__/services.tsx deleted file mode 100644 index e24367947f89e6..00000000000000 --- a/x-pack/plugins/ess_security/public/__mocks__/services.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -export const KibanaServicesProvider = jest - .fn() - .mockImplementation(({ children }) =>
    {children}
    ); - -export const useKibana = jest.fn().mockReturnValue({ - services: { - http: { - basePath: { - prepend: jest.fn().mockImplementation((path: string) => path), - }, - }, - cloudExperiments: {}, - }, -}); diff --git a/x-pack/plugins/ess_security/public/get_started/index.tsx b/x-pack/plugins/ess_security/public/get_started/index.tsx deleted file mode 100644 index b06d1c0b2c8440..00000000000000 --- a/x-pack/plugins/ess_security/public/get_started/index.tsx +++ /dev/null @@ -1,21 +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 { CoreStart } from '@kbn/core/public'; -import { KibanaServicesProvider } from '../services'; -import { EssSecurityPluginStartDependencies } from '../types'; -import { GetStarted } from './lazy'; - -export const getSecurityGetStartedComponent = - (core: CoreStart, pluginsStart: EssSecurityPluginStartDependencies): React.ComponentType => - () => - ( - - - - ); diff --git a/x-pack/plugins/ess_security/public/jest.config.js b/x-pack/plugins/ess_security/public/jest.config.js deleted file mode 100644 index ffee6062ec59ba..00000000000000 --- a/x-pack/plugins/ess_security/public/jest.config.js +++ /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. - */ -module.exports = { - preset: '@kbn/test', - rootDir: '../../../..', - /** all nested directories have their own Jest config file */ - testMatch: ['/x-pack/plugins/ess_security/public/**/*.test.{js,mjs,ts,tsx}'], - roots: ['/x-pack/plugins/ess_security/public'], - coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/ess_security/public', - coverageReporters: ['text', 'html'], - collectCoverageFrom: [ - '/x-pack/plugins/ess_security/public/**/*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', - '!/x-pack/plugins/ess_security/public/*mock*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.d.ts', - '!/x-pack/plugins/ess_security/public/*.config.ts', - '!/x-pack/plugins/ess_security/public/index.{js,ts,tsx}', - ], -}; diff --git a/x-pack/plugins/ess_security/public/plugin.ts b/x-pack/plugins/ess_security/public/plugin.ts deleted file mode 100644 index 52d75c01f81198..00000000000000 --- a/x-pack/plugins/ess_security/public/plugin.ts +++ /dev/null @@ -1,49 +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 { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; -import { subscribeBreadcrumbs } from './breadcrumbs'; -import { getSecurityGetStartedComponent } from './get_started'; -import { - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies, -} from './types'; - -export class EssSecurityPlugin - implements - Plugin< - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies - > -{ - constructor() {} - - public setup( - _core: CoreSetup, - _setupDeps: EssSecurityPluginSetupDependencies - ): EssSecurityPluginSetup { - return {}; - } - - public start( - core: CoreStart, - startDeps: EssSecurityPluginStartDependencies - ): EssSecurityPluginStart { - const { securitySolution } = startDeps; - - subscribeBreadcrumbs(securitySolution, core); - securitySolution.setGetStartedPage(getSecurityGetStartedComponent(core, startDeps)); - - return {}; - } - - public stop() {} -} diff --git a/x-pack/plugins/security_solution/common/index.ts b/x-pack/plugins/security_solution/common/index.ts index ebe102e29ce2bc..24beb602305dd5 100644 --- a/x-pack/plugins/security_solution/common/index.ts +++ b/x-pack/plugins/security_solution/common/index.ts @@ -13,6 +13,8 @@ export { APP_ID, CASES_FEATURE_ID, SERVER_APP_ID, + APP_PATH, + MANAGE_PATH, ADD_DATA_PATH, SecurityPageName, } from './constants'; diff --git a/x-pack/plugins/ess_security/.gitignore b/x-pack/plugins/security_solution_ess/.gitignore similarity index 100% rename from x-pack/plugins/ess_security/.gitignore rename to x-pack/plugins/security_solution_ess/.gitignore diff --git a/x-pack/plugins/ess_security/README.md b/x-pack/plugins/security_solution_ess/README.md similarity index 51% rename from x-pack/plugins/ess_security/README.md rename to x-pack/plugins/security_solution_ess/README.md index c207b6d2671d4d..de7339892f7508 100755 --- a/x-pack/plugins/ess_security/README.md +++ b/x-pack/plugins/security_solution_ess/README.md @@ -1,3 +1,3 @@ -# essSecurity +# securitySolutionEss -This plugin contains the ESS/on-prem deployments (non-serverless) customizations for Security Solution. \ No newline at end of file +This plugin contains the ESS/on-prem deployments (non-serverless) specific logic for Security Solution. \ No newline at end of file diff --git a/x-pack/plugins/ess_security/common/index.ts b/x-pack/plugins/security_solution_ess/common/index.ts similarity index 72% rename from x-pack/plugins/ess_security/common/index.ts rename to x-pack/plugins/security_solution_ess/common/index.ts index 0b3ef135ddc161..b3541827fd1173 100644 --- a/x-pack/plugins/ess_security/common/index.ts +++ b/x-pack/plugins/security_solution_ess/common/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export const PLUGIN_ID = 'essSecurity'; -export const PLUGIN_NAME = 'essSecurity'; +export const PLUGIN_ID = 'securitySolutionEss'; +export const PLUGIN_NAME = 'securitySolutionEss'; diff --git a/x-pack/plugins/serverless_security/jest.config.dev.js b/x-pack/plugins/security_solution_ess/jest.config.dev.js similarity index 78% rename from x-pack/plugins/serverless_security/jest.config.dev.js rename to x-pack/plugins/security_solution_ess/jest.config.dev.js index f759355f0e0e5a..6ac2f96f95f04b 100644 --- a/x-pack/plugins/serverless_security/jest.config.dev.js +++ b/x-pack/plugins/security_solution_ess/jest.config.dev.js @@ -8,5 +8,5 @@ module.exports = { preset: '@kbn/test', rootDir: '../../../', - projects: ['/x-pack/plugins/serverless_security/public/*/jest.config.js'], + projects: ['/x-pack/plugins/security_solution_ess/public/jest.config.js'], }; diff --git a/x-pack/plugins/ess_security/kibana.jsonc b/x-pack/plugins/security_solution_ess/kibana.jsonc similarity index 73% rename from x-pack/plugins/ess_security/kibana.jsonc rename to x-pack/plugins/security_solution_ess/kibana.jsonc index eee71237a2a7da..cf1edb3f571c5a 100644 --- a/x-pack/plugins/ess_security/kibana.jsonc +++ b/x-pack/plugins/security_solution_ess/kibana.jsonc @@ -1,13 +1,13 @@ { "type": "plugin", - "id": "@kbn/ess-security", + "id": "@kbn/security-solution-ess", "owner": "@elastic/security-solution", "description": "ESS customizations for Security Solution.", "plugin": { - "id": "essSecurity", + "id": "securitySolutionEss", "server": true, "browser": true, - "configPath": ["xpack", "ess", "security"], + "configPath": ["xpack", "securitySolutionEss"], "requiredPlugins": [ "securitySolution" ], diff --git a/x-pack/plugins/serverless_security/package.json b/x-pack/plugins/security_solution_ess/package.json similarity index 85% rename from x-pack/plugins/serverless_security/package.json rename to x-pack/plugins/security_solution_ess/package.json index 0154207c22d6f1..e7ab99edd6a2aa 100644 --- a/x-pack/plugins/serverless_security/package.json +++ b/x-pack/plugins/security_solution_ess/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/serverless-security", + "name": "@kbn/security-solution-ess", "version": "1.0.0", "license": "Elastic License 2.0", "private": true, @@ -8,4 +8,4 @@ "plugin-helpers": "node ../../../scripts/plugin_helpers", "kbn": "node ../../../scripts/kbn" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.test.ts similarity index 100% rename from x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.test.ts diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts similarity index 67% rename from x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts index 8fa8107226f4cc..ca76dc304ab995 100644 --- a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts +++ b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts @@ -5,17 +5,15 @@ * 2.0. */ -import type { PluginStart as SecuritySolutionPluginStart } from '@kbn/security-solution-plugin/public'; -import { ChromeBreadcrumb, CoreStart } from '@kbn/core/public'; +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import type { Services } from '../common/services'; -export const subscribeBreadcrumbs = ( - securitySolution: SecuritySolutionPluginStart, - core: CoreStart -) => { +export const subscribeBreadcrumbs = (services: Services) => { + const { chrome, securitySolution } = services; securitySolution.getBreadcrumbsNav$().subscribe((breadcrumbsNav) => { const breadcrumbs = [...breadcrumbsNav.leading, ...breadcrumbsNav.trailing]; if (breadcrumbs.length > 0) { - core.chrome.setBreadcrumbs(emptyLastBreadcrumbUrl(breadcrumbs)); + chrome.setBreadcrumbs(emptyLastBreadcrumbUrl(breadcrumbs)); } }); }; diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/index.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/index.ts similarity index 100% rename from x-pack/plugins/ess_security/public/breadcrumbs/index.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/index.ts diff --git a/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts new file mode 100644 index 00000000000000..9e9909b45894b2 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.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 { coreMock } from '@kbn/core/public/mocks'; +import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; +import type { Services } from '../services'; + +export const mockServices: Services = { + ...coreMock.createStart(), + securitySolution: securitySolutionMock.createStart(), +}; diff --git a/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx new file mode 100644 index 00000000000000..710a9b378adadf --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockServices } from './services.mock'; + +export const useKibana = jest.fn(() => ({ services: mockServices })); diff --git a/x-pack/plugins/ess_security/public/common/hooks/__mocks__/use_variation.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/__mocks__/use_variation.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/__mocks__/use_variation.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/__mocks__/use_variation.ts diff --git a/x-pack/plugins/ess_security/public/common/hooks/use_variation.test.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.test.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/use_variation.test.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.test.ts diff --git a/x-pack/plugins/ess_security/public/common/hooks/use_variation.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/use_variation.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.ts diff --git a/x-pack/plugins/ess_security/public/services.tsx b/x-pack/plugins/security_solution_ess/public/common/services.tsx similarity index 59% rename from x-pack/plugins/ess_security/public/services.tsx rename to x-pack/plugins/security_solution_ess/public/common/services.tsx index ef8c0db8e792f3..d00fd10350a7d3 100644 --- a/x-pack/plugins/ess_security/public/services.tsx +++ b/x-pack/plugins/security_solution_ess/public/common/services.tsx @@ -5,22 +5,27 @@ * 2.0. */ -import { CoreStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import React from 'react'; import { KibanaContextProvider, useKibana as useKibanaReact, } from '@kbn/kibana-react-plugin/public'; -import type { EssSecurityPluginStartDependencies } from './types'; +import type { SecuritySolutionEssPluginStartDeps } from '../types'; -export type Services = CoreStart & EssSecurityPluginStartDependencies; +export type Services = CoreStart & SecuritySolutionEssPluginStartDeps; export const KibanaServicesProvider: React.FC<{ - core: CoreStart; - pluginsStart: EssSecurityPluginStartDependencies; -}> = ({ core, pluginsStart, children }) => { - const services: Services = { ...core, ...pluginsStart }; + services: Services; +}> = ({ services, children }) => { return {children}; }; export const useKibana = () => useKibanaReact(); + +export const createServices = ( + core: CoreStart, + pluginsStart: SecuritySolutionEssPluginStartDeps +): Services => { + return { ...core, ...pluginsStart }; +}; diff --git a/x-pack/plugins/ess_security/public/get_started/images/cloud1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/cloud1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/cloud1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/cloud1.svg diff --git a/x-pack/plugins/ess_security/public/get_started/images/endpoint1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/endpoint1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/endpoint1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/endpoint1.svg diff --git a/x-pack/plugins/ess_security/public/get_started/images/siem1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/siem1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/siem1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/siem1.svg diff --git a/x-pack/plugins/security_solution_ess/public/get_started/index.tsx b/x-pack/plugins/security_solution_ess/public/get_started/index.tsx new file mode 100644 index 00000000000000..f85d20afe0c07a --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/get_started/index.tsx @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; + +import { KibanaServicesProvider, type Services } from '../common/services'; +import { GetStarted } from './lazy'; + +export const getSecurityGetStartedComponent = (services: Services): React.ComponentType => + function GetStartedComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx similarity index 98% rename from x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx index 05ef9d5cf23f49..153d279a6a06ec 100644 --- a/x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx +++ b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx @@ -12,7 +12,7 @@ import { ADD_DATA_PATH } from '@kbn/security-solution-plugin/common'; import { useVariation } from '../common/hooks/use_variation'; jest.mock('../common/hooks/use_variation'); -jest.mock('../services'); +jest.mock('../common/services'); describe('LandingCards component', () => { beforeEach(() => { diff --git a/x-pack/plugins/ess_security/public/get_started/landing_cards.tsx b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx similarity index 98% rename from x-pack/plugins/ess_security/public/get_started/landing_cards.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx index eacf3c380a2936..91e3c2c5f1fc8c 100644 --- a/x-pack/plugins/ess_security/public/get_started/landing_cards.tsx +++ b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx @@ -12,8 +12,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiPageHeader, - EuiThemeComputed, useEuiTheme, + type EuiThemeComputed, } from '@elastic/eui'; import { css } from '@emotion/react'; import { ADD_DATA_PATH } from '@kbn/security-solution-plugin/common'; @@ -22,7 +22,7 @@ import * as i18n from './translations'; import endpointSvg from './images/endpoint1.svg'; import cloudSvg from './images/cloud1.svg'; import siemSvg from './images/siem1.svg'; -import { useKibana } from '../services'; +import { useKibana } from '../common/services'; const imgUrls = { cloud: cloudSvg, diff --git a/x-pack/plugins/ess_security/public/get_started/lazy.tsx b/x-pack/plugins/security_solution_ess/public/get_started/lazy.tsx similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/lazy.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/lazy.tsx diff --git a/x-pack/plugins/ess_security/public/get_started/translations.tsx b/x-pack/plugins/security_solution_ess/public/get_started/translations.tsx similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/translations.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/translations.tsx diff --git a/x-pack/plugins/ess_security/public/index.ts b/x-pack/plugins/security_solution_ess/public/index.ts similarity index 62% rename from x-pack/plugins/ess_security/public/index.ts rename to x-pack/plugins/security_solution_ess/public/index.ts index 730b776d97b25d..3a26496d3692dc 100644 --- a/x-pack/plugins/ess_security/public/index.ts +++ b/x-pack/plugins/security_solution_ess/public/index.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/public'; -import { EssSecurityPlugin } from './plugin'; +import type { PluginInitializerContext } from '@kbn/core/public'; +import { SecuritySolutionEssPlugin } from './plugin'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(_initializerContext: PluginInitializerContext) { - return new EssSecurityPlugin(); + return new SecuritySolutionEssPlugin(); } -export type { EssSecurityPluginSetup, EssSecurityPluginStart } from './types'; +export type { SecuritySolutionEssPluginSetup, SecuritySolutionEssPluginStart } from './types'; diff --git a/x-pack/plugins/security_solution_ess/public/jest.config.js b/x-pack/plugins/security_solution_ess/public/jest.config.js new file mode 100644 index 00000000000000..fac3d4ceba4204 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/jest.config.js @@ -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. + */ +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + /** all nested directories have their own Jest config file */ + testMatch: ['/x-pack/plugins/security_solution_ess/public/**/*.test.{js,mjs,ts,tsx}'], + roots: ['/x-pack/plugins/security_solution_ess/public'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_ess/public', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_ess/public/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_ess/public/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.d.ts', + '!/x-pack/plugins/security_solution_ess/public/*.config.ts', + '!/x-pack/plugins/security_solution_ess/public/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/security_solution_ess/public/plugin.ts b/x-pack/plugins/security_solution_ess/public/plugin.ts new file mode 100644 index 00000000000000..7224a46f682e46 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/plugin.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { subscribeBreadcrumbs } from './breadcrumbs'; +import { createServices } from './common/services'; +import { getSecurityGetStartedComponent } from './get_started'; +import type { + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps, +} from './types'; + +export class SecuritySolutionEssPlugin + implements + Plugin< + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps + > +{ + public setup( + _core: CoreSetup, + _setupDeps: SecuritySolutionEssPluginSetupDeps + ): SecuritySolutionEssPluginSetup { + return {}; + } + + public start( + core: CoreStart, + startDeps: SecuritySolutionEssPluginStartDeps + ): SecuritySolutionEssPluginStart { + const { securitySolution } = startDeps; + const services = createServices(core, startDeps); + + securitySolution.setGetStartedPage(getSecurityGetStartedComponent(services)); + subscribeBreadcrumbs(services); + + return {}; + } + + public stop() {} +} diff --git a/x-pack/plugins/ess_security/public/types.ts b/x-pack/plugins/security_solution_ess/public/types.ts similarity index 69% rename from x-pack/plugins/ess_security/public/types.ts rename to x-pack/plugins/security_solution_ess/public/types.ts index 3ba22c5f0ff311..2bdeeffebf723f 100644 --- a/x-pack/plugins/ess_security/public/types.ts +++ b/x-pack/plugins/security_solution_ess/public/types.ts @@ -9,19 +9,19 @@ import type { PluginSetup as SecuritySolutionPluginSetup, PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; -import { CloudExperimentsPluginStart } from '@kbn/cloud-experiments-plugin/common'; +import type { CloudExperimentsPluginStart } from '@kbn/cloud-experiments-plugin/common'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginSetup {} +export interface SecuritySolutionEssPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginStart {} +export interface SecuritySolutionEssPluginStart {} -export interface EssSecurityPluginSetupDependencies { +export interface SecuritySolutionEssPluginSetupDeps { securitySolution: SecuritySolutionPluginSetup; } -export interface EssSecurityPluginStartDependencies { +export interface SecuritySolutionEssPluginStartDeps { securitySolution: SecuritySolutionPluginStart; cloudExperiments?: CloudExperimentsPluginStart; } diff --git a/x-pack/plugins/ess_security/server/config.ts b/x-pack/plugins/security_solution_ess/server/config.ts similarity index 80% rename from x-pack/plugins/ess_security/server/config.ts rename to x-pack/plugins/security_solution_ess/server/config.ts index 1d03beec8e2630..48e96989859f5c 100644 --- a/x-pack/plugins/ess_security/server/config.ts +++ b/x-pack/plugins/security_solution_ess/server/config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginConfigDescriptor } from '@kbn/core/server'; +import { schema, type TypeOf } from '@kbn/config-schema'; +import type { PluginConfigDescriptor } from '@kbn/core/server'; export const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), diff --git a/x-pack/plugins/ess_security/server/constants.ts b/x-pack/plugins/security_solution_ess/server/constants.ts similarity index 100% rename from x-pack/plugins/ess_security/server/constants.ts rename to x-pack/plugins/security_solution_ess/server/constants.ts diff --git a/x-pack/plugins/ess_security/server/index.ts b/x-pack/plugins/security_solution_ess/server/index.ts similarity index 64% rename from x-pack/plugins/ess_security/server/index.ts rename to x-pack/plugins/security_solution_ess/server/index.ts index a6dbcaa2893b7c..ebb28fda2cf0a0 100644 --- a/x-pack/plugins/ess_security/server/index.ts +++ b/x-pack/plugins/security_solution_ess/server/index.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/server'; +import type { PluginInitializerContext } from '@kbn/core/server'; -import { EssSecurityPlugin } from './plugin'; +import { SecuritySolutionEssPlugin } from './plugin'; export { config } from './config'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(_initializerContext: PluginInitializerContext) { - return new EssSecurityPlugin(); + return new SecuritySolutionEssPlugin(); } -export type { EssSecurityPluginSetup, EssSecurityPluginStart } from './types'; +export type { SecuritySolutionEssPluginSetup, SecuritySolutionEssPluginStart } from './types'; diff --git a/x-pack/plugins/ess_security/server/plugin.ts b/x-pack/plugins/security_solution_ess/server/plugin.ts similarity index 50% rename from x-pack/plugins/ess_security/server/plugin.ts rename to x-pack/plugins/security_solution_ess/server/plugin.ts index d845216ad722b7..0083fe1314cfd1 100644 --- a/x-pack/plugins/ess_security/server/plugin.ts +++ b/x-pack/plugins/security_solution_ess/server/plugin.ts @@ -5,28 +5,26 @@ * 2.0. */ -import { Plugin, CoreSetup } from '@kbn/core/server'; +import type { Plugin, CoreSetup } from '@kbn/core/server'; import { DEFAULT_APP_FEATURES } from './constants'; -import { - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies, +import type { + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps, } from './types'; -export class EssSecurityPlugin +export class SecuritySolutionEssPlugin implements Plugin< - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps > { - constructor() {} - - public setup(_coreSetup: CoreSetup, pluginsSetup: EssSecurityPluginSetupDependencies) { + public setup(_coreSetup: CoreSetup, pluginsSetup: SecuritySolutionEssPluginSetupDeps) { pluginsSetup.securitySolution.setAppFeatures(DEFAULT_APP_FEATURES); return {}; } diff --git a/x-pack/plugins/ess_security/server/types.ts b/x-pack/plugins/security_solution_ess/server/types.ts similarity index 73% rename from x-pack/plugins/ess_security/server/types.ts rename to x-pack/plugins/security_solution_ess/server/types.ts index d90729e77be4bd..37dd38d76ed77d 100644 --- a/x-pack/plugins/ess_security/server/types.ts +++ b/x-pack/plugins/security_solution_ess/server/types.ts @@ -5,20 +5,20 @@ * 2.0. */ -import { +import type { PluginSetup as SecuritySolutionPluginSetup, PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginSetup {} +export interface SecuritySolutionEssPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginStart {} +export interface SecuritySolutionEssPluginStart {} -export interface EssSecurityPluginSetupDependencies { +export interface SecuritySolutionEssPluginSetupDeps { securitySolution: SecuritySolutionPluginSetup; } -export interface EssSecurityPluginStartDependencies { +export interface SecuritySolutionEssPluginStartDeps { securitySolution: SecuritySolutionPluginStart; } diff --git a/x-pack/plugins/ess_security/tsconfig.json b/x-pack/plugins/security_solution_ess/tsconfig.json similarity index 92% rename from x-pack/plugins/ess_security/tsconfig.json rename to x-pack/plugins/security_solution_ess/tsconfig.json index f28c81c6c59ec3..c37fc777902549 100644 --- a/x-pack/plugins/ess_security/tsconfig.json +++ b/x-pack/plugins/security_solution_ess/tsconfig.json @@ -11,9 +11,7 @@ "server/**/*.ts", "../../../typings/**/*" ], - "exclude": [ - "target/**/*" - ], + "exclude": ["target/**/*"], "kbn_references": [ "@kbn/core", "@kbn/config-schema", diff --git a/x-pack/plugins/serverless_security/.gitignore b/x-pack/plugins/security_solution_serverless/.gitignore similarity index 100% rename from x-pack/plugins/serverless_security/.gitignore rename to x-pack/plugins/security_solution_serverless/.gitignore diff --git a/x-pack/plugins/security_solution_serverless/README.mdx b/x-pack/plugins/security_solution_serverless/README.mdx new file mode 100755 index 00000000000000..a9e20bf8147a40 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/README.mdx @@ -0,0 +1,4 @@ +# Serverless Security project plugin + +This plugin contains configuration and code used to create a Serverless Security project. +It leverages universal configuration and other APIs in the [`serverless`](../serverless/README.mdx) plugin to configure Kibana. \ No newline at end of file diff --git a/x-pack/plugins/serverless_security/common/config.ts b/x-pack/plugins/security_solution_serverless/common/config.ts similarity index 77% rename from x-pack/plugins/serverless_security/common/config.ts rename to x-pack/plugins/security_solution_serverless/common/config.ts index 63b173ff3930e0..cc661da4af1a9e 100644 --- a/x-pack/plugins/serverless_security/common/config.ts +++ b/x-pack/plugins/security_solution_serverless/common/config.ts @@ -5,13 +5,8 @@ * 2.0. */ -import { schema, TypeOf } from '@kbn/config-schema'; - -export enum ProductLine { - security = 'security', - cloud = 'cloud', - endpoint = 'endpoint', -} +import { schema, type TypeOf } from '@kbn/config-schema'; +import { ProductLine, ProductTier } from './product'; export const productLine = schema.oneOf([ schema.literal(ProductLine.security), @@ -21,7 +16,10 @@ export const productLine = schema.oneOf([ export type SecurityProductLine = TypeOf; -export const productTier = schema.oneOf([schema.literal('essentials'), schema.literal('complete')]); +export const productTier = schema.oneOf([ + schema.literal(ProductTier.essentials), + schema.literal(ProductTier.complete), +]); export type SecurityProductTier = TypeOf; export const productType = schema.object({ diff --git a/x-pack/plugins/serverless_security/common/index.ts b/x-pack/plugins/security_solution_serverless/common/index.ts similarity index 69% rename from x-pack/plugins/serverless_security/common/index.ts rename to x-pack/plugins/security_solution_serverless/common/index.ts index 0dc5be6ddf9bbf..e6a263165b00e6 100644 --- a/x-pack/plugins/serverless_security/common/index.ts +++ b/x-pack/plugins/security_solution_serverless/common/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export const PLUGIN_ID = 'serverlessSecurity'; -export const PLUGIN_NAME = 'serverlessSecurity'; +export const PLUGIN_ID = 'securitySolutionServerless'; +export const PLUGIN_NAME = 'securitySolutionServerless'; diff --git a/x-pack/plugins/security_solution_serverless/common/jest.config.js b/x-pack/plugins/security_solution_serverless/common/jest.config.js new file mode 100644 index 00000000000000..01ea1139d6e44c --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/common/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/x-pack/plugins/security_solution_serverless/common'], + testMatch: [ + '/x-pack/plugins/security_solution_serverless/common/**/*.test.{js,mjs,ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_serverless/common', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_serverless/common/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_serverless/common/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.d.ts', + '!/x-pack/plugins/security_solution_serverless/common/*.config.ts', + '!/x-pack/plugins/security_solution_serverless/common/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/serverless_security/common/pli/pli_config.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts similarity index 100% rename from x-pack/plugins/serverless_security/common/pli/pli_config.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts diff --git a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts similarity index 80% rename from x-pack/plugins/serverless_security/common/pli/pli_features.test.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts index c00f8d7fdd9ec1..3358ee69a42508 100644 --- a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts +++ b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts @@ -6,7 +6,7 @@ */ import { getProductAppFeatures } from './pli_features'; import * as pliConfig from './pli_config'; -import { ProductLine } from '../config'; +import { ProductLine, ProductTier } from '../product'; describe('getProductAppFeatures', () => { it('should return the essentials PLIs features', () => { @@ -19,7 +19,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: ProductTier.essentials }, ]); expect(appFeatureKeys).toEqual(['foo']); @@ -35,7 +35,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'complete' }, + { product_line: ProductLine.security, product_tier: ProductTier.complete }, ]); expect(appFeatureKeys).toEqual(['foo', 'baz']); @@ -59,9 +59,9 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'essentials' }, - { product_line: ProductLine.endpoint, product_tier: 'complete' }, - { product_line: ProductLine.cloud, product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: ProductTier.essentials }, + { product_line: ProductLine.endpoint, product_tier: ProductTier.complete }, + { product_line: ProductLine.cloud, product_tier: ProductTier.essentials }, ]); expect(appFeatureKeys).toEqual(['foo', 'bar', 'repeated', 'qux', 'quux', 'corge', 'garply']); diff --git a/x-pack/plugins/serverless_security/common/pli/pli_features.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.ts similarity index 100% rename from x-pack/plugins/serverless_security/common/pli/pli_features.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_features.ts diff --git a/x-pack/plugins/security_solution_serverless/common/product.ts b/x-pack/plugins/security_solution_serverless/common/product.ts new file mode 100644 index 00000000000000..d5095eea316374 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/common/product.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. + */ + +export enum ProductLine { + security = 'security', + endpoint = 'endpoint', + cloud = 'cloud', +} + +export enum ProductTier { + essentials = 'essentials', + complete = 'complete', +} diff --git a/x-pack/plugins/security_solution_serverless/jest.config.dev.js b/x-pack/plugins/security_solution_serverless/jest.config.dev.js new file mode 100644 index 00000000000000..2591fcc775ab03 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/jest.config.dev.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../', + projects: ['/x-pack/plugins/security_solution_serverless/public/jest.config.js'], +}; diff --git a/x-pack/plugins/serverless_security/kibana.jsonc b/x-pack/plugins/security_solution_serverless/kibana.jsonc similarity index 74% rename from x-pack/plugins/serverless_security/kibana.jsonc rename to x-pack/plugins/security_solution_serverless/kibana.jsonc index 306918ed70697f..c9895ac040f345 100644 --- a/x-pack/plugins/serverless_security/kibana.jsonc +++ b/x-pack/plugins/security_solution_serverless/kibana.jsonc @@ -1,16 +1,15 @@ { "type": "plugin", - "id": "@kbn/serverless-security", + "id": "@kbn/security-solution-serverless", "owner": "@elastic/security-solution", "description": "Serverless customizations for security.", "plugin": { - "id": "serverlessSecurity", + "id": "securitySolutionServerless", "server": true, "browser": true, "configPath": [ "xpack", - "serverless", - "security" + "securitySolutionServerless", ], "requiredPlugins": [ "kibanaReact", @@ -21,7 +20,7 @@ "serverless" ], "optionalPlugins": [ - "essSecurity" + "securitySolutionEss" ], "requiredBundles": ["kibanaUtils"] } diff --git a/x-pack/plugins/ess_security/package.json b/x-pack/plugins/security_solution_serverless/package.json similarity index 83% rename from x-pack/plugins/ess_security/package.json rename to x-pack/plugins/security_solution_serverless/package.json index 1ea768291aff05..745afbe7d97c6a 100644 --- a/x-pack/plugins/ess_security/package.json +++ b/x-pack/plugins/security_solution_serverless/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/ess-security", + "name": "@kbn/security-solution-serverless", "version": "1.0.0", "license": "Elastic License 2.0", "private": true, diff --git a/x-pack/plugins/serverless_security/public/common/services.mock.tsx b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx similarity index 75% rename from x-pack/plugins/serverless_security/public/common/services.mock.tsx rename to x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx index a3aba806af18c0..e4b1c777191efb 100644 --- a/x-pack/plugins/serverless_security/public/common/services.mock.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx @@ -13,12 +13,12 @@ import { securityMock } from '@kbn/security-plugin/public/mocks'; import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; import { BehaviorSubject } from 'rxjs'; import { managementPluginMock } from '@kbn/management-plugin/public/mocks'; -import type { ProjectNavigationLink } from './navigation/links'; -import type { Services } from './services'; +import type { ProjectNavigationLink } from '../../navigation/links'; +import type { Services } from '../services'; export const mockProjectNavLinks = jest.fn((): ProjectNavigationLink[] => []); -export const servicesMocks: Services = { +export const mockServices: Services = { ...coreMock.createStart(), serverless: serverlessMock.createStart(), security: securityMock.createStart(), @@ -27,8 +27,10 @@ export const servicesMocks: Services = { management: managementPluginMock.createStartContract(), }; -export const KibanaServicesProvider = React.memo(({ children }) => ( - - {children} - -)); +export const ServicesWrapper = React.memo(function ServicesWrapper({ children }) { + return ( + + {children} + + ); +}); diff --git a/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx new file mode 100644 index 00000000000000..5c6d2f1117c64f --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { I18nProvider } from '@kbn/i18n-react'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { mockServices } from './services.mock'; + +export const KibanaServicesProvider: React.FC = ({ children }) => ( + + {children} + +); + +export const useKibana = jest.fn(() => ({ services: mockServices })); diff --git a/x-pack/plugins/serverless_security/public/hooks/__mocks__/use_link_props.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/__mocks__/use_link_props.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/hooks/__mocks__/use_link_props.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/__mocks__/use_link_props.ts diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx similarity index 82% rename from x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx index 2a20ca97ef8552..5b4d215e331ead 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx @@ -5,15 +5,18 @@ * 2.0. */ -import { MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider, servicesMocks } from '../common/services.mock'; +import { mockServices } from '../__mocks__/services.mock'; import { useGetLinkProps, useLinkProps } from './use_link_props'; -const { getUrlForApp, navigateToUrl: mockNavigateToUrl } = servicesMocks.application; +jest.mock('../services'); const href = '/app/security/test'; + +const { getUrlForApp, navigateToUrl } = mockServices.application; +const mockNavigateToUrl = navigateToUrl as jest.MockedFunction; const mockGetUrlForApp = getUrlForApp as jest.MockedFunction; mockGetUrlForApp.mockReturnValue(href); @@ -23,7 +26,7 @@ describe('useLinkProps', () => { }); it('should return link props', async () => { - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const linkProps = result.current; @@ -37,7 +40,7 @@ describe('useLinkProps', () => { it('should call navigate when clicked normally', async () => { const ev = { preventDefault: jest.fn() } as unknown as MouseEvent; - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const { onClick } = result.current; onClick(ev); @@ -48,7 +51,7 @@ describe('useLinkProps', () => { it('should not call navigate when clicked with modifiers', async () => { const ev = { preventDefault: jest.fn(), ctrlKey: true } as unknown as MouseEvent; - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const { onClick } = result.current; onClick(ev); @@ -58,7 +61,6 @@ describe('useLinkProps', () => { it('should return link props passing deepLink', async () => { const { result } = renderHook(useLinkProps, { - wrapper: KibanaServicesProvider, initialProps: { deepLinkId: SecurityPageName.alerts }, }); @@ -74,7 +76,6 @@ describe('useLinkProps', () => { it('should return link props passing deepLink and path', async () => { const { result } = renderHook(useLinkProps, { - wrapper: KibanaServicesProvider, initialProps: { deepLinkId: SecurityPageName.alerts, path: '/test' }, }); @@ -95,7 +96,7 @@ describe('useGetLinkProps', () => { }); it('should return link props', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({}); @@ -109,7 +110,7 @@ describe('useGetLinkProps', () => { it('should call navigate when clicked normally', async () => { const ev = { preventDefault: jest.fn() } as unknown as MouseEvent; - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const { onClick } = result.current({}); onClick(ev); @@ -120,7 +121,7 @@ describe('useGetLinkProps', () => { it('should not call navigate when clicked with modifiers', async () => { const ev = { preventDefault: jest.fn(), ctrlKey: true } as unknown as MouseEvent; - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const { onClick } = result.current({}); onClick(ev); @@ -129,7 +130,7 @@ describe('useGetLinkProps', () => { }); it('should return link props passing deepLink', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({ deepLinkId: SecurityPageName.alerts }); @@ -142,7 +143,7 @@ describe('useGetLinkProps', () => { }); it('should return link props passing deepLink and path', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({ deepLinkId: SecurityPageName.alerts, path: '/test' }); diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts similarity index 96% rename from x-pack/plugins/serverless_security/public/hooks/use_link_props.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts index 6644afb7fdf011..3a1989dbdc79a0 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts @@ -7,7 +7,7 @@ import { APP_UI_ID, type SecurityPageName } from '@kbn/security-solution-plugin/common'; import { useMemo, useCallback, type MouseEventHandler, type MouseEvent } from 'react'; -import { useKibana, type Services } from '../common/services'; +import { useKibana, type Services } from '../services'; interface LinkProps { onClick: MouseEventHandler; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts similarity index 92% rename from x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts index eaa643603f86df..625e8362238228 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts @@ -7,7 +7,7 @@ import { useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { useKibana } from '../common/services'; +import { useKibana } from '../services'; export const useNavLinks = () => { const { getProjectNavLinks$ } = useKibana().services; diff --git a/x-pack/plugins/serverless_security/public/lib/__mocks__/storage.ts b/x-pack/plugins/security_solution_serverless/public/common/lib/__mocks__/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/__mocks__/storage.ts rename to x-pack/plugins/security_solution_serverless/public/common/lib/__mocks__/storage.ts diff --git a/x-pack/plugins/serverless_security/public/lib/storage.ts b/x-pack/plugins/security_solution_serverless/public/common/lib/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/storage.ts rename to x-pack/plugins/security_solution_serverless/public/common/lib/storage.ts diff --git a/x-pack/plugins/serverless_security/public/common/services.tsx b/x-pack/plugins/security_solution_serverless/public/common/services.tsx similarity index 74% rename from x-pack/plugins/serverless_security/public/common/services.tsx rename to x-pack/plugins/security_solution_serverless/public/common/services.tsx index f3bfe1dbbfa1be..799b2e5913c0a3 100644 --- a/x-pack/plugins/serverless_security/public/common/services.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/services.tsx @@ -5,20 +5,20 @@ * 2.0. */ -import { CoreStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import React from 'react'; import { KibanaContextProvider, useKibana as useKibanaReact, } from '@kbn/kibana-react-plugin/public'; -import type { ServerlessSecurityPluginStartDependencies } from '../types'; -import { getProjectNavLinks$, type ProjectNavLinks } from './navigation/links'; +import type { SecuritySolutionServerlessPluginStartDeps } from '../types'; +import { getProjectNavLinks$, type ProjectNavLinks } from '../navigation/links'; interface InternalServices { getProjectNavLinks$: () => ProjectNavLinks; } -export type Services = CoreStart & ServerlessSecurityPluginStartDependencies & InternalServices; +export type Services = CoreStart & SecuritySolutionServerlessPluginStartDeps & InternalServices; export const KibanaServicesProvider: React.FC<{ services: Services; @@ -30,7 +30,7 @@ export const useKibana = () => useKibanaReact(); export const createServices = ( core: CoreStart, - pluginsStart: ServerlessSecurityPluginStartDependencies + pluginsStart: SecuritySolutionServerlessPluginStartDeps ): Services => { const { securitySolution } = pluginsStart; const projectNavLinks$ = getProjectNavLinks$(securitySolution.getNavLinks$()); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/card_step.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/card_step.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/card_step.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/card_step.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/product_switch.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/product_switch.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/product_switch.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/product_switch.tsx diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/__mocks__/storage.ts b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/get_started/__mocks__/storage.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/storage.ts diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/toggle_panel.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/toggle_panel.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/welcome_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/welcome_panel.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/welcome_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/welcome_panel.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx similarity index 92% rename from x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx index aacd3f520d9cf0..c132eb72bb3595 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx @@ -7,8 +7,9 @@ import React from 'react'; import { render } from '@testing-library/react'; import { CardItem } from './card_item'; -import { CardId, GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; -import { EuiThemeComputed } from '@elastic/eui'; +import type { CardId, StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; +import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('./card_step'); describe('CardItemComponent', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx similarity index 90% rename from x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx index 4abb71354b6412..2dbd6da34d9921 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx @@ -5,18 +5,11 @@ * 2.0. */ -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiPanel, - EuiText, - EuiThemeComputed, - EuiTitle, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPanel, EuiText, EuiTitle } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; import React, { useCallback, useState } from 'react'; import { css } from '@emotion/react'; -import { CardId, SectionId, StepId } from './types'; +import type { CardId, SectionId, StepId } from './types'; import * as i18n from './translations'; import { CardStep } from './card_step'; import { getSections } from './sections'; @@ -102,7 +95,10 @@ const CardItemComponent: React.FC<{ {i18n.STEPS_LEFT(stepsLeft)} )} {timeInMins != null && timeInMins > 0 && ( - • {i18n.STEP_TIME_MIN(timeInMins)} + + {' • '} + {i18n.STEP_TIME_MIN(timeInMins)} + )} diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx index d5fe2433a9faba..9e72370f179e8d 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx @@ -7,7 +7,8 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { CardStep } from './card_step'; -import { GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; +import type { StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; describe('CardStepComponent', () => { const step = { @@ -18,7 +19,7 @@ describe('CardStepComponent', () => { { id: 'badge2', name: 'Badge 2' }, ], description: ['Description line 1', 'Description line 2'], - splitPanel:
    Split Panel
    , + splitPanel:
    {'Split Panel'}
    , }; const onStepClicked = jest.fn(); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx similarity index 97% rename from x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx index 67d683edaac5e4..137895b9bb0782 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx @@ -18,7 +18,7 @@ import { import { css } from '@emotion/react'; import React, { useCallback, useState } from 'react'; -import { CardId, SectionId, Step, StepId } from './types'; +import type { CardId, SectionId, Step, StepId } from './types'; import step from './images/step.svg'; const CardStepComponent: React.FC<{ diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx index ddf0b179852230..51896789c6b31b 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { GetStartedComponent } from './get_started'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; jest.mock('./toggle_panel'); jest.mock('./welcome_panel'); @@ -32,7 +32,7 @@ describe('GetStartedComponent', () => { const { getByText } = render(); const pageTitle = getByText('Welcome'); - const subtitle = getByText('Let’s get started'); + const subtitle = getByText(`Let's get started`); const description = getByText( `Set up your Elastic Security workspace. Use the toggles below to curate a list of tasks that best fits your environment` ); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx index b29ba3b30d6a4f..55550495e6e13e 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx @@ -17,15 +17,17 @@ import { GET_STARTED_PAGE_SUBTITLE, GET_STARTED_PAGE_TITLE, } from './translations'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; import { ProductSwitch } from './product_switch'; import { useTogglePanel } from './use_toggle_panel'; const CONTENT_WIDTH = 1150; -export const GetStartedComponent: React.FC<{ productTypes: SecurityProductTypes }> = ({ - productTypes, -}) => { +export interface GetStartedProps { + productTypes: SecurityProductTypes; +} + +export const GetStartedComponent: React.FC = ({ productTypes }) => { const { euiTheme } = useEuiTheme(); const shadow = useEuiShadow('s'); const { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts similarity index 98% rename from x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts index f5511d4eaa85d8..050d42fbec5730 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts @@ -12,19 +12,15 @@ import { setupCards, updateCard, } from './helpers'; +import type { ActiveCards, Card, CardId, Section, StepId } from './types'; import { - ActiveCards, - Card, - CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, - Section, SectionId, - StepId, } from './types'; import * as sectionsConfigs from './sections'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; const mockSections = jest.spyOn(sectionsConfigs, 'getSections'); describe('getCardTimeInMinutes', () => { it('should calculate the total time in minutes for a card correctly', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts similarity index 92% rename from x-pack/plugins/serverless_security/public/components/get_started/helpers.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts index 0042550a34c4bf..202e00dc1a40a6 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import type { ProductLine } from '../../common/product'; import { getSections } from './sections'; -import { ActiveCard, ActiveCards, Card, CardId, SectionId, StepId } from './types'; +import type { ActiveCard, ActiveCards, Card, CardId, SectionId, StepId } from './types'; export const getCardTimeInMinutes = (card: Card, stepsDone: Set) => card.steps?.reduce( (totalMin, { timeInMinutes, id: stepId }) => - (totalMin += stepsDone.has(stepId) ? 0 : timeInMinutes ?? 0), + totalMin + (stepsDone.has(stepId) ? 0 : timeInMinutes ?? 0), 0 ) ?? 0; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/invite.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/invite.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/invite.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/invite.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/progress.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/progress.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/progress.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/progress.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/protect.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/protect.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/protect.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/protect.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/respond.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/respond.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/respond.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/respond.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/step.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/step.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/step.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/step.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/index.tsx similarity index 53% rename from x-pack/plugins/serverless_security/public/components/get_started/index.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/index.tsx index 0ee8c7a1ce62d4..c457d47a3da308 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/index.tsx @@ -7,18 +7,18 @@ import React from 'react'; -import { KibanaServicesProvider, type Services } from '../../common/services'; -import type { GetStartedComponent } from './types'; +import { KibanaServicesProvider, type Services } from '../common/services'; import { GetStarted } from './lazy'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; export const getSecurityGetStartedComponent = ( services: Services, productTypes: SecurityProductTypes -): GetStartedComponent => { - return () => ( - - - - ); -}; +): React.ComponentType => + function GetStartedComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx similarity index 80% rename from x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx index 3130bbe272f527..99f89ada0055dc 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx @@ -6,13 +6,13 @@ */ import React, { lazy, Suspense } from 'react'; import { EuiLoadingLogo } from '@elastic/eui'; -import { SecurityProductTypes } from '../../../common/config'; +import type { GetStartedProps } from './get_started'; const GetStartedLazy = lazy(() => import('./get_started')); const centerLogoStyle = { display: 'flex', margin: 'auto' }; -export const GetStarted = ({ productTypes }: { productTypes: SecurityProductTypes }) => ( +export const GetStarted = ({ productTypes }: GetStartedProps) => ( }> diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx similarity index 95% rename from x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx index 29c01ddce5376a..5c54c87ccdd218 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { ProductSwitch } from './product_switch'; -import { EuiThemeComputed } from '@elastic/eui'; -import { ProductLine } from '../../../common/config'; +import type { EuiThemeComputed } from '@elastic/eui'; +import { ProductLine } from '../../common/product'; describe('ProductSwitch', () => { const onProductSwitchChangedMock = jest.fn(); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx similarity index 91% rename from x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx index 822e5f3e69ca09..62f58caaacd6d9 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import { EuiPanel, EuiSwitch, EuiText, EuiThemeComputed, EuiTitle } from '@elastic/eui'; +import { EuiPanel, EuiSwitch, EuiText, EuiTitle, type EuiThemeComputed } from '@elastic/eui'; import { css } from '@emotion/react'; import React, { useMemo } from 'react'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; import * as i18n from './translations'; -import { Switch } from './types'; +import type { Switch } from './types'; const switches: Switch[] = [ { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts similarity index 96% rename from x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts index 259923080bfaa9..fe38c68a1a160f 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; import { reducer, getFinishedStepsInitialStates, @@ -13,16 +13,16 @@ import { getActiveCardsInitialStates, } from './reducer'; import { - ActiveCards, - CardId, GetSetUpCardId, GetStartedPageActions, IntroductionSteps, SectionId, - StepId, - ToggleProductAction, - AddFinishedStepAction, GetMoreFromElasticSecurityCardId, + type ActiveCards, + type CardId, + type StepId, + type ToggleProductAction, + type AddFinishedStepAction, } from './types'; describe('reducer', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx index 403bfb85e0a932..f59911aa11808a 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx @@ -5,15 +5,15 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import type { ProductLine } from '../../common/product'; import { setupCards, updateCard } from './helpers'; import { - CardId, + type CardId, + type StepId, + type ToggleProductAction, + type TogglePanelReducer, + type AddFinishedStepAction, GetStartedPageActions, - StepId, - ToggleProductAction, - TogglePanelReducer, - AddFinishedStepAction, } from './types'; export const reducer = ( diff --git a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx similarity index 95% rename from x-pack/plugins/serverless_security/public/components/get_started/sections.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx index 33dbb6f62aa405..11b15264d53eab 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx @@ -5,18 +5,17 @@ * 2.0. */ import React from 'react'; - import { - Section, SectionId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, + type Section, } from './types'; import * as i18n from './translations'; import respond from './images/respond.svg'; import protect from './images/protect.svg'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; export const introductionSteps = [ { @@ -61,7 +60,7 @@ export const sections: Section[] = [ id: GetSetUpCardId.introduction, steps: introductionSteps, timeInMins: introductionSteps.reduce( - (totalMin, { timeInMinutes }) => (totalMin += timeInMinutes), + (totalMin, { timeInMinutes }) => totalMin + timeInMinutes, 0 ), stepsLeft: introductionSteps.length, diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts similarity index 95% rename from x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts index e55c4ef28948b3..a5d013bd5a4e0d 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts @@ -6,12 +6,12 @@ */ import { getStartedStorage } from './storage'; -import { GetSetUpCardId, IntroductionSteps, StepId } from '../../components/get_started/types'; -import { storage } from '../storage'; -import { MockStorage } from '../__mocks__/storage'; -import { ProductLine } from '../../../common/config'; +import { GetSetUpCardId, IntroductionSteps, type StepId } from './types'; +import { storage } from '../common/lib/storage'; +import type { MockStorage } from '../common/lib/__mocks__/storage'; +import { ProductLine } from '../../common/product'; -jest.mock('../storage'); +jest.mock('../common/lib/storage'); describe('useStorage', () => { const mockStorage = storage as unknown as MockStorage; diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts b/x-pack/plugins/security_solution_serverless/public/get_started/storage.ts similarity index 77% rename from x-pack/plugins/serverless_security/public/lib/get_started/storage.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/storage.ts index 1d9c52813c8325..e01a0c7064df84 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/storage.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; -import { CardId, StepId } from '../../components/get_started/types'; -import { storage } from '../storage'; +import type { ProductLine } from '../../common/product'; +import type { CardId, StepId } from './types'; +import { storage } from '../common/lib/storage'; export const ACTIVE_PRODUCTS_STORAGE_KEY = 'ACTIVE_PRODUCTS'; export const FINISHED_STEPS_STORAGE_KEY = 'FINISHED_STEPS'; @@ -15,11 +15,10 @@ export const FINISHED_STEPS_STORAGE_KEY = 'FINISHED_STEPS'; export const getStartedStorage = { getActiveProductsFromStorage: () => { const activeProducts: ProductLine[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY); - return activeProducts ?? new Array(); + return activeProducts ?? []; }, toggleActiveProductsInStorage: (productId: ProductLine) => { - const activeProducts: ProductLine[] = - storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? new Array(); + const activeProducts: ProductLine[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? []; const index = activeProducts.indexOf(productId); if (index < 0) { activeProducts.push(productId); @@ -31,7 +30,7 @@ export const getStartedStorage = { }, getFinishedStepsFromStorageByCardId: (cardId: CardId) => { const finishedSteps = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const card: StepId[] = finishedSteps[cardId] ?? new Array(); + const card: StepId[] = finishedSteps[cardId] ?? []; return card; }, getAllFinishedStepsFromStorage: () => { @@ -41,7 +40,7 @@ export const getStartedStorage = { }, addFinishedStepToStorage: (cardId: CardId, stepId: StepId) => { const finishedSteps: Record = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const card: StepId[] = finishedSteps[cardId] ?? new Array(); + const card: StepId[] = finishedSteps[cardId] ?? []; if (card.indexOf(stepId) < 0) { card.push(stepId); storage.set(FINISHED_STEPS_STORAGE_KEY, { ...finishedSteps, [cardId]: card }); @@ -49,7 +48,7 @@ export const getStartedStorage = { }, removeFinishedStepFromStorage: (cardId: CardId, stepId: StepId) => { const finishedSteps = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const steps: StepId[] = finishedSteps[cardId] ?? new Array(); + const steps: StepId[] = finishedSteps[cardId] ?? []; const index = steps.indexOf(stepId); if (index >= 0) { steps.splice(index, 1); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx index 1a924b70fc45f0..57fead23ad57dc 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx @@ -8,8 +8,9 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TogglePanel } from './toggle_panel'; import { useSetUpCardSections } from './use_setup_cards'; -import { ActiveCards, CardId, GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; -import { ProductLine } from '../../../common/config'; +import type { ActiveCards, CardId, StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; +import { ProductLine } from '../../common/product'; jest.mock('@elastic/eui', () => ({ ...jest.requireActual('@elastic/eui'), @@ -17,8 +18,6 @@ jest.mock('@elastic/eui', () => ({ useEuiShadow: jest.fn(), })); -jest.mock('../../lib/get_started/storage'); - jest.mock('./use_setup_cards', () => ({ useSetUpCardSections: jest.fn(), })); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx index af365b83bd80c3..a110b33f875459 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx @@ -13,8 +13,8 @@ import { css } from '@emotion/react'; import * as i18n from './translations'; import { useSetUpCardSections } from './use_setup_cards'; -import { ActiveCards, CardId, IntroductionSteps, SectionId } from './types'; -import { ProductLine } from '../../../common/config'; +import type { ActiveCards, CardId, IntroductionSteps, SectionId } from './types'; +import type { ProductLine } from '../../common/product'; const TogglePanelComponent: React.FC<{ finishedSteps: Record>; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/translations.ts b/x-pack/plugins/security_solution_serverless/public/get_started/translations.ts similarity index 58% rename from x-pack/plugins/serverless_security/public/components/get_started/translations.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/translations.ts index 0f30a03a2ec0e7..5f30b5b135d1a2 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/translations.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/translations.ts @@ -7,206 +7,215 @@ import { i18n } from '@kbn/i18n'; -export const GET_STARTED_PAGE_TITLE = i18n.translate('xpack.serverlessSecurity.getStarted.title', { - defaultMessage: `Welcome`, -}); +export const GET_STARTED_PAGE_TITLE = i18n.translate( + 'xpack.securitySolutionServerless.getStarted.title', + { + defaultMessage: `Welcome`, + } +); export const GET_STARTED_PAGE_SUBTITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.subTitle', + 'xpack.securitySolutionServerless.getStarted.subTitle', { - defaultMessage: `Let’s get started`, + defaultMessage: `Let's get started`, } ); export const GET_STARTED_PAGE_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.description', + 'xpack.securitySolutionServerless.getStarted.description', { defaultMessage: `Set up your Elastic Security workspace. Use the toggles below to curate a list of tasks that best fits your environment`, } ); export const WELCOME_PANEL_PROJECT_CREATED_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.projectCreated.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.projectCreated.title', { defaultMessage: `Project created`, } ); export const WELCOME_PANEL_PROJECT_CREATED_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.projectCreated.description', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.projectCreated.description', { defaultMessage: `View all projects here.`, } ); export const WELCOME_PANEL_INVITE_YOUR_TEAM_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.inviteYourTeam.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.inviteYourTeam.title', { defaultMessage: 'Invite your team', } ); export const WELCOME_PANEL_INVITE_YOUR_TEAM_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.inviteYourTeam.description', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.inviteYourTeam.description', { defaultMessage: `Boost security through collaboration`, } ); export const WELCOME_PANEL_PROGRESS_TRACKER_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.progressTracker.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.progressTracker.title', { defaultMessage: 'Progress tracker', } ); export const STEP_TIME_MIN = (min: number) => - i18n.translate('xpack.serverlessSecurity.getStarted.togglePanel.progressTracker.stepTimeMin', { - defaultMessage: 'About {min} {min, plural, =1 {min} other {mins}}', - values: { min }, - }); + i18n.translate( + 'xpack.securitySolutionServerless.getStarted.togglePanel.progressTracker.stepTimeMin', + { + defaultMessage: 'About {min} {min, plural, =1 {min} other {mins}}', + values: { min }, + } + ); export const STEPS_LEFT = (steps: number) => - i18n.translate('xpack.serverlessSecurity.getStarted.togglePanel.progressTracker.stepsLeft', { - defaultMessage: '{steps} {steps, plural, =1 {step} other {steps}} left', - values: { steps }, - }); + i18n.translate( + 'xpack.securitySolutionServerless.getStarted.togglePanel.progressTracker.stepsLeft', + { + defaultMessage: '{steps} {steps, plural, =1 {step} other {steps}} left', + values: { steps }, + } + ); export const GET_SET_UP_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.getSetUp.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.getSetUp.title', { defaultMessage: 'Get set up', } ); export const INTRODUCTION_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.introduction.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.introduction.title', { defaultMessage: 'introduction', } ); export const WATCH_OVERVIEW_VIDEO_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.title', { defaultMessage: 'Watch the overview video', } ); export const PRODUCT_BADGE_ANALYTICS = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.analytics', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.analytics', { defaultMessage: 'Analytics', } ); export const PRODUCT_BADGE_CLOUD = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.cloud', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.cloud', { defaultMessage: 'Cloud', } ); export const PRODUCT_BADGE_EDR = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.edr', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.edr', { defaultMessage: 'EDR', } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION1 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description1', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description1', { defaultMessage: `Elastic security keeps your organization’s data safe from attack. `, } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION2 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description2', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description2', { defaultMessage: `Our unified security platform combines Analytics, EDR, and cloud security capabilities into a single SaaS product, providing organizations with a comprehensive solution to protect against a wide range of security threats. With centralized management, real-time threat detection and response, and scalability, our platform can help organizations improve their security posture and reduce the risk of data breaches.`, } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION3 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description3', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description3', { defaultMessage: `Watch the video to explore the core features that allow you to keep your data safe.`, } ); export const WATCH_OVERVIEW_VIDEO_HEADER = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.header', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.header', { defaultMessage: 'Elastic Security', } ); export const BRING_IN_YOUR_DATA_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.bringInYourData.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.bringInYourData.title', { defaultMessage: 'Bring in your data', } ); export const ACTIVATE_AND_CREATE_RULES_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.activateAndCreateRules.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.activateAndCreateRules.title', { defaultMessage: 'Activate and create rules', } ); export const PROTECT_YOUR_ENVIRONMENT_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.protectYourEnvironmentInRealtime.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.protectYourEnvironmentInRealtime.title', { defaultMessage: 'Protect your environment in realtime', } ); export const GET_MORE_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.getMoreFromElasticSecurity.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.getMoreFromElasticSecurity.title', { defaultMessage: 'Get more from Elastic Security', } ); export const MASTER_THE_INVESTIGATION_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.masterTheInvestigationsWorkflow.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.masterTheInvestigationsWorkflow.title', { defaultMessage: 'Master the investigations workflow', } ); export const RESPOND_TO_THREATS_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.respondToThreatsWithAutomation.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.respondToThreatsWithAutomation.title', { defaultMessage: 'Respond to threats with automation', } ); export const OPTIMIZE_YOUR_WORKSPACE_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.optimizeYourWorkspace.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.optimizeYourWorkspace.title', { defaultMessage: 'Optimize your workspace', } ); export const TOGGLE_PANEL_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStartedProductLabel.title', + 'xpack.securitySolutionServerless.getStartedProductLabel.title', { defaultMessage: `Curate your Get Started experience:`, } ); export const ANALYTICS_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.analytics.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.analytics.label', { defaultMessage: 'Analytics', } ); export const CLOUD_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.cloud.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.cloud.label', { defaultMessage: 'Cloud', @@ -214,21 +223,21 @@ export const CLOUD_SWITCH_LABEL = i18n.translate( ); export const ENDPOINT_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.endpoint.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.endpoint.label', { defaultMessage: 'Endpoint', } ); export const TOGGLE_PANEL_EMPTY_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.empty.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.empty.title', { defaultMessage: `Hmm, there doesn't seem to be anything there`, } ); export const TOGGLE_PANEL_EMPTY_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.empty.description', + 'xpack.securitySolutionServerless.getStarted.togglePanel.empty.description', { defaultMessage: `Switch on a toggle to continue your curated "Get Started" experience`, } diff --git a/x-pack/plugins/serverless_security/public/components/get_started/types.ts b/x-pack/plugins/security_solution_serverless/public/get_started/types.ts similarity index 88% rename from x-pack/plugins/serverless_security/public/components/get_started/types.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/types.ts index d19041432569de..69c970f3981324 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/types.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/types.ts @@ -5,14 +5,9 @@ * 2.0. */ -import { EuiIconProps } from '@elastic/eui'; -import React from 'react'; -import { ProductLine } from '../../../common/config'; - -// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -export type GetStartedComponentProps = {}; - -export type GetStartedComponent = (props?: GetStartedComponentProps) => JSX.Element; +import type { EuiIconProps } from '@elastic/eui'; +import type React from 'react'; +import type { ProductLine } from '../../common/product'; export interface HeaderSection { description?: string; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx index 6e726fd9a002f9..efb07e0ade09f4 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx @@ -6,16 +6,14 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { EuiThemeComputed } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; import { useSetUpCardSections } from './use_setup_cards'; +import type { ActiveCards, CardId, StepId } from './types'; import { - ActiveCards, - CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, SectionId, - StepId, } from './types'; const mockEuiTheme: EuiThemeComputed = { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx index bd762042196eec..5c45e75ea4f93a 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import { EuiSpacer, EuiThemeComputed } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; +import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; import React, { useCallback } from 'react'; import { css } from '@emotion/react'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; -import { ActiveCards, CardId, SectionId, StepId } from './types'; +import type { ActiveCards, CardId, SectionId, StepId } from './types'; import { CardItem } from './card_item'; import { getSections } from './sections'; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx similarity index 97% rename from x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx index 62010093959356..41131ec5c54535 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx @@ -6,8 +6,9 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; import { useTogglePanel } from './use_toggle_panel'; -import { getStartedStorage } from '../../lib/get_started/storage'; -import { ProductLine, SecurityProductTypes } from '../../../common/config'; +import { getStartedStorage } from './storage'; +import { ProductLine } from '../../common/product'; +import type { SecurityProductTypes } from '../../common/config'; import { GetMoreFromElasticSecurityCardId, GetSetUpCardId, @@ -15,7 +16,7 @@ import { SectionId, } from './types'; -jest.mock('../../lib/get_started/storage'); +jest.mock('./storage'); describe('useTogglePanel', () => { const productTypes = [ diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx similarity index 90% rename from x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx index f449478572c45d..4ea767ae498ba8 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx @@ -6,15 +6,17 @@ */ import { useCallback, useMemo, useReducer } from 'react'; -import { ProductLine, SecurityProductTypes } from '../../../common/config'; -import { getStartedStorage } from '../../lib/get_started/storage'; +import { ProductLine } from '../../common/product'; +import type { SecurityProductTypes } from '../../common/config'; +import { getStartedStorage } from './storage'; import { getActiveCardsInitialStates, getActiveSectionsInitialStates, getFinishedStepsInitialStates, reducer, } from './reducer'; -import { CardId, GetStartedPageActions, SectionId, StepId, Switch } from './types'; +import type { CardId, SectionId, StepId, Switch } from './types'; +import { GetStartedPageActions } from './types'; export const useTogglePanel = ({ productTypes }: { productTypes: SecurityProductTypes }) => { const { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx similarity index 96% rename from x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx index 27a68f640e1752..a15c70df33428e 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render, RenderResult } from '@testing-library/react'; +import { render, type RenderResult } from '@testing-library/react'; import { WelcomePanel } from './welcome_panel'; jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx similarity index 98% rename from x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx index c6e25a085998dc..79eecfbac7a335 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx @@ -10,7 +10,7 @@ import { css } from '@emotion/react'; import React from 'react'; import progress from './images/progress.svg'; import invite from './images/invite.svg'; -import { HeaderSection } from './types'; +import type { HeaderSection } from './types'; import { WELCOME_PANEL_PROJECT_CREATED_TITLE, WELCOME_PANEL_PROJECT_CREATED_DESCRIPTION, diff --git a/x-pack/plugins/serverless_security/public/index.ts b/x-pack/plugins/security_solution_serverless/public/index.ts similarity index 58% rename from x-pack/plugins/serverless_security/public/index.ts rename to x-pack/plugins/security_solution_serverless/public/index.ts index 1a6466261b1bd0..20c00e6985332f 100644 --- a/x-pack/plugins/serverless_security/public/index.ts +++ b/x-pack/plugins/security_solution_serverless/public/index.ts @@ -5,13 +5,16 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/public'; -import { ServerlessSecurityPlugin } from './plugin'; +import type { PluginInitializerContext } from '@kbn/core/public'; +import { SecuritySolutionServerlessPlugin } from './plugin'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(initializerContext: PluginInitializerContext) { - return new ServerlessSecurityPlugin(initializerContext); + return new SecuritySolutionServerlessPlugin(initializerContext); } -export type { ServerlessSecurityPluginSetup, ServerlessSecurityPluginStart } from './types'; +export type { + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, +} from './types'; diff --git a/x-pack/plugins/security_solution_serverless/public/jest.config.js b/x-pack/plugins/security_solution_serverless/public/jest.config.js new file mode 100644 index 00000000000000..cf3ad9340c14d8 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + /** all nested directories have their own Jest config file */ + testMatch: [ + '/x-pack/plugins/security_solution_serverless/public/**/*.test.{js,mjs,ts,tsx}', + ], + roots: ['/x-pack/plugins/security_solution_serverless/public'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_serverless/public', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_serverless/public/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_serverless/public/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.d.ts', + '!/x-pack/plugins/security_solution_serverless/public/*.config.ts', + '!/x-pack/plugins/security_solution_serverless/public/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts b/x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts similarity index 90% rename from x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts index d4e9d13b37698c..195a1a070abcf2 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { Services } from '../services'; +import type { Services } from '../common/services'; export const subscribeBreadcrumbs = (services: Services) => { const { securitySolution, serverless } = services; diff --git a/x-pack/plugins/security_solution_serverless/public/navigation/index.ts b/x-pack/plugins/security_solution_serverless/public/navigation/index.ts new file mode 100644 index 00000000000000..226c20997ef5e8 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/navigation/index.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 { APP_PATH, MANAGE_PATH } from '@kbn/security-solution-plugin/common'; +import type { Services } from '../common/services'; +import { subscribeBreadcrumbs } from './breadcrumbs'; +import { subscribeNavigationTree } from './navigation_tree'; +import { getSecuritySideNavComponent } from './side_navigation'; + +const SECURITY_MANAGE_PATH = `${APP_PATH}${MANAGE_PATH}`; + +/** + * Configures the serverless project navigation + */ +export const setServerlessNavigation = (services: Services) => { + const { serverless, securitySolution, management } = services; + securitySolution.setIsSidebarEnabled(false); + management.setLandingPageRedirect(SECURITY_MANAGE_PATH); + + serverless.setProjectHome(APP_PATH); + serverless.setSideNavComponent(getSecuritySideNavComponent(services)); + + subscribeNavigationTree(services); + subscribeBreadcrumbs(services); +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/index.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/index.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/index.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/index.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/nav_links.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/nav_links.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/types.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/types.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/types.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/types.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts similarity index 86% rename from x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts index 91d020c3327021..b1e619a30fc135 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts @@ -6,10 +6,9 @@ */ import type { ChromeNavLink } from '@kbn/core/public'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { servicesMocks } from '../services.mock'; import { subscribeNavigationTree } from './navigation_tree'; import { BehaviorSubject } from 'rxjs'; -import { mockProjectNavLinks } from '../services.mock'; +import { mockServices, mockProjectNavLinks } from '../common/__mocks__/services.mock'; import type { ProjectNavigationLink } from './links'; const mockChromeNavLinks = jest.fn((): ChromeNavLink[] => []); @@ -21,12 +20,12 @@ const mockChromeNavLinksHas = jest.fn((id: string): boolean => mockChromeNavLinks().some((link) => link.id === id) ); -const mockServices = { - ...servicesMocks, +const testServices = { + ...mockServices, chrome: { - ...servicesMocks.chrome, + ...mockServices.chrome, navLinks: { - ...servicesMocks.chrome.navLinks, + ...mockServices.chrome.navLinks, get: mockChromeNavLinksGet, has: mockChromeNavLinksHas, getNavLinks$: mockChromeGetNavLinks, @@ -66,10 +65,10 @@ describe('subscribeNavigationTree', () => { it('should call serverless setNavigation', async () => { mockProjectNavLinks.mockReturnValueOnce([link1]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -98,10 +97,10 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLinkExpected]); mockProjectNavLinks.mockReturnValueOnce([externalLink]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -124,10 +123,10 @@ describe('subscribeNavigationTree', () => { it('should call serverless setNavigation with nested children', async () => { mockProjectNavLinks.mockReturnValueOnce([{ ...link1, links: [link2] }]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -158,20 +157,20 @@ describe('subscribeNavigationTree', () => { it('should not call serverless setNavigation when projectNavLinks is empty', async () => { mockProjectNavLinks.mockReturnValueOnce([]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); }); it('should not call serverless setNavigation when chrome navLinks is empty', async () => { mockChromeNavLinks.mockReturnValue([]); mockProjectNavLinks.mockReturnValueOnce([link1]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); }); it('should debounce updates', async () => { @@ -185,18 +184,18 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLink1, chromeNavLink2, chromeNavLinkExpected]); mockProjectNavLinks.mockReturnValueOnce([linkExpected]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); chromeGetNavLinks$.next([chromeNavLink1]); chromeGetNavLinks$.next([chromeNavLink2]); chromeGetNavLinks$.next([chromeNavLinkExpected]); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledTimes(1); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledTimes(1); + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -220,10 +219,10 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLink2]); mockProjectNavLinks.mockReturnValueOnce([link1, link2]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -254,10 +253,10 @@ describe('subscribeNavigationTree', () => { link2, ]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts similarity index 98% rename from x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts index 70464c0c53f5d8..82555ae54332f2 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts @@ -8,7 +8,7 @@ import type { ChromeNavLinks, ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; import { combineLatest, skipWhile, debounceTime } from 'rxjs'; -import type { Services } from '../services'; +import type { Services } from '../common/services'; import type { ProjectNavigationLink } from './links/types'; // We need to hide breadcrumbs for some pages (tabs) because they appear duplicated. diff --git a/x-pack/plugins/serverless_security/public/hooks/__mocks__/use_side_nav_items.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/__mocks__/use_side_nav_items.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/hooks/__mocks__/use_side_nav_items.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/__mocks__/use_side_nav_items.ts diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/categories.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/categories.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/components/side_navigation/categories.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/categories.ts diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx similarity index 73% rename from x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx index 399d6ecab13deb..c749131300b5d9 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx @@ -10,10 +10,11 @@ import type { SideNavComponent } from '@kbn/core-chrome-browser/src/project_navi import { SecuritySideNavigation } from './lazy'; import { KibanaServicesProvider, type Services } from '../../common/services'; -export const getSecuritySideNavComponent = (services: Services): SideNavComponent => { - return () => ( - - - - ); -}; +export const getSecuritySideNavComponent = (services: Services): SideNavComponent => + function SecuritySideNavComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/lazy.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/lazy.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/side_navigation/lazy.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/lazy.tsx diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx similarity index 85% rename from x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx index eef0ccb8da671a..1df7e2ca3008f4 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx @@ -8,11 +8,12 @@ import React from 'react'; import { render } from '@testing-library/react'; import { SecuritySideNavigation } from './side_navigation'; -import { useSideNavItems, useSideNavSelectedId } from '../../hooks/use_side_nav_items'; +import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider } from '../../common/services.mock'; +import { ServicesWrapper } from '../../common/__mocks__/services.mock'; + +jest.mock('./use_side_nav_items'); -jest.mock('../../hooks/use_side_nav_items'); const mockUseSideNavItems = useSideNavItems as jest.Mock; const mockUseSideNavSelectedId = useSideNavSelectedId as jest.Mock; @@ -54,22 +55,22 @@ describe('SecuritySideNavigation', () => { it('should render loading when not items received', () => { mockUseSideNavItems.mockReturnValueOnce([]); - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('sideNavLoader')).toBeInTheDocument(); }); it('should not render loading when items received', () => { - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('sideNavLoader')).not.toBeInTheDocument(); }); it('should render the SideNav when items received', () => { - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('solutionSideNav')).toBeInTheDocument(); }); it('should pass item props to the SolutionSideNav component', () => { - render(, { wrapper: KibanaServicesProvider }); + render(, { wrapper: ServicesWrapper }); expect(mockSolutionSideNav).toHaveBeenCalledWith( expect.objectContaining({ @@ -79,7 +80,7 @@ describe('SecuritySideNavigation', () => { }); it('should selectedId the SolutionSideNav component', () => { - render(, { wrapper: KibanaServicesProvider }); + render(, { wrapper: ServicesWrapper }); expect(mockSolutionSideNav).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx similarity index 79% rename from x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx index b38ff02dd34177..5ba20e26cac214 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { EuiLoadingSpinner, useEuiTheme } from '@elastic/eui'; import { SolutionNav } from '@kbn/shared-ux-page-solution-nav'; import { SolutionSideNav } from '@kbn/security-solution-side-nav'; -import { useSideNavItems, useSideNavSelectedId } from '../../hooks/use_side_nav_items'; +import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { CATEGORIES } from './categories'; export const SecuritySideNavigation: React.FC = () => { @@ -26,19 +26,18 @@ export const SecuritySideNavigation: React.FC = () => { canBeCollapsed={false} name={'Security'} icon={'logoSecurity'} - children={ - - } closeFlyoutButtonPosition={'inside'} headingProps={{ 'data-test-subj': 'securitySolutionNavHeading', }} - /> + > + + ); }; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx similarity index 82% rename from x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx index 22c0e7118ec761..2145961e36aa5d 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx @@ -8,13 +8,10 @@ import { renderHook } from '@testing-library/react-hooks'; import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { - KibanaServicesProvider, - servicesMocks, - mockProjectNavLinks, -} from '../common/services.mock'; +import { mockServices, mockProjectNavLinks } from '../../common/__mocks__/services.mock'; -jest.mock('./use_link_props'); +jest.mock('../../common/hooks/use_link_props'); +jest.mock('../../common/services'); const mockUseLocation = jest.fn(() => ({ pathname: '/' })); jest.mock('react-router-dom', () => ({ @@ -28,12 +25,11 @@ describe('useSideNavItems', () => { }); it('should return empty items', async () => { - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); - + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([]); - expect(servicesMocks.getProjectNavLinks$).toHaveBeenCalledTimes(1); + expect(mockServices.getProjectNavLinks$).toHaveBeenCalledTimes(1); }); it('should return main items', async () => { @@ -41,7 +37,7 @@ describe('useSideNavItems', () => { { id: SecurityPageName.alerts, title: 'Alerts' }, { id: SecurityPageName.case, title: 'Cases' }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([ @@ -70,7 +66,7 @@ describe('useSideNavItems', () => { links: [{ id: SecurityPageName.detectionAndResponse, title: 'Detection & Response' }], }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([ @@ -100,7 +96,7 @@ describe('useSideNavItems', () => { sideNavIcon: 'launch', }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; @@ -139,10 +135,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(''); @@ -165,10 +158,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(SecurityPageName.alerts); @@ -193,10 +183,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(SecurityPageName.dashboards); diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts similarity index 95% rename from x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts index 7ec68683eb2232..779dd86764d744 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts @@ -12,9 +12,9 @@ import { SolutionSideNavItemPosition, type SolutionSideNavItem, } from '@kbn/security-solution-side-nav'; -import { useKibana } from '../common/services'; -import { type GetLinkProps, useGetLinkProps } from './use_link_props'; -import { useNavLinks } from './use_nav_links'; +import { useKibana } from '../../common/services'; +import { type GetLinkProps, useGetLinkProps } from '../../common/hooks/use_link_props'; +import { useNavLinks } from '../../common/hooks/use_nav_links'; type NavigationLink = ReturnType[number]; diff --git a/x-pack/plugins/security_solution_serverless/public/plugin.ts b/x-pack/plugins/security_solution_serverless/public/plugin.ts new file mode 100644 index 00000000000000..307a438c6e9c3a --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/plugin.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; + +import { getSecurityGetStartedComponent } from './get_started'; +import type { + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, + SecuritySolutionServerlessPluginSetupDeps, + SecuritySolutionServerlessPluginStartDeps, + ServerlessSecurityPublicConfig, +} from './types'; +import { registerUpsellings } from './upselling'; +import { createServices } from './common/services'; +import { setServerlessNavigation } from './navigation'; + +export class SecuritySolutionServerlessPlugin + implements + Plugin< + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, + SecuritySolutionServerlessPluginSetupDeps, + SecuritySolutionServerlessPluginStartDeps + > +{ + private config: ServerlessSecurityPublicConfig; + + constructor(private readonly initializerContext: PluginInitializerContext) { + this.config = this.initializerContext.config.get(); + } + + public setup( + _core: CoreSetup, + setupDeps: SecuritySolutionServerlessPluginSetupDeps + ): SecuritySolutionServerlessPluginSetup { + registerUpsellings(setupDeps.securitySolution.upselling, this.config.productTypes); + return {}; + } + + public start( + core: CoreStart, + startDeps: SecuritySolutionServerlessPluginStartDeps + ): SecuritySolutionServerlessPluginStart { + const { securitySolution } = startDeps; + const { productTypes } = this.config; + + const services = createServices(core, startDeps); + + securitySolution.setGetStartedPage(getSecurityGetStartedComponent(services, productTypes)); + + setServerlessNavigation(services); + + return {}; + } + + public stop() {} +} diff --git a/x-pack/plugins/serverless_security/public/types.ts b/x-pack/plugins/security_solution_serverless/public/types.ts similarity index 78% rename from x-pack/plugins/serverless_security/public/types.ts rename to x-pack/plugins/security_solution_serverless/public/types.ts index 73052810127ad8..e65813aa68f6c8 100644 --- a/x-pack/plugins/serverless_security/public/types.ts +++ b/x-pack/plugins/security_solution_serverless/public/types.ts @@ -11,23 +11,23 @@ import type { PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public'; -import { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; +import type { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; import type { SecurityProductTypes } from '../common/config'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ServerlessSecurityPluginSetup {} +export interface SecuritySolutionServerlessPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ServerlessSecurityPluginStart {} +export interface SecuritySolutionServerlessPluginStart {} -export interface ServerlessSecurityPluginSetupDependencies { +export interface SecuritySolutionServerlessPluginSetupDeps { security: SecurityPluginSetup; securitySolution: SecuritySolutionPluginSetup; serverless: ServerlessPluginSetup; management: ManagementSetup; } -export interface ServerlessSecurityPluginStartDependencies { +export interface SecuritySolutionServerlessPluginStartDeps { security: SecurityPluginStart; securitySolution: SecuritySolutionPluginStart; serverless: ServerlessPluginStart; diff --git a/x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts b/x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts similarity index 93% rename from x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts rename to x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts index f1486469247cb8..df4a97e3b0347f 100644 --- a/x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts +++ b/x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts @@ -6,7 +6,7 @@ */ import type { AppFeatureKey } from '@kbn/security-solution-plugin/common'; -import { PLI_APP_FEATURES } from '../../../../common/pli/pli_config'; +import { PLI_APP_FEATURES } from '../../../common/pli/pli_config'; export const useProductTypeByPLI = (requiredPLI: AppFeatureKey): string | null => { if (PLI_APP_FEATURES.security.essentials.includes(requiredPLI)) { diff --git a/x-pack/plugins/serverless_security/public/components/upselling/index.ts b/x-pack/plugins/security_solution_serverless/public/upselling/index.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/components/upselling/index.ts rename to x-pack/plugins/security_solution_serverless/public/upselling/index.ts diff --git a/x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx b/x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx similarity index 83% rename from x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx rename to x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx index aed8d768984953..cc6440358da611 100644 --- a/x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx +++ b/x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx @@ -11,16 +11,16 @@ import type { AppFeatureKey } from '@kbn/security-solution-plugin/common'; import { useProductTypeByPLI } from '../hooks/use_product_type_by_pli'; export const GenericUpsellingPage: React.FC<{ requiredPLI: AppFeatureKey }> = React.memo( - ({ requiredPLI }) => { + function GenericUpsellingPage({ requiredPLI }) { const productTypeRequired = useProductTypeByPLI(requiredPLI); return ( This is a testing component for a Serverless upselling prompt.} + title={<>{'This is a testing component for a Serverless upselling prompt.'}} body={ <> - Get {productTypeRequired} to enable this feature + {'Get'} {productTypeRequired} {'to enable this feature'}